{
  "openapi": "3.0.1",
  "info": {
    "title": "Shine Jobs Scraper — India Jobs with Recruiter Emails & Phones",
    "description": "Scrape Shine.com jobs across India with the hiring recruiter's real email and phone — Shine's fake placeholder contact is detected and stripped, so every contact you get is genuine. Filter by experience, salary, industry and employment type. Schedule it for only-new postings.",
    "version": "0.0",
    "x-build-id": "nhXxufzn8SPqTGmz7"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~shine-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-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/memo23~shine-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-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/memo23~shine-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-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": "Search keywords",
            "type": "array",
            "description": "What to search for on Shine.com, e.g. \"python\", \"sales manager\", \"staff nurse\". Each keyword becomes a Shine search that is paged through.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location (optional)",
            "type": "string",
            "description": "Restrict every keyword to one city, e.g. \"Bangalore\", \"Mumbai\", \"Delhi\". Leave empty to search all of India. Ignored for URLs pasted into Start URLs."
          },
          "startUrls": {
            "title": "Start URLs (optional)",
            "type": "array",
            "description": "Shine.com search URLs to scrape as-is, e.g. https://www.shine.com/job-search/python-jobs-in-bangalore. Use this instead of keywords when you have already built the search on Shine.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "maxItems": {
            "title": "Maximum results",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after this many rows. Each Shine search page yields 20 jobs, so 100 results is 5 requests.",
            "default": 100
          },
          "maxPagesPerKeyword": {
            "title": "Maximum pages per keyword",
            "minimum": 1,
            "type": "integer",
            "description": "Safety cap on how deep to page for each keyword, regardless of the result limit. Popular keywords run to 1,500+ pages.",
            "default": 500
          },
          "minExperienceYears": {
            "title": "Years of experience",
            "minimum": 2,
            "maximum": 25,
            "type": "integer",
            "description": "Filter to jobs suited to a candidate with this many years of experience. Shine applies this as a band rather than a floor: 3 returns \"0 to 4 Yrs\" roles, 15 returns \"8 to 12\" and \"10 to 14\". Values outside 2–25 return nothing."
          },
          "minSalaryLakh": {
            "title": "Minimum salary (lakh/year)",
            "minimum": 1,
            "maximum": 45,
            "type": "integer",
            "description": "Only jobs paying at least this many lakh rupees per year. Measured on a python search: 12 cuts 30,000 jobs to 3,770 and 25 cuts it to 922. Note that Shine keeps listings with a hidden salary in the results at every threshold, so some rows still read \"[Salary Hidden]\" — switch on “Also scrape each job page” to get a numeric band for many of those."
          },
          "industry": {
            "title": "Industry",
            "type": "string",
            "description": "Restrict to one Shine industry, e.g. \"IT Services & Consulting\", \"BFSI\", \"Medical / Healthcare\", \"Education / Training\", \"BPO / Call Center\". Matched against the live list Shine returns for your search, so partial names work and the run logs what it matched. A numeric Shine industry id is also accepted."
          },
          "functionalArea": {
            "title": "Functional area",
            "type": "string",
            "description": "Restrict to one job function, e.g. \"Testing\", \"Finance / Accounts / Tax\", \"Network / System Administration\", \"Teacher / Tutor\". Matched the same way as Industry. Narrower than industry, so pair it with a broad keyword."
          },
          "employmentType": {
            "title": "Employment type",
            "enum": [
              "any",
              "regular",
              "contractual",
              "internship",
              "workFromHome"
            ],
            "type": "string",
            "description": "Keep only one kind of contract. Work-from-home and internship listings are a small fraction of Shine, so expect far fewer results than an unfiltered search.",
            "default": "any"
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "relevance",
              "newest"
            ],
            "type": "string",
            "description": "Shine’s own ranking, or newest postings first. Newest-first is what makes a date window cheap, so setting one switches this automatically.",
            "default": "relevance"
          },
          "postedWithinDays": {
            "title": "Posted within (days)",
            "minimum": 1,
            "maximum": 365,
            "type": "integer",
            "description": "Keep only jobs posted in the last N days. Shine has no date filter of its own, so the Actor sorts newest-first and stops paging as soon as a whole page falls outside the window — a 1-day window on a 1,500-page keyword reads a handful of pages, not all of them."
          },
          "scrapeJobDetails": {
            "title": "Also scrape each job page",
            "type": "boolean",
            "description": "Fetch every job’s own page as well as the search listing. The search page already carries the full description, recruiter email and phone, so this is only for the extra fields a job page adds: applyCount (how many people applied — observed 0 to 991), numeric salaryMin/salaryMax, each city mapped to its state, the employer’s company description, and Shine’s category tags. Costs one request per job instead of one per 20, so runs take longer. Job URLs pasted into Start URLs get these fields regardless. Has no effect when “One row per recruiter” is on, since these fields describe one job.",
            "default": false
          },
          "uniqueRecruiters": {
            "title": "One row per recruiter",
            "type": "boolean",
            "description": "Group jobs by recruiter contact instead of returning one row per job. Indian recruitment consultancies post the same contact against many vacancies (measured ~3.2x), so this turns the output into a de-duplicated contact list with job counts, titles, locations and industries attached.",
            "default": false
          },
          "requireContact": {
            "title": "Only jobs with a recruiter contact",
            "type": "boolean",
            "description": "Skip any job that has neither a recruiter email nor a phone number. Measured over 480 jobs, a genuine email is on 43% of postings and a phone on 38%, so this typically removes more than half the results — switch it on when every row must be actionable, leave it off to see the whole market. Shine’s placeholder contact for opted-out recruiters is already stripped, so this filter never keeps a row on the strength of a fake address.",
            "default": false
          },
          "skipDescriptions": {
            "title": "Skip job descriptions",
            "type": "boolean",
            "description": "Leave out jobDescription and jobDescriptionHtml. Descriptions are the largest part of each row, so turning them off makes exports much smaller.",
            "default": false
          },
          "enrichEmails": {
            "title": "Enrich rows missing a recruiter email",
            "type": "boolean",
            "description": "When on, each job without a recruiterEmail is looked up by company name + city to attach contact_email, contact_website and an emailEnrichment object. Adds time per uncovered row and is charged per enriched record.",
            "default": false
          },
          "monitorMode": {
            "title": "Only new jobs since the last run",
            "type": "boolean",
            "description": "Remember which jobs have already been delivered and return only ones you have not received before. Built for a schedule: the first run delivers everything it finds and becomes the baseline, and every run after it returns just that day’s new postings, so you stop paying for the same feed over and over. A run that finds nothing new finishes successfully and says so — that is the mode working, not a failure. Only jobs actually delivered are remembered, so anything cut by your result limit still arrives next time.",
            "default": false
          },
          "monitorStateKey": {
            "title": "Monitoring state key",
            "type": "string",
            "description": "Separate memories for separate schedules. Two schedules on different keywords should use different keys, e.g. \"nursing-delhi\" and \"python-blr\", or each will treat the other’s jobs as already seen. Leave as \"default\" if you run only one schedule.",
            "default": "default"
          },
          "resetMonitorState": {
            "title": "Forget everything and start over",
            "type": "boolean",
            "description": "Wipe the remembered jobs before this run, so it delivers everything again and becomes the new baseline. Use it after changing keywords or filters, when the old memory no longer matches what you are asking for.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "The Actor starts direct and falls back to its own residential exit when Shine withholds the data, so you do not need to set anything here. Supply a proxy only if you want all traffic routed through your own."
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}