Blog

Pull LinkedIn job postings into a spreadsheet, on a schedule

If you are tracking a hiring market, the job you actually want is boring: get every posting for a role in a location, keep the list fresh, and have it land somewhere you can sort. Writing that yourself means a headless browser, a proxy pool, and a standing commitment to fix it whenever the markup shifts.

This walks through doing it with a call.

What you get back

One row per posting, with the title, company, location, posting date and the link. The fields come from the listing itself, so what is missing on LinkedIn is missing here too. A posting with no stated salary returns no salary rather than a guess.

The call

The scraper takes a search query and a location, which are the same two things you would type into the site:

curl -X POST "https://api.apify.com/v2/acts/parseforge~linkedin-jobs-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQuery": "software engineer",
    "location": "United States",
    "datePosted": "anyTime",
    "maxItems": 50
  }'

The response is the dataset: a JSON array, one object per posting. There is no pagination to handle and nothing to parse.

datePosted is the filter worth knowing about. Set it to the last day or the last week and a nightly run only brings back what is new, which keeps both the run and your deduplication cheap.

Getting it into a spreadsheet

Every run writes to a dataset that exports in other formats. Swap the endpoint and you get a CSV instead of JSON:

https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv

That URL is stable, so a spreadsheet can pull it directly. In Google Sheets, IMPORTDATA against it gives you a sheet that refreshes on its own.

Running it nightly

Two options, both without a server:

What breaks, and what does not

LinkedIn changes its markup. When it does, the scraper is repaired and rebuilt. The thing that does not change is the call above: same endpoint, same input fields, same shape coming back. That is the part worth integrating against.

The harder limit is scope. This reads public job listings. It does not sign in, and it does not reach anything behind an account.

Browse the library