{
  "openapi": "3.0.1",
  "info": {
    "title": "LinkedIn Jobs Scraper & LinkedIn Jobs API: Job Postings Data",
    "description": "LinkedIn jobs API and scraper, no login: search LinkedIn job listings by keywords and location with LinkedIn's filters (date, company, Easy Apply, under 10 applicants); each job posting with description, salary, seniority, applicants and company facts; a job by URL or id.",
    "version": "0.1",
    "x-build-id": "SoNxBRlGsMOFwoCNX"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/hyperbach~linkedin-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-hyperbach-linkedin-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/hyperbach~linkedin-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-hyperbach-linkedin-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/hyperbach~linkedin-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-hyperbach-linkedin-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",
            "maxLength": 200,
            "type": "string",
            "description": "What to search for, as you would type it on LinkedIn Jobs (python developer, \"data engineer\"). Empty with everything else empty = LinkedIn's blank search (every job, newest first, in the location or the worker's country). A word LinkedIn cannot match is served by LinkedIn as the location's whole list with the word echoed in the summary row's header_text: use titleInclude to keep only the titles you mean.",
            "default": ""
          },
          "location": {
            "title": "Location",
            "maxLength": 200,
            "type": "string",
            "description": "A city, a region or a country as LinkedIn names it (United States, Austin, Texas, Germany). LinkedIn resolves it; the summary row's header_text shows what it searched (\"Python Jobs in Germany\"). Beside a searches list it is the list's default location.",
            "default": ""
          },
          "searches": {
            "title": "Searches",
            "maxItems": 100,
            "type": "array",
            "description": "Several searches in one run (at most 100). Each item is a string (keywords, or a LinkedIn jobs search URL: its keywords, location, geoId, distance, f_TPR, f_C, f_AL and f_EA apply, f_E / f_JT / f_WT become the criteria checks, sortBy is left out) or an object with keywords, location, url, geoId, distance, datePosted, postedWithinSeconds, companyIds, easyApplyOnly, under10ApplicantsOnly, experienceLevels, employmentTypes, workplaceTypes, titleInclude, titleExclude, companyExclude, maxItemsPerSearch and your own id (carried on every row of that search as input_id). The run's own fields are the defaults of every item.",
            "default": []
          },
          "jobUrls": {
            "title": "Job URLs or ids",
            "maxItems": 1000,
            "type": "array",
            "description": "Jobs to read one by one: a LinkedIn job URL (https://www.linkedin.com/jobs/view/<id>, with or without the slug) or a bare job id. Each gets its posting (and the company's facts). An id LinkedIn does not know is a free not_found row; a value that is no job URL or id a free invalid row.",
            "items": {
              "type": "string",
              "maxLength": 500
            },
            "default": []
          },
          "datePosted": {
            "title": "Date posted",
            "enum": [
              "",
              "24h",
              "week",
              "month"
            ],
            "type": "string",
            "description": "LinkedIn's own date filter (f_TPR), applied by LinkedIn: every row's posted_date lies inside the window. For any other window use postedWithinSeconds.",
            "default": ""
          },
          "postedWithinSeconds": {
            "title": "Posted within (seconds)",
            "minimum": 0,
            "maximum": 315360000,
            "type": "integer",
            "description": "Any date window in seconds (3600 = the past hour, 172800 = two days): LinkedIn's f_TPR=r<seconds>, applied by LinkedIn. 0 = off (datePosted decides). A narrow window is also how a scheduled task reads only the newest jobs.",
            "default": 0
          },
          "companyIds": {
            "title": "Companies",
            "maxItems": 50,
            "type": "array",
            "description": "Only jobs of these companies: LinkedIn company ids (1441 = Google), company URLs (https://www.linkedin.com/company/google) or slugs; a URL or slug is read to its id on the company's public page first (LinkedIn's search takes ids only), and one whose page gives no id is a free invalid search row. Several = any of them (LinkedIn's f_C filter, applied by LinkedIn).",
            "items": {
              "type": "string",
              "maxLength": 300
            },
            "default": []
          },
          "easyApplyOnly": {
            "title": "Easy Apply only",
            "type": "boolean",
            "description": "Only jobs with LinkedIn's Easy Apply (f_AL=true, applied by LinkedIn). Off: every job, with apply_type saying easy_apply or external on each.",
            "default": false
          },
          "under10ApplicantsOnly": {
            "title": "Under 10 applicants only",
            "type": "boolean",
            "description": "Only jobs with fewer than 10 applicants (LinkedIn's f_EA filter, applied by LinkedIn).",
            "default": false
          },
          "geoId": {
            "title": "geoId",
            "pattern": "^[0-9]*$",
            "maxLength": 20,
            "type": "string",
            "description": "LinkedIn's own place id from a LinkedIn jobs search URL (geoId=90000064 is Austin, Texas); with distance it replaces location. Leave empty to search by location.",
            "default": ""
          },
          "distance": {
            "title": "Distance (miles)",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "A radius in miles around the geoId or the location (LinkedIn's distance filter, applied by LinkedIn). 0 = LinkedIn's default.",
            "default": 0
          },
          "experienceLevels": {
            "title": "Experience levels",
            "maxItems": 6,
            "type": "array",
            "description": "Internship, Entry level, Associate, Mid-Senior level, Director, Executive. LinkedIn's logged-out search ignores its experience filter, so each job's full page is read and its Seniority level checked (the job's fragment says Not Applicable for many jobs whose page names a level): a job that does not match is dropped free before it is charged, and the summary row counts the drops (dropped_by_criteria). A rare level stops the search at a read budget (after the first 20 job pages, at most 7 pages a delivered row; the summary row says so). Needs includeJobDetails on. Empty = every level.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "employmentTypes": {
            "title": "Job types",
            "maxItems": 7,
            "type": "array",
            "description": "Full-time, Part-time, Contract, Temporary, Volunteer, Internship, Other. Checked on each job's page (its Employment type), a miss dropped free, with the same read budget as experienceLevels. Needs includeJobDetails on. Empty = every type.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "workplaceTypes": {
            "title": "Workplace",
            "maxItems": 3,
            "type": "array",
            "description": "Remote, Hybrid, On-site. LinkedIn's logged-out pages carry no workplace field, so the posting decides: its title or location (\"(Remote)\", \"(Hybrid)\") or a statement about this job in its description (\"a fully remote position\", \"work model: hybrid\", \"three days a week in the office\"); a perk such as \"work from home on Fridays\" is not one, and a posting that states none is dropped free, never guessed. Same read budget as experienceLevels; needs includeJobDetails on. Empty = every job, with workplace_type the posting's own statement or null.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "titleInclude": {
            "title": "Title must contain",
            "maxItems": 50,
            "type": "array",
            "description": "Keep only jobs whose title contains one of these words (case-insensitive), checked on the search card before any page is read. Empty = every title.",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "default": []
          },
          "titleExclude": {
            "title": "Title must not contain",
            "maxItems": 50,
            "type": "array",
            "description": "Drop jobs whose title contains one of these words (case-insensitive), checked on the search card. Empty = nothing dropped.",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "default": []
          },
          "companyExclude": {
            "title": "Company must not be",
            "maxItems": 50,
            "type": "array",
            "description": "Drop jobs whose company name contains one of these words (case-insensitive), checked on the search card. Empty = nothing dropped.",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "default": []
          },
          "maxItemsPerSearch": {
            "title": "Max jobs per search",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "How many jobs each search delivers at most, in LinkedIn's order. 0 = every job LinkedIn lists for the search: up to 1,000 (LinkedIn's own cap per search), and past it the date windows of deepSearch. An item of searches may carry its own.",
            "default": 0
          },
          "deepSearch": {
            "title": "Past LinkedIn's 1,000 cap (date windows)",
            "type": "boolean",
            "description": "When a search's count is a floor (\"11,000+\") and its list ends at LinkedIn's 1,000, read it again inside nested date windows (past 30 days, 7 days, 24 hours, 6 hours, 1 hour), each a slice of up to 1,000 more, every job once. The summary row names each window's count and what it added. More rows and calls: up to 6 slices per search.",
            "default": false
          },
          "includeJobDetails": {
            "title": "Read each job's posting",
            "type": "boolean",
            "description": "On: each job's page is read (one call): the description as HTML and text, seniority, employment type, industries, the applicants text, the salary block, the apply type, the closed flag; the row is charged as a job. Off: the search cards alone (id, URL, title, company, location, date, salary text, badge): a cheaper card row, no page read. A job given in jobUrls always gets its posting. experienceLevels, employmentTypes and workplaceTypes are checked on the page, so they need this on.",
            "default": true
          },
          "includeCompanyDetails": {
            "title": "Company facts",
            "type": "boolean",
            "description": "The company's public page once per company (website, industry, size, headquarters, type, founded, specialties, followers, description), on every row of that company at no extra charge.",
            "default": true
          },
          "includeExpiry": {
            "title": "Expiry and the exact posted time",
            "type": "boolean",
            "description": "Read each job's full page instead of its fragment (about four times the bytes): expires_at (LinkedIn's validThrough) and posted_at (the posting time to the second). Needs includeJobDetails on.",
            "default": false
          },
          "onlyNewJobs": {
            "title": "Only new jobs (memory between runs)",
            "type": "boolean",
            "description": "Remember every job delivered under this memory (stateStoreName, or a name derived from the searches) and skip it free in the next run: a scheduled task delivers only what is new. The summary row counts the skipped (skipped_seen).",
            "default": false
          },
          "stateStoreName": {
            "title": "Memory name",
            "pattern": "^([a-zA-Z0-9][a-zA-Z0-9._-]{0,63})?$",
            "type": "string",
            "description": "The name of the onlyNewJobs memory, so several tasks can share one or keep theirs apart. Empty: a name derived from the searches.",
            "default": ""
          },
          "maxItems": {
            "title": "Max jobs (whole run)",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "The most charged rows the run delivers over every search and job (summary rows and free rows do not count). 0 = no limit beyond maxItemsPerSearch and LinkedIn's own ends. The log names the most the run can cost before the first request.",
            "default": 0
          },
          "maxConcurrency": {
            "title": "Exits in parallel",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "How many LinkedIn sessions read at once, one call a second each. 4 by default: about 85 jobs a minute with the postings (780 of a 944-job search in 9 minutes on our test, so a whole 1,000-job search takes about 12 minutes); 8 read about 145 jobs a minute on two test runs; 1 for a gentle run.",
            "default": 4
          },
          "proxyUrl": {
            "title": "Proxy URL",
            "type": "string",
            "description": "Empty (recommended): LinkedIn is read through the Actor's own exits at no extra cost to you. Your own proxy URL (scheme://user:pass@host:port) carries every call instead. The word none runs without any proxy, from the Apify worker's own IP (for tests)."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}