{
  "openapi": "3.0.1",
  "info": {
    "title": "LinkedIn Smart Job Description & Recruiter Extractor",
    "description": "Read LinkedIn job postings in full and turn each description into structured data: the tech stack named, certifications and clearances demanded, the pay range, seniority and the applicant count. No login required. Recruiter profiles are added when you supply your own li_at cookie.",
    "version": "0.0",
    "x-build-id": "Ewi64jQaJpAC2dC3z"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/fanndev~linkedin-job-recruiter-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-fanndev-linkedin-job-recruiter-extractor",
        "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/fanndev~linkedin-job-recruiter-extractor/runs": {
      "post": {
        "operationId": "runs-sync-fanndev-linkedin-job-recruiter-extractor",
        "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/fanndev~linkedin-job-recruiter-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-fanndev-linkedin-job-recruiter-extractor",
        "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": {
          "searchQueries": {
            "title": "Search queries",
            "type": "array",
            "description": "Job titles or keywords to search, one per line. Each query is paginated ten results at a time and stops returning anything past roughly 975 postings, so coverage comes from using more queries rather than raising the per-query cap.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "Free-text location applied to every query, exactly as you would type it on LinkedIn - 'United States', 'Jakarta, Indonesia', 'Remote'. Leave empty for worldwide."
          },
          "jobUrls": {
            "title": "Job URLs or ids",
            "type": "array",
            "description": "Specific postings to read, instead of or alongside a search. Full /jobs/view/ URLs, ?currentJobId= links and bare numeric ids all work.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Job URLs (request list)",
            "type": "array",
            "description": "The same job links in the request-list format, for callers that already keep one.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "datePosted": {
            "title": "Posted within",
            "enum": [
              "",
              "past24Hours",
              "pastWeek",
              "pastMonth"
            ],
            "type": "string",
            "description": "The one filter LinkedIn's public jobs endpoint actually honours - it is applied server-side, before results are returned.",
            "default": ""
          },
          "workplaceType": {
            "title": "Workplace type",
            "enum": [
              "",
              "REMOTE",
              "HYBRID",
              "ONSITE"
            ],
            "type": "string",
            "description": "Applied AFTER each description is read, not by LinkedIn. LinkedIn's public endpoint accepts its own workplace filter and then ignores it - passing it returns results identical to passing nothing - so this actor infers the workplace type from the description text and filters on that instead. It means filtered runs still cost one request per posting read.",
            "default": ""
          },
          "employmentType": {
            "title": "Employment type",
            "enum": [
              "",
              "Full-time",
              "Part-time",
              "Contract",
              "Temporary",
              "Internship",
              "Volunteer"
            ],
            "type": "string",
            "description": "Also applied client-side, matched against the posting's own criteria grid. Same reason as above.",
            "default": ""
          },
          "seniorityLevel": {
            "title": "Seniority level",
            "enum": [
              "",
              "Internship",
              "Entry level",
              "Associate",
              "Mid-Senior level",
              "Director",
              "Executive"
            ],
            "type": "string",
            "description": "Client-side filter against the posting's stated seniority.",
            "default": ""
          },
          "requiredTech": {
            "title": "Must mention these technologies",
            "type": "array",
            "description": "Keep only postings whose description names at least one of these, matched against the parsed tech stack rather than raw text - so 'R' will not match 'R&D' and 'React' will not match 'React Native' alone.",
            "items": {
              "type": "string"
            }
          },
          "onlyWithSalary": {
            "title": "Only postings that state pay",
            "type": "boolean",
            "description": "Keep only postings where a pay range was found. Be aware most postings state none: in a sample of eight, two carried an employer-provided range.",
            "default": false
          },
          "includeFullDescription": {
            "title": "Include the full description text",
            "type": "boolean",
            "description": "Keep the complete description on each row. Turn off for a much smaller dataset when you only want the parsed fields.",
            "default": true
          },
          "includeRecruiter": {
            "title": "Include the recruiter who posted",
            "type": "boolean",
            "description": "Requires a session cookie below. LinkedIn does not render the 'Meet the hiring team' block to logged-out visitors - none of eight sampled postings carried it - so without a cookie the recruiter fields stay empty.",
            "default": false
          },
          "sessionCookie": {
            "title": "Your li_at session cookie",
            "type": "string",
            "description": "Optional, and only needed for recruiter details. Copy the li_at cookie value from a browser where you are already signed in to LinkedIn (DevTools > Application > Cookies > www.linkedin.com > li_at). This actor never asks for your password and never signs in for you. Scraping while signed in breaches LinkedIn's User Agreement and can get an account restricted - use one you are willing to risk."
          },
          "resolveCompanyDomain": {
            "title": "Resolve each employer's web domain",
            "type": "boolean",
            "description": "Opens each employer's LinkedIn page once to read their website, giving you the company domain for mail-merge work. Cached per company, so forty employers cost forty extra requests regardless of how many postings they have. No email address is ever guessed from it - a fabricated address that bounces costs you your sending reputation.",
            "default": false
          },
          "maxJobsPerQuery": {
            "title": "Maximum postings per query",
            "minimum": 1,
            "maximum": 975,
            "type": "integer",
            "description": "Cap per search query, before detail pages are read. LinkedIn stops serving results past roughly 975 per query.",
            "default": 50
          },
          "maxJobs": {
            "title": "Maximum postings in total",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Overall ceiling across every query and URL after de-duplication. Each posting costs one detail request on top of the search requests.",
            "default": 200
          },
          "minDelaySeconds": {
            "title": "Minimum delay between requests",
            "minimum": 0,
            "maximum": 60,
            "type": "integer",
            "description": "LinkedIn answers request bursts with HTTP 999 and a near-empty page. A randomised gap between requests is what keeps a run under that gate; this is the floor of that range.",
            "default": 2
          },
          "maxDelaySeconds": {
            "title": "Maximum delay between requests",
            "minimum": 0,
            "maximum": 120,
            "type": "integer",
            "description": "The ceiling of the randomised gap. Raise both bounds if the log shows rate-gate warnings.",
            "default": 8
          },
          "exportFormats": {
            "title": "Extra export files",
            "type": "array",
            "description": "Besides the dataset, write ready-made files into this run's key-value store.",
            "items": {
              "type": "string",
              "enum": [
                "json",
                "ndjson",
                "csv",
                "excel"
              ],
              "enumTitles": [
                "JSON",
                "NDJSON",
                "CSV",
                "Excel (XLSX)"
              ]
            },
            "default": []
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Genuinely optional here: the public jobs endpoint has no WAF and no IP block, and Apify's datacenter range reaches it. Worth turning on for long runs, for results localised to another country, and always when you supply a session cookie.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}