LinkedIn scraper

Extract the people or companies of a LinkedIn or Sales Navigator search with the Emelia LinkedIn Scraper API, find their emails, download the CSV, and get them as an Emelia list.

The LinkedIn scraper extracts the people (or companies) of a LinkedIn search into a CSV, then optionally finds their professional emails. Every finished extraction also becomes an Emelia list, ready to attach to a campaign.

Emelia V3

The V3 flow (scrape into a list) is being documented.

The flow

  1. Connect a LinkedIn account for scraping, with the cookies of a browser session (Connect an account). The Emelia browser extension does it for you.
  2. Start an extraction with the search URL (Start an extraction). It runs in the background.
  3. Follow it: poll Get a scraper every 30 to 60 seconds, or register a webhook.
  4. When status is done: optionally find the emails (Find the emails), then download the CSV (Download the CSV), or use the Emelia list in convertedListId.

Start an extraction

POST/linkedin-scrappers
curl -X POST https://api.emelia.io/linkedin-scrappers \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CTOs SaaS France",
    "authes": ["66e0f1a2b3c4d5e6f7a8b9c0"],
    "url": "https://www.linkedin.com/sales/search/people?query=..."
  }'
# {"success":true,"scrapId":"66e0f1a2b3c4d5e6f7a8b9d0"}

Accepted URLs and accounts

SearchURLauthes
Sales Navigator people searchhttps://www.linkedin.com/sales/search/people...Accounts connected for scraping (the authId of Connect an account)
Sales Navigator lead listhttps://www.linkedin.com/sales/lists/people/...Same
Sales Navigator account search (companies)https://www.linkedin.com/sales/search/company...Same
Classic LinkedIn people searchhttps://www.linkedin.com/search/results/people/...LinkedIn accounts connected to your campaigns, set in the Emelia app

Every account must exist, belong to you and be valid. Several accounts share the chunks of a large extraction; otherwise one of them is picked. Another https://linkedin.com/sales/... URL is accepted at creation, then the scraper stops with BAD_SALES_NAV_URL. plannedStart schedules the start, at least one hour ahead.

How many contacts

  • A Sales Navigator search returns 2,500 results at most (100 pages of 25). Lead lists and saved searches: 2,500. Searches filtered on your network: 1,000. Account searches: 1,000 companies. Classic searches: 1,000 people.
  • Grow and Scale plans: a search of 3,000 results or more that has filters is split automatically into chunks of 2,500 (segmented: true), extracted at 2,500 contacts per day and per LinkedIn account (5,000 with a Sales Navigator Advanced seat). Give several accounts to go faster. Above 80,000 results the scraper stops with TOO_MUCH_RESULT.
  • Start plan: capped at 2,500, no automatic split.
  • max_contacts stops the extraction early (on Sales Navigator, up to 25 more; ignored for split searches).

Plans and credits

Extraction is included in the Emelia subscriptions. Without a subscription, a workspace gets one free extraction, then extracts on credits: about 1 credit per 2 contacts, and the scraper pauses when the credits run out.

Follow an extraction

GET/linkedin-scrappers/{id}
curl https://api.emelia.io/linkedin-scrappers/66e0f1a2b3c4d5e6f7a8b9d0 \
  -H "Authorization: $EMELIA_API_KEY"
statusMeaning
planifiedWaits for its plannedStart.
runningExtracting. scrapIndex contacts out of totalContact (0 until LinkedIn gives the count).
pausedPaused by you (split searches only) or out of credits. Resume an extraction.
doneFinished. The CSV is ready, and the Emelia list follows within a few minutes (convertedListId).
enrichingFinding emails, then done again.
errorStopped. error gives the code: INVALID_COOKIE, 2FA_REQUIRED, BAD_SALES_NAV_URL, NEED_SUBSCRIPTION, TOO_MUCH_RESULT, RATE_LIMIT, SEGMENTATION_ERROR, PROCESS_ERROR, NO_AUTH_FOUND.

After INVALID_COOKIE or RATE_LIMIT, refresh the account with Refresh an account, then resume the scraper. A Sales Navigator RATE_LIMIT is retried on its own about 12 hours later. The other codes are final: start a new extraction.

Find the emails

POST/linkedin-scrappers/{id}/enrich
curl -X POST https://api.emelia.io/linkedin-scrappers/66e0f1a2b3c4d5e6f7a8b9d0/enrich \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"country": "FR"}'
  • Only on a finished people extraction that was never enriched.
  • You need at least as many credits as totalContact. That amount is taken at the start, and the credits of the contacts without email come back at the end: 1 credit per email found.
  • An enrichment ends within about an hour. There is no webhook at the end: poll the scraper until status is done again; enrichFound gives the number of emails found.
  • To pay less, first remove the contacts already extracted by your 10 last scrapers.

Download the CSV

GET/linkedin-scrappers/{id}/download
curl "https://api.emelia.io/linkedin-scrappers/66e0f1a2b3c4d5e6f7a8b9d0/download?format=3" \
  -H "Authorization: $EMELIA_API_KEY" | jq -r .data > contacts.csv

The CSV comes as a string in data, with ; as separator. format is 1 for the contacts with an email (after an enrichment), 2 for the contacts without, 3 for all. It works while the extraction runs: you get what was collected so far. After an enrichment, the email is in email_emelia and its verdict in qualification_emelia.

Webhooks

POST/linkedin-scrappers/{id}/webhook

Register a URL right after starting the extraction, with {"webhookUrl": "https://hooks.yourcompany.com/emelia/scraper", "events": ["FINISHED", "ERROR"]}. Emelia then sends { "event", "id", "name", "error" }:

  • FINISHED when the extraction ends (every chunk included);
  • ERROR when it stops on an error code, at most once per hour for the same code.

Every registered URL receives every event, whatever its events. One attempt only, no signature: check the scraper with GET /linkedin-scrappers/{id} when you receive a call. The success response of this route is an empty object {}.

Scraping accounts

POST/linkedin-scrappers/authes

A scraping account is a LinkedIn session, sent as the cookies of a browser where the user is logged in to LinkedIn and Sales Navigator. li_at is required; li_a, ua, additionnalsCookie (objects { name, value, domain }), viewport and country are strongly recommended. The response gives the authId to use in authes.

Session cookies are secrets

These cookies open the LinkedIn account. Send them only to Emelia, never log them, and protect your API key accordingly. There is no API route to remove a scraping account yet.

When a session expires, update the same account with Refresh an account rather than creating a new one, and send the complete set of cookies every time: omitted fields are cleared.

On this page