# LinkedIn Jobs Search Lookup: jobs scraper from $1.50/1k (`accountable_eel/linkedin-jobs-search-lookup`) Actor

LinkedIn jobs scraper by keyword and location — run a search on LinkedIn's public job board and get one row per posting: title, company, location, posted date, apply link, and the full description on request. No login, no cookies. Pay per posting returned; empty searches are free.

- **URL**: https://apify.com/accountable\_eel/linkedin-jobs-search-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.14 / 1,000 job posting returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## LinkedIn Jobs Search Lookup: LinkedIn Jobs Scraper by Keyword & Location

You write job searches the way you'd type them into LinkedIn — `data engineer @ Berlin, Germany` —
and this actor runs each one against LinkedIn's **public, logged-out** job board and returns one
clean row per posting: title, company, location, posted date, and a permanent link. Turn on the
description option and each row also carries the full posting text, the pay range when the posting
states one, seniority, employment type, job function, industry and applicant count.

No login. No cookies. No LinkedIn account or session token of any kind — see the legal note at the
bottom of this page.

### Who it's for

The accountable\_eel catalogue sells company and hiring intelligence columns for outbound and
recruiting. Each actor takes a list of identifiers — domains, company slugs, and here, job
searches — and returns one flat, stably-named row per result: the shape a Clay table, an n8n
workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event: a fraction
of a cent for a row you actually got, and nothing at all for a search that finds nothing. No seat
licence, no monthly minimum, no credit system to decode.

This actor is the wide-net end of that catalogue. The ATS lookups in the same family
(`greenhouse-jobs-lookup`, `lever-jobs-lookup`, `ashby-jobs-lookup` and friends) answer "what is
*this company* hiring for" — you bring the company list. This one answers "who is hiring for *this
role*, *here*" when you don't have the list yet.

### Why this one

- **Every filter it offers is a filter that works.** LinkedIn's logged-out search endpoint accepts
  a great many `f_*` parameters and quietly ignores most of them. Measured on 2026-08-24 by running
  each one 4–6 times and comparing the returned job IDs against an unfiltered search: date-posted,
  Easy Apply, location, geo ID and company ID are real; job type, experience level, remote,
  salary band, industry and sort order return the *identical* result set to no filter at all.
  So keywords, location and posted-date go to LinkedIn, and role/company/location/remote narrowing
  happens here on the postings after they arrive — and the page tells you which is which. Paste a
  LinkedIn search URL that carried filters LinkedIn drops, and the row's
  `ignoredSearchFilters` column names them instead of pretending they applied.
- **You are never billed for the same posting twice.** LinkedIn hands out ten results at a time,
  reshuffles between requests, and repeats postings across neighbouring pages — two requests at
  offsets ten apart shared half their results on one measurement. Every posting is deduplicated by
  its LinkedIn job ID across the pages of a search and, by default, across every search in the run.
  On a per-posting price, that is a billing guarantee, not a tidiness feature.
- **The description hop is opt-in and separately priced.** Opening every posting's own page is one
  extra visit per posting and roughly twenty times the bandwidth. It's off by default, and when
  it's on you're charged for it only on postings whose page actually came back.
- **Partial results survive a rate limit.** If LinkedIn throttles the run halfway through a
  100-posting search, you get the postings collected so far, flagged with `blockedWhilePaging`,
  instead of losing the whole search to a retry.
- **Three input shapes.** `keywords @ location`, bare keywords with a location set once for the
  whole run, or a LinkedIn jobs search URL pasted straight out of your browser's address bar.

### What you get

One row per job posting by default. (Turn off "One row per job posting" in the Input tab to get one
row per *search* instead, with the whole posting list nested in `jobs`.) Every row carries these
fields, whether or not you turned on filters or descriptions — the columns never move:

