{
  "openapi": "3.0.1",
  "info": {
    "title": "Shine.com Jobs Scraper | India Jobs Feed, New and Closed",
    "description": "Shine jobs scraper for India job listings: search any role and city, get one clean row per job with salary band, experience and description. Schedule it for a feed of what moved: mostly new roles, plus the rarer closures, each confirmed against the posting's own page.",
    "version": "1.5",
    "x-build-id": "031FTf91wGnhYP8iP"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/titian_fluorite~shine-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-titian_fluorite-shine-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/titian_fluorite~shine-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-titian_fluorite-shine-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/titian_fluorite~shine-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-titian_fluorite-shine-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Job titles or skills to search for on Shine.com, one per line. Each keyword becomes one search, and each keyword is searched in every city you list below. Leave this empty only if you are giving Shine search URLs instead.",
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Cities",
            "type": "array",
            "description": "Optional. Indian cities to search in, one per line, for example Bangalore, Mumbai, Delhi NCR, Hyderabad, Pune or Chennai. Leave this empty to search all of India. A city Shine does not recognise is skipped with a warning rather than quietly returning all India results.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "searchUrls": {
            "title": "Shine search URLs",
            "type": "array",
            "description": "Optional. Paste Shine job search addresses to use exactly as they are, for example https://www.shine.com/job-search/python-developer-jobs-in-bangalore. Only job search pages are accepted, and an address with a query string is refused because robots.txt disallows several of them.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxJobsPerSearch": {
            "title": "Maximum jobs per search",
            "minimum": 0,
            "type": "integer",
            "description": "How many jobs to collect from each search before moving on. Shine returns 20 jobs per page. Set 0 to take everything Shine will serve, up to a safety cap of 250 pages per search. A run collects at most 50 searches and 20,000 jobs in total. Every job row you receive is billed. Time matters as much as cost here: with descriptions on, a run fits about 2,250 jobs per hour of its timeout, so 50 searches at 100 jobs each needs about two hours rather than the default one. The log says at the start whether what you asked for fits.",
            "default": 100
          },
          "postedWithinDays": {
            "title": "Posted within the last N days",
            "minimum": 0,
            "maximum": 3650,
            "type": "integer",
            "description": "Optional. Keep only jobs posted in the last N days. Leave empty to keep everything Shine returns. A job whose posting date cannot be read is withheld rather than delivered, because there is no way to tell whether it is inside the window you asked for and you are never charged for a row you did not ask for. The run says loudly at the end if that happened."
          },
          "experienceMin": {
            "title": "Minimum experience",
            "minimum": 0,
            "maximum": 80,
            "type": "integer",
            "description": "Optional. Keep only jobs whose published experience band reaches at least this many years. A band open at the top, \"10+ Yrs\", clears every floor it passes. A job whose band cannot be read is withheld rather than delivered, for the same reason as the posting date above, and the run says so at the end."
          },
          "experienceMax": {
            "title": "Maximum experience",
            "minimum": 0,
            "maximum": 80,
            "type": "integer",
            "description": "Optional. Keep only jobs whose published experience band starts at or below this many years. The listing's band and yours have to overlap, not match, so asking for 3 to 5 years returns the 2 to 6 year posting too. A job whose band cannot be read is withheld rather than delivered, and the run says so at the end."
          },
          "includeDescription": {
            "title": "Include the job description",
            "type": "boolean",
            "description": "Add the full job description as cleaned HTML and as plain text, plus the industry, the employment type and the expiry date. Since Shine's September 2026 redesign these live on each job's own page rather than in the search listing, so leaving this on costs one extra request per job delivered. That is most of what a long run spends its time on: turning it off makes a run about twenty times faster, lighter on the site, and the dataset several times smaller.",
            "default": true
          },
          "trackChanges": {
            "title": "Track changes between runs",
            "type": "boolean",
            "description": "Remember each search between runs and label every row: new, closed, salaryChanged, updated or unchanged. A row that changed also carries what the last run saw, under previous. The memory is kept in a key-value store called shine-jobs-scraper-state in your own account, and each search keeps its own memory, so a schedule on \"python developer in Bangalore\" is not disturbed by a one-off run on something else. Changing any of the filters, the job limit or the description setting starts that search on a fresh memory, because those decide which jobs the search returns at all. A job is only ever reported as closed when the run read the whole search and then asked Shine about that job's own page and Shine answered that the posting has gone.",
            "default": false
          },
          "onlyChanges": {
            "title": "Only deliver jobs that changed",
            "type": "boolean",
            "description": "Deliver and bill for only the jobs that are new, closed, or whose pay or details moved since the last run. Jobs that did not move are skipped, so a quiet morning returns no rows and costs nothing. Turns on change tracking by itself. The first run has nothing to compare against, so it delivers everything once and builds the memory. If a search's memory cannot be read in full, that search is skipped rather than delivered as a full catalogue you did not ask for.",
            "default": false
          },
          "maxConcurrency": {
            "title": "Maximum concurrent requests",
            "minimum": 1,
            "maximum": 2,
            "type": "integer",
            "description": "How many requests may be in flight at once. Capped at 2 on purpose: this Actor reads a public site politely and will not be turned into a hammer. Raising this does not make a long run finish sooner while Shine keeps answering in about 1.4 seconds, because the one to two second pause between requests is applied to the whole run rather than to each search, and that pause is the slower of the two. What decides a run's length is how many requests your input implies.",
            "default": 2
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}