LinkedIn profiles in n8n: enrich a list of LinkedIn URLs with one HTTP Request node
You keep LinkedIn profile URLs in a Google Sheet, Airtable or a CRM, and an n8n workflow should fill in each person's name, headline, location, company and title. n8n's own LinkedIn node can't: its one operation creates a post. The usual templates start a scraper on Apify, wait for its run, then read its dataset.
Here it's one HTTP Request node that gets the profile back in the same step, at $1.25 per 1,000 profiles found through Up2Data, nothing for a profile it can't find. You send the provider's own request to api.datacircle.dev, with your Datacircle key. That's the only change. Below, the node, what each answer means, and the whole workflow to import, run on n8n 2.42.6 before it went up.
What you need
- n8n, self-hosted or n8n Cloud. Nothing to install: the workflow uses only n8n's own nodes.
- A Datacircle API key: sign up with your work email and it's on your dashboard, with the $5 credit, 4,000 profiles through Up2Data.
- A list where each item has a
linkedin_url, likehttps://www.linkedin.com/in/williamhgates.
The credential
In n8n, add a credential of the type Header Auth. Name: Authorization. Value: Token, a space, then your key. Save it as Datacircle API key. Both HTTP Request nodes below use it, and the key stays out of the workflow's JSON when you share it.
The HTTP Request node
| Field | Value |
|---|---|
| Method | POST |
| URL | https://api.datacircle.dev/v1/profiles/enrich |
| Authentication | Generic Credential Type, then Header Auth: Datacircle API key |
| Send Headers | X-Data-Provider: up2data |
| Send Body | JSON, Using Fields Below: url = {{ $json.linkedin_url }} |
| Options, Response | Include Response Headers and Status: on. Never Error: on |
| Options, Batching | Items per Batch: 1. Batch Interval (ms): 1000 |
Never Error keeps one private profile from stopping the run: every answer comes out of the node, and its statusCode says what it is. Batching sends one URL at a time, a second apart. Or copy the node and paste it on your canvas:
{
"nodes": [
{
"parameters": {
"method": "POST",
"url": "https://api.datacircle.dev/v1/profiles/enrich",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Data-Provider",
"value": "up2data"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "url",
"value": "={{ $json.linkedin_url }}"
}
]
},
"options": {
"batching": {
"batch": {
"batchSize": 1,
"batchInterval": 1000
}
},
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"name": "Up2Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
300
],
"credentials": {
"httpHeaderAuth": {
"id": "datacircle",
"name": "Datacircle API key"
}
},
"id": "71dd5be5-3c66-4982-8e15-f2421444e60a"
}
],
"connections": {}
}A 200 carries Up2Data's own profile in body.data, and what the call cost and your balance after it in body.datacircle_meta. Every field, jobs, schools and skills included: LinkedIn Profile API.
What each answer means
A Switch node on {{ $json.statusCode }} sends each answer down its own branch:
| Status | What it means | Cost | The branch |
|---|---|---|---|
| 200 | the profile | $0.00125 | Profile: writes the columns |
| 422 | Up2Data can't reach that profile: private or deleted | free | Not found |
| 400 | not a LinkedIn profile URL: a company page or a malformed URL | free | Not a profile URL |
| 429 | Up2Data's daily limit, or its own rate limit | free | HarvestAPI: the same URL, $0.0037 found, $0.0023 not found |
| other | 401: the key is wrong; 402: your balance; 502, 503 or 504: the provider failed | free | Error: the status and the reason, to run again |
Up2Data takes $1 a day per account (800 profiles), with a shared daily limit for all customers, then answers 429 until 00:00 UTC; HarvestAPI has no daily limit. So past 800 profiles in a day, the workflow sends each URL to HarvestAPI, through the same key: a GET with the URL as a query parameter and X-Data-Provider: harvestapi. HarvestAPI answers a 200 even when it finds nothing; then body.element is null and the row says not found (HarvestAPI). A call your balance can't cover answers 402. Add funds, from $5, on your dashboard.
The whole workflow
Download the workflow (JSON), then in n8n open a new workflow and import it from the file, or paste its contents on the canvas. Pick your Datacircle API key credential on the two HTTP Request nodes. Swap the LinkedIn URLs node, two example URLs, for your own source: a Google Sheets, Airtable or CRM node whose items have a linkedin_url. After the five branches, add the node that writes the rows back.
Every branch ends with the same columns, so one write node takes them all:
| Column | From Up2Data | From HarvestAPI |
|---|---|---|
| linkedin_url | your item | your item |
| status | found, not found: private or deleted, free, not a profile URL, free or error with the status and the reason | found (HarvestAPI), not found (HarvestAPI) or error with the status and the reason |
| full_name | data.full_name | element.firstName + lastName |
| headline | data.headline | element.headline |
| location | data.location.raw | element.location.linkedinText |
| company | data.current_company.name | element.currentPosition[0].companyName |
| title | data.current_company.title | element.currentPosition[0].position |
| industry, headcount | data.current_company.industry, .headcount | empty |
| cost_usd | datacircle_meta.cost_usd | datacircle_meta.cost_usd |
We ran this file on n8n 2.42.6, self-hosted, against a stand-in of the API that answers as its reference does. With four URLs, a profile came out found, a private one not found for free, a company page not a profile URL for free, and a profile past the daily limit found (HarvestAPI). With a wrong key, every row came out error 401, and nothing stopped the run.
What it costs
From the pricing, per profile, taken from your balance with nothing added:
| Up2Data | HarvestAPI | |
|---|---|---|
| Profile found | $0.00125 | $0.0037 |
| Per 1,000 found | $1.25 | $3.70 |
| Profile not found | free | $0.0023 |
| Daily limit | 800 profiles per account | none |
So a sheet of 1,000 URLs run in one day, every profile found, costs $1.00 for the first 800 through Up2Data and $0.74 for the other 200 through HarvestAPI: $1.74. Spread over two days, 500 a day, they fit in your account's Up2Data limit: $1.25.
The same call from Python: get LinkedIn profile data with Python. In a Google Sheet, without n8n: LinkedIn profiles in Google Sheets. From a Clay table: Clay alternative. What Apify's LinkedIn profile actors cost next to it: Apify LinkedIn profile scraper alternative; and every vendor's price per 1,000: LinkedIn profile API pricing compared.
Questions
Can n8n scrape LinkedIn profiles?
Not with its own LinkedIn node: its one operation creates a post, as you or your company page. An HTTP Request node can call a LinkedIn profile API instead: send the profile's URL, get JSON back. Through Datacircle: POST {"url": "<the profile's LinkedIn URL>"} to https://api.datacircle.dev/v1/profiles/enrich, with your key in a Header Auth credential and the header X-Data-Provider: up2data.
How much does it cost to enrich LinkedIn profiles in n8n?
$1.25 per 1,000 through Up2Data (a profile it can't find is free), $3.70 per 1,000 through HarvestAPI. n8n doesn't charge per HTTP request: each call is taken from your Datacircle balance. 1,000 profiles found in a day: 800 through Up2Data ($1.00) and 200 through HarvestAPI ($0.74), $1.74 in all.
Is there a daily limit?
Up2Data takes $1 a day per account (800 profiles), with a shared daily limit for all customers, then answers 429 until 00:00 UTC; HarvestAPI has no daily limit.
Is each request live, or cached?
Live. Each request goes to the provider and gets the profile as it is today.
Does it need a LinkedIn account, a cookie or Apify?
No. The HTTP Request node sends a URL to an API and gets JSON back in the same step: no LinkedIn login, no session cookie, no actor run to start and wait for. You need a Datacircle API key.
What happens when my balance runs out?
A call your balance can't cover answers 402. Add funds, from $5, on your dashboard.
Sign up at datacircle.dev with your work email: a $5 credit, that's 4,000 LinkedIn profiles at $1.25 per 1,000. Free: 10M+ U.S. B2B leads, as a flat file. Download it at datacircle.dev.
Sign up