| Field | Type / format | Description |
| --- | --- | --- |
| `query` | text | The search line you passed in, unchanged. |
| `found` | boolean | `true` if the search returned at least one posting. `false` rows are never charged. |
| `status` | text | `OK`, `NOT_FOUND` (no public postings for that search), `BAD_FORMAT` (the line wasn't a search or a LinkedIn URL), or `BLOCKED`. |
| `searchKeywords` | text | The keywords actually sent to LinkedIn. |
| `searchLocation` | text | The location actually sent to LinkedIn. |
| `jobCount` | number | How many postings this search returned after your filters — this is exactly what you're charged for. |
| `truncated` | boolean | `true` if more postings were available than you asked for, or if paging stopped early. |
| `ignoredSearchFilters` | array | Filters present on a pasted LinkedIn URL that the public endpoint does not honour. Empty for a normal search line. |
| `jobs` | array | The full posting list. Present in every row; it's what gets expanded into separate rows in "one row per posting" mode. |
| `jobId` | text | LinkedIn's own numeric posting ID — stable, and what deduplication keys on. |
| `title` | text | Job title. |
| `company` | text | Hiring company as LinkedIn names it. |
| `companyUrl` | link | The company's LinkedIn page, with tracking parameters stripped. |
| `companyLogoUrl` | image | Company logo image URL. |
| `location` | text | Location as LinkedIn prints it on the posting (e.g. "Fort Wayne, IN", "United States"). |
| `remote` | boolean | `true` if the location or title reads as remote. |
| `postedAt` | date (ISO) | The posting date, read from LinkedIn's own `datetime` attribute — a real calendar date, not a guess back-derived from "4 days ago". |
| `postedAgo` | text | The same thing in LinkedIn's words ("4 days ago", "20 hours ago"). |
| `jobUrl` | link | Permanent public link to the posting, with this run's tracking parameters removed. |
| `activelyHiring` | boolean | `true` if LinkedIn shows the "Actively Hiring" badge. |
| `earlyApplicant` | boolean | `true` if LinkedIn says you'd be among the first applicants. |
| `benefitsText` | text | The benefits teaser LinkedIn shows on some cards ("Medical insurance +6 benefits"). Most postings don't have one. |
| `descriptionFetched` | boolean | `true` if the posting's own page was opened for the fields below. |
| `description` | text | The full posting text, as plain text. |
| `salaryText` | text | The pay range, when the posting states one in its description. |
| `seniorityLevel` | text | e.g. "Associate", "Mid-Senior level". |
| `employmentType` | text | e.g. "Full-time", "Contract". |
| `jobFunction` | text | e.g. "Engineering and Information Technology". |
| `industries` | text | e.g. "Software Development". |
| `applicantsText` | text | e.g. "Over 200 applicants", "Be among the first 25 applicants". Shown on roughly half of postings. |
| `scrapedAt` | date (ISO) | When this actor fetched the row. |

A search that returns no public postings comes back as a single `found: false` row with a
`status`/`message` explaining why, and is never charged. So does a line that isn't a usable search.

Two honest limits, both measured rather than assumed:

- **There is no `applyUrl`.** The Apply button on a logged-out posting opens a LinkedIn sign-up
  dialog, not an offsite application link — so no such field is offered rather than filled with the
  sign-up URL. `jobUrl` is the permanent public link.
- **`salaryText` comes out of the description.** There is no structured compensation field on a
  logged-out posting, so pay is read from the posting text and is null unless you turn descriptions
  on and the posting actually states a range. A perk written like pay (a learning budget, a signing
  bonus) is deliberately not reported as salary.

### Pricing

- **Job posting returned**: $1.5 per 1,000 job postings
- **Full description added**: $1 per 1,000 job postings

Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (`found:false`) are never charged.

You're charged **per posting returned**, not per search — a search that returns 4 postings costs
four, a search that returns none costs nothing, and a `BAD_FORMAT` line costs nothing. The
description option adds a second, separate charge on top, and only on the postings whose page
actually loaded.

Because you pay per posting, "Most postings to return per search" is your budget control: leave it
at 100 and a five-search run costs at most 500 postings' worth. LinkedIn stops serving results at
roughly 1,000 per search regardless, so that is the real ceiling per line.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `searches` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~linkedin-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"searches":["marketing manager @ United States"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

Paste one search per line. All three of these work, and you can mix them in one run:

```
data engineer @ Berlin, Germany
marketing manager
https://www.linkedin.com/jobs/search?keywords=data%20engineer&location=Berlin%2C%20Germany
```

A line with no `@ location` uses the location you set once in **🔍 Search settings**. A pasted
LinkedIn URL brings its own keywords, location, geo ID, date-posted, Easy Apply and company filters
with it; anything else it carries is dropped and named in `ignoredSearchFilters`.

**🔍 Search settings** — these are sent to LinkedIn, so they narrow the search before results are
returned, which makes runs cheaper as well as more relevant:

| Input | What it does |
| --- | --- |
| `defaultLocation` | Location for any line that doesn't name one. Write it as LinkedIn does — "Berlin, Germany", "United States". |
| `maxJobsPerQuery` | Most postings to return per search. Default 100, capped at what LinkedIn will serve (about 1,000). |
| `postedWithin` | Past 24 hours / week / month. |
| `easyApplyOnly` | Only roles you can apply to without leaving LinkedIn. |
| `fetchDescription` | Open each posting for its full text, pay range, seniority, employment type, function, industry and applicant count. |

**🎯 Narrow the results** — these are applied here, to the postings after they arrive, because
LinkedIn's logged-out search ignores the equivalent parameters. They combine with AND across fields
and OR within a field:

| Input | What it does |
| --- | --- |
| `titleKeywords` | Keep only titles containing one of these — `["engineer","designer"]`. |
| `excludeTitleKeywords` | Drop titles containing one of these — `["intern","senior"]`. Applied after the include list. |
| `companies` | Keep only these companies — partial names match. |
| `excludeCompanies` | Drop these companies — useful for filtering out staffing agencies you already know. |
| `locations` | Narrow a wide search to particular cities or regions. |
| `remoteOnly` | Keep only roles whose location or title reads as remote. |
| `skipDuplicateJobs` | On by default. Each posting is returned, and billed, once per run even if two searches overlap. |

If LinkedIn throttles a run, lower **Max concurrency** (in ⚙️ Advanced) to 1 and keep the
Residential proxy setting on. Rate limits are retried with backoff automatically, and a run that
gets limited mid-search returns what it collected rather than failing.

### Input

```json
{
  "searches": [
    "marketing manager @ United States"
  ]
}
```

One search per line. Write it as "keywords @ location", or just the keywords and set a location below, or paste a LinkedIn jobs search URL straight from your browser. Accepted formats: data engineer @ Berlin, Germany, marketing manager, https://www.linkedin.com/jobs/search?keywords=data%20engineer\&location=Berlin%2C%20Germany.

### Output

| query | found | status | searchKeywords | searchLocation | jobCount | truncated | ignoredSearchFilters | jobs | jobId | title | company | companyUrl | companyLogoUrl | location | remote | postedAt | postedAgo | jobUrl | activelyHiring | earlyApplicant | benefitsText | descriptionFetched | description | salaryText | seniorityLevel | employmentType | jobFunction | industries | applicantsText | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| marketing manager @ United States | true | OK | marketing manager | United States | 100 | true |  | \<all postings found (full list)> | 4447045308 | Marketing Manager | Amcor | https://ch.linkedin.com/company/amcor | https://media.licdn.com/dms/image/v2/C4D0BAQF0sed-lbowMg/company-logo\_100\_100/company-logo\_100\_100/0/1630499181382/amcor\_logo | Evansville, IN | false | 2026-08-20 | 1 week ago | https://www.linkedin.com/jobs/view/marketing-manager-at-amcor-4447045308 | true | false |  | false |  |  |  |  |  |  |  | 2026-08-31T06:50:20.789Z |

### Legal note

This actor reads **public data only**. It requests the same two logged-out URLs your browser
requests when you open a LinkedIn job search or a job posting while signed out — the ones LinkedIn
serves to search engines and to visitors without an account.

It does **not** log in, does **not** accept or store a LinkedIn account, password, session cookie
or `li_at` token, and has no input field in which you could give it one. It reads no private
profiles, no connection graphs and no personal data beyond what a hiring company chose to publish
in its own job advertisement: the role, the company, the location and the posting text. It does not
collect names, email addresses or contact details of individuals.

You are responsible for how you use the results. Public-data collection of this kind has been held
lawful in the United States (*hiQ Labs v. LinkedIn*), but that is not the whole picture: LinkedIn's
User Agreement prohibits automated collection regardless, and if you are in or handling data from
the EU/UK, the GDPR applies to job-posting data that identifies a person (a named hiring manager in
the posting text, for instance) even though it is public. Check your own obligations before putting
this on a schedule, and don't use it to build profiles of individuals.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~linkedin-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"searches":["marketing manager @ United States"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~linkedin-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"searches":["marketing manager @ United States"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~linkedin-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"searches":["{{search}}"]}`, mapping the row's search into the `searches` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "LinkedIn Jobs Scraper by Keyword | Apify" — the agent will find and run this actor.

# Actor input Schema

## `searches` (type: `array`):

One search per line. Write it as "keywords @ location", or just the keywords and set a location below, or paste a LinkedIn jobs search URL straight from your browser. Accepted formats: data engineer @ Berlin, Germany, marketing manager, https://www.linkedin.com/jobs/search?keywords=data%20engineer\&location=Berlin%2C%20Germany. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

## `excludeKeywords` (type: `array`):

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `defaultLocation` (type: `string`):

Used for any line that's just keywords. Write it the way LinkedIn does — "Berlin, Germany", "United States", "Greater London Area". Leave empty to search worldwide.

## `maxJobsPerQuery` (type: `integer`):

LinkedIn hands out 10 postings at a time and stops at about 1,000 per search, so anything above that is capped. You pay per posting returned, so this is also your budget control.

## `postedWithin` (type: `string`):

Ask LinkedIn for recent postings only. This one is applied by LinkedIn itself before results are sent, so it makes runs cheaper as well as fresher.

## `easyApplyOnly` (type: `boolean`):

Keep only roles you can apply to without leaving LinkedIn. Also applied by LinkedIn before results are sent.

## `fetchDescription` (type: `boolean`):

Opens every posting's own page to add the full description, pay range if it states one, seniority, employment type, job function, industry and applicant count. This is one extra visit per posting, so it's slower and costs more — see the pricing section.

## `titleKeywords` (type: `array`):

Optional. Keep only roles whose title contains at least one of these words — e.g. "engineer", "account executive". Case doesn't matter and partial words work. Leave empty to keep every role.

## `excludeTitleKeywords` (type: `array`):

Optional. Drop any role whose title contains one of these words — e.g. "intern", "senior". Applied after the include list above, so a role matching both is dropped.

## `companies` (type: `array`):

Optional. Keep only roles at companies whose name contains one of these — e.g. "Stripe", "Bosch". Partial matches work.

## `excludeCompanies` (type: `array`):

Optional. Drop roles at companies whose name contains one of these — handy for filtering out staffing and recruiting agencies you already know.

## `locations` (type: `array`):

Optional. Narrow a wide search down to particular cities or regions — e.g. "Berlin", "New York". Applied to the location LinkedIn prints on each posting.

## `remoteOnly` (type: `boolean`):

Keep only roles whose location or title reads as remote. LinkedIn does not let a logged-out search ask for remote roles, so this is applied to the postings after they arrive — treat it as a strong filter, not a guarantee.

## `skipDuplicateJobs` (type: `boolean`):

On by default. Overlapping searches routinely surface the same role, and LinkedIn repeats postings between pages of one search — with this on, each posting is returned, and billed, exactly once per run.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each job posting found gets its own row instead of being grouped under its search. You're still only charged once per search, no matter how many rows it produces.

## `maxConcurrency` (type: `integer`):

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

## `proxyConfiguration` (type: `object`):

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "searches": [
    "marketing manager @ United States"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "defaultLocation": "",
  "maxJobsPerQuery": 100,
  "postedWithin": "",
  "easyApplyOnly": false,
  "fetchDescription": false,
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "companies": [],
  "excludeCompanies": [],
  "locations": [],
  "remoteOnly": false,
  "skipDuplicateJobs": true,
  "columns": [
    "searchKeywords",
    "searchLocation",
    "jobCount",
    "truncated",
    "ignoredSearchFilters",
    "jobs",
    "jobId",
    "title",
    "company",
    "companyUrl",
    "companyLogoUrl",
    "location",
    "remote",
    "postedAt",
    "postedAgo",
    "jobUrl",
    "activelyHiring",
    "earlyApplicant",
    "benefitsText",
    "descriptionFetched",
    "description",
    "salaryText",
    "seniorityLevel",
    "employmentType",
    "jobFunction",
    "industries",
    "applicantsText"
  ],
  "expandRows": true,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searches": [
        "marketing manager @ United States"
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "companies": [],
    "excludeCompanies": [],
    "locations": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/linkedin-jobs-search-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searches": ["marketing manager @ United States"],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "companies": [],
    "excludeCompanies": [],
    "locations": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/linkedin-jobs-search-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searches": [
    "marketing manager @ United States"
  ],
  "includeKeywords": [],
  "excludeKeywords": [],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "companies": [],
  "excludeCompanies": [],
  "locations": []
}' |
apify call accountable_eel/linkedin-jobs-search-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/linkedin-jobs-search-lookup"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RDi6MImnY8GwUohxs/builds/g3YyCYQsJsP4veSBf/openapi.json
