You can scrape LinkedIn company data in Python by sending a list of company page URLs to Datablist's API with the Requests library. The API returns structured company records with fields such as industry, employee count, headquarters, website, and description when they are available on the public company page.
In this guide, I use one readable Python function to retrieve records for n8n, PostHog, Back Market, and Datablist. Then I reuse those results to qualify software accounts with 50 to 500 employees in the United States or Germany. The qualified record keeps its website and description for deeper sales research.
🔑 Summary For Those In a Rush
Datablist turns reviewed LinkedIn company page URLs into structured company records that you can use in a sales-research workflow. The Python example below retrieves every result page, then applies a local account filter without making a second API call.
- Input: LinkedIn company page URLs.
- Output: Available company details and a local qualification decision, with the original URL and complete company output kept together.
💡 Prefer a no-code solution? Use Datablist's LinkedIn Company Page Scraper to extract company fields from known LinkedIn company page URLs without writing code.
Set up Python and your Datablist API key
For this Python example, I use the requests package. Datablist's REST API is
available on the Growth plan, and each company-page lookup consumes enrichment
credits.
Create a Personal API Key from your Datablist API account page.
Create a file named scrape_linkedin_companies.py, then prepare a virtual
environment and install Requests:
python -m venv .venv
source .venv/bin/activate
python -m pip install requests
export DATABLIST_API_KEY="your-api-key"The script reads the key from DATABLIST_API_KEY and sends it in the
X-API-Key header.
Scrape LinkedIn company pages with one Python function
The source list below contains companies with different industries, sizes, and
headquarters countries. Each account_id becomes the API's inputId. Results
are not joined by their position in the response, so this stable ID is what
connects each result to the correct source URL.
Paste this complete script into scrape_linkedin_companies.py:
import json
import os
import time
import uuid
import requests
accounts = [
{
"account_id": "account-n8n",
"linkedin_company_url": "https://www.linkedin.com/company/n8n/",
},
{
"account_id": "account-posthog",
"linkedin_company_url": "https://www.linkedin.com/company/posthog/",
},
{
"account_id": "account-back-market",
"linkedin_company_url": "https://www.linkedin.com/company/back-market/",
},
{
"account_id": "account-datablist",
"linkedin_company_url": "https://www.linkedin.com/company/datablist/",
},
]
def scrape_companies(accounts, api_key):
"""Submit one task, wait for it to finish, and return every result."""
tasks_url = "https://api.datablist.com/v1/enrichments/tasks"
headers = {"X-API-Key": api_key}
inputs = [
{
"inputId": account["account_id"],
"data": {"companyLinkedInUrl": account["linkedin_company_url"]},
}
for account in accounts
]
unique_id = str(uuid.uuid4())
print(f"Request ID: {unique_id}")
payload = {
"enrichmentId": "linkedin-company-enrichment",
"uniqueId": unique_id,
"settings": {},
"inputs": inputs,
}
response = requests.post(tasks_url, headers=headers, json=payload)
response.raise_for_status()
task = response.json()
task_id = task["@id"]
task_url = f"{tasks_url}/{task_id}"
print(f"Task ID: {task_id}")
while task["status"] not in ("completed", "failed", "stopped"):
time.sleep(3)
response = requests.get(task_url, headers=headers)
response.raise_for_status()
task = response.json()
if task["status"] != "completed":
raise RuntimeError(
f"Task {task_id} {task['status']}: {task.get('error')}"
)
results = []
results_url = f"{task_url}/results"
params = {"limit": 100}
while True:
response = requests.get(results_url, headers=headers, params=params)
response.raise_for_status()
page = response.json()
results.extend(page["results"])
next_cursor = page["nextCursor"]
if next_cursor is None:
break
params["cursor"] = next_cursor
return results
api_key = os.environ.get("DATABLIST_API_KEY")
if not api_key:
raise RuntimeError("Set DATABLIST_API_KEY before running this script.")
company_results = scrape_companies(accounts, api_key)
print(json.dumps(company_results, indent=2, ensure_ascii=False))Run it with:
python scrape_linkedin_companies.pyThe main values to change are the records in accounts. Keep each
account_id stable and unique, then replace linkedin_company_url with a
reviewed LinkedIn company page. The function converts those records into the
API's inputs format and sends the company URL as companyLinkedInUrl.
settings stays empty because this enrichment has no public settings.
The POST creates a background enrichment task. The API responds with 202 Accepted and a task ID, while the Requests client waits by polling the status
URL. This blocking Python code is convenient for a small script, but the task
still runs asynchronously on Datablist's side.
The first GET checks the task itself. A task can finish as completed, failed,
or stopped. The script continues only after completed; otherwise, it raises
an error that includes the task ID and the API's task error. Keep that ID when
you investigate because a failed or stopped task may still have results and
credit usage to review.
Once the task is complete, the final loop fetches result pages with a limit of
100. It fetches the next page until nextCursor is null. Each result keeps
the inputId you supplied, which is why the later qualification loop can join
results correctly even when response order differs from input order.
Read the company result and understand the retrieval method
The LinkedIn URL identifies the company directly. Datablist normalizes that organization URL and retrieves the available public company-page data rather than searching for and scoring several possible companies. For a named company URL, it starts from the public page and can fill unresolved fields from managed fallback sources while keeping useful values already found.
That distinction matters when you read the result. Optional fields depend on what is publicly available. A null headquarters address or a missing specialty does not mean that the whole company lookup failed.
Here is the complete results page returned for the four URLs:
{
"taskId": "69516a973dc34481920f41ade748e917",
"results": [
{
"inputId": "account-n8n",
"status": "success",
"outputs": {
"companyName": "n8n",
"companyHQPostalCode": "10115",
"companyDescription": "n8n is a workflow automation platform that uniquely combines AI capabilities with business process automation. The platform enables connection to any app or API while maintaining the flexibility of code with the speed of no-code.\n\nReleased under a fair-code license, n8n can be self-hosted and is supported by a vibrant community of developers and builders. Users can start simple and layer complexity as needed - utilizing the visual builder for quick wins, and adding custom Javascript or Python code where more control is required, enabling the connection of anything to everything.\n\nn8n is privately held, with funding from Sequoia, Felicis Ventures, Firstminute Capital, Harpoon Ventures, and others. Individual investors include Eventbrite's Kevin Hartz and Supercell's IIkka Paananen. n8n was founded in 2019 and is headquartered in Berlin.",
"companyTagline": "Flexible AI workflow automation for technical teams.",
"companyIndustry": "Software Development",
"companySpecialities": "AI, SOAR, Workflow Automation, and AI agents",
"companyWebsite": "https://n8n.io",
"companyHQCity": "Berlin",
"linkedInCompanyId": "28491094",
"companyType": "Privately Held",
"companyHQCountry": "DE",
"companySize": 1389,
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/D4D0BAQEgEphZqatXwA/company-logo_200_200/B4DaFY.Sa2JcAE-/0/1792494086070/n8n_logo?e=2147483647&v=beta&t=NTL4C6f5QAd_o9nXd15PO8pOMSSEoms_tJdDHEo6eLk",
"companyHQAddress": "Novalisstraße 10",
"companyFoundedYear": 2019,
"companyFollowerCount": 442229
},
"creditsUsed": "25",
"error": null
},
{
"inputId": "account-posthog",
"status": "success",
"outputs": {
"companyName": "PostHog",
"companyHQPostalCode": null,
"companyDescription": "At PostHog, we're working to increase the number of successful products in the world.\n\nUntil now, tools for building products have been fragmented. Product analytics, heatmaps, session recording, web analytics, feature flags, and A/B testing are all helpful, but no one wants to buy, send data to, and integrate multiple products.\n\nPostHog offers these tools (and more) in an integrated, open source platform which can be hosted in either the US or EU. Both versions are SOC2 certified, GDPR-ready, and HIPAA compliant. \n\nWe started PostHog during Y Combinator's W20 cohort and had the most successful B2B software launch on Hacker News since 2012 - with a product that was just 4 weeks old.\n\nWith over 100,000 users, we're default alive, growing 97% through word of mouth, and we are in the top 0.01% most popular repos on GitHub.",
"companyTagline": "Your product's context layer. Get started with npx @posthog/wizard",
"companyIndustry": "Software Development",
"companySpecialities": "analytics, open source, product analytics, product, data, engineering, self-driving product, session replay, context warehouse, AI, product context, and error tracking",
"companyWebsite": "https://posthog.com/",
"companyHQCity": "San Francisco",
"linkedInCompanyId": "37415928",
"companyType": "Privately Held",
"companyHQCountry": "US",
"companySize": 234,
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/D560BAQGQUyE_CXUxIw/company-logo_200_200/B56aCMWEgaJAAE-/0/1789060991251/posthog_logo?e=2147483647&v=beta&t=WfTGRSqp5UfYL33sBXx3tZ1zmFUECfUPf7JtEGPAvbA",
"companyHQAddress": null,
"companyFoundedYear": 2020,
"companyFollowerCount": 59696
},
"creditsUsed": "25",
"error": null
},
{
"inputId": "account-back-market",
"status": "success",
"outputs": {
"companyName": "Back Market",
"companyHQPostalCode": null,
"companyDescription": "The world is waking up to what fast tech costs. Back Market is where the revolution shops. \nWe make refurbished tech the smart, confident choice by building trust in quality, repair and circularity. New is not always better. Smarter is.\n\nAs a certified B Corp, our mission is to create a world that does more with what we already have by prolonging the lifespan of electronic devices through circularity and repair. We have grown by double digits year over year and now serve 18 million customers across 17 markets, avoiding more than 2 million tons of CO2 emissions*\n*Back Market calculation based on ADEME 2022 methodology.\n\nFounded in Paris in 2014 by Thibaud Hug de Larauze, Quentin Le Brouster and Vianney Vaute, Back Market is a leading global marketplace where people can buy professionally refurbished technology or trade in their devices.\n\nAre you ready to join us?",
"companyTagline": "Where the world shops refurbished tech.",
"companyIndustry": "Internet Marketplace Platforms",
"companySpecialities": "refurbished tech, marketplace, sustainability, circularity, Right to Repair, sustainable solutions, refurbished marketplace, circular economy, and sustainable alternatives",
"companyWebsite": "http://www.backmarket.com",
"companyHQCity": "Paris",
"linkedInCompanyId": "4793443",
"companyType": "Privately Held",
"companyHQCountry": "FR",
"companySize": 1054,
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/D4E0BAQHRv6UClt5D2g/company-logo_200_200/B4EZnoUG3tKgAI-/0/1760539209613/back_market_logo?e=2147483647&v=beta&t=Pywpeu1Qs3h0Cl8kgvYurmBfXbImm5QIIc-aQog1MqM",
"companyHQAddress": null,
"companyFoundedYear": 2014,
"companyFollowerCount": 101878
},
"creditsUsed": "25",
"error": null
},
{
"inputId": "account-datablist",
"status": "success",
"outputs": {
"companyName": "Datablist",
"companyHQPostalCode": null,
"companyDescription": "When people hear \"data,\" they think of something complicated. We will change this.\n\nDatablist is an AI-powered spreadsheet that helps you: get, manipulate, or clean data and create workflows that run automatically while you focus on what matters most.\n\nIf you want to separate Datablist.com into its main parts, you can say we have:\n\n- Deduplicating, grouping, and labeling data\n- Cleaning and editing data\n- Managing data and automated workflows\n- 50+ B2B data sources and scrapers\n- 3 AI agents:\n - Editing assistant\n - AI Research agent\n - Deduplication assistant\n\nThe top 3 reasons why companies choose Datablist.com are:\n\n1. Simplicity: you don't need to have technical knowledge or experience with formulas to get everything out of it.\n2. Flexibility that allows you to do (almost) everything with your data and AI while keeping everything under your control.\n3. Scalability that no other solution can match. Up to 2 million rows—forget Excel.\n\nGo on try it for free!\n\nhttps://www.Datablist.com",
"companyTagline": "Let your tasks become workflows: automated workflows.",
"companyIndustry": "Information Technology & Services",
"companyWebsite": "https://www.datablist.com",
"companyHQCity": "Paris",
"linkedInCompanyId": "69842428",
"companyType": "Privately Held",
"companyHQCountry": "FR",
"companySize": 3,
"companyLogoUrl": "https://media.licdn.com/dms/image/v2/C4E0BAQFNFlMb8KEPRQ/company-logo_200_200/company-logo_200_200/0/1630622803412?e=2147483647&v=beta&t=UVkk7BOerChiWgS9Y06zOpT08SlK4kpAWGDYiVvUEVU",
"companyFollowerCount": 134,
"companyFoundedYear": 2020,
"companyHQAddress": null
},
"creditsUsed": "25",
"error": null
}
],
"nextCursor": null
}All four rows succeeded and used 25 credits each. PostHog returned Software Development, 234 employees, US headquarters, its website, and its description.
n8n is also a software company in a selected country, but its returned employee
count is 1,389. Back Market returned Internet Marketplace Platforms, 1,054
employees, and FR headquarters. Datablist returned Information Technology & Services, 3 employees, and FR headquarters.
The complete object is useful because account research rarely stops at one field. You can qualify with industry, employee count, and country while keeping the exact returned website and description for the next research step.
In this response, companySize is the returned employee count, not a LinkedIn
size-range label. companyHQCountry is the headquarters location, not every
country where the company operates. Those distinctions matter when you adapt
the size and country filters to your ideal customer profile.
Optional fields do not all have to be present for qualification. A missing
address or specialty can remain empty when industry, employee count, and
headquarters country are available. Keep companyWebsite as returned instead
of assuming the API converts it to a bare domain. The description can help a
sales researcher understand the company's product and prepare account-specific
research before outreach. The result-level status, creditsUsed, and error
should stay beside the company fields when you review or store the record.
Qualify accounts for sales research
Suppose your target is a software or technology company with 50 to 500 employees
and headquarters in the US or Germany. Add this loop below the complete script.
It reuses company_results, so it does not submit another task:
accounts_by_id = {account["account_id"]: account for account in accounts}
qualified_accounts = []
other_accounts = []
for result in company_results:
account = accounts_by_id.get(result["inputId"])
qualification = "needs_review"
if result["status"] == "success":
outputs = result["outputs"]
industry = outputs.get("companyIndustry")
company_size = outputs.get("companySize")
country = outputs.get("companyHQCountry")
if industry and isinstance(company_size, (int, float)) and country:
industry_matches = any(
keyword in industry.lower()
for keyword in ("software", "technology")
)
size_matches = 50 <= company_size <= 500
country_matches = country in {"US", "DE"}
if industry_matches and size_matches and country_matches:
qualification = "qualified"
else:
qualification = "not_qualified"
source_url = None
if account is not None:
source_url = account["linkedin_company_url"]
reviewed_account = dict(result)
reviewed_account["sourceLinkedInUrl"] = source_url
reviewed_account["qualification"] = qualification
if qualification == "qualified":
qualified_accounts.append(reviewed_account)
else:
other_accounts.append(reviewed_account)
print(json.dumps(qualified_accounts, indent=2, ensure_ascii=False))PostHog maps back to account-posthog even if the API returns rows in a
different order. It qualifies because Software Development, 234 employees,
and US pass all three checks. The loop copies the original result with its
complete outputs, returned https://posthog.com/ website, description,
creditsUsed, and error. It adds only the source URL and local qualification
label.
n8n maps to account-n8n and does not qualify because 1,389 employees exceeds
the upper limit. Back Market misses the selected industry, size, and country,
while Datablist is below the size range and outside the selected countries.
Future unsuccessful or incomplete rows receive needs_review rather than being
silently discarded.
You can download the maintained synchronous Requests example or use the repository's async HTTPX alternative when you need non-blocking application code.
Estimate LinkedIn company scraping credits
A standard named LinkedIn company page uses 25 credits. A numerical company-ID
URL can use 75 credits when the final fallback is needed, but 75 credits is not
the price of every numerical URL. Failed or no-match lookups can also consume
credits, so use the task's total and each result's creditsUsed value as the
record of actual usage.
The four named URLs in this guide used 100 credits in total. At the standard rate, 1,000 company pages use 25,000 credits. Numerical-ID-heavy input needs more room for the possible 75-credit path.
REST API access requires the Growth plan. The monthly plan includes 20,000 credits, and top-up credits are a separate purchase. At the current USD base top-up of $20 for 20,000 credits, one credit costs $0.001. At that rate, 25,000 credits are worth $25. Check Datablist pricing for the current plan and credit catalog.
Fix common input, task, and result problems
DATABLIST_API_KEYis missing: the script stops before sending a request. Export the variable and run the file again.- The API rejects the key: verify your Personal API Key and keep it in the
X-API-Keyheader used by the example. - The source URL is invalid: replace a personal profile, unrelated site, blank value, or malformed URL with a supported public LinkedIn company, school, showcase, numerical-ID, or Sales Navigator company URL.
- Credits are insufficient: check your balance, then use included credits or add a top-up before creating another task.
- The task is
failedorstopped: inspect its error, existing results, and credit usage before deciding whether to submit another paid task. - A result is sparse,
no_result, orerror: keep its source URL, status, credits, and error for review. Confirm that the input is a public company page before resubmitting, without guessing why the data was unavailable.
If the creation response is lost, use the request ID that the script printed
before the POST. List tasks first and match that value in uniqueId:
curl "https://api.datablist.com/v1/enrichments/tasks?limit=100" \
-H "X-API-Key: $DATABLIST_API_KEY"The matching task's @id is the task ID. Use it to continue checking
/v1/enrichments/tasks/{taskId} or to fetch
/v1/enrichments/tasks/{taskId}/results instead of automatically creating
another task. A single request can contain up to 10,000 inputs and 10 MiB; see
the task documentation
for retention and other lifecycle details.
Next steps
You now have one reusable Python Requests function that turns a list of LinkedIn company page URLs into structured company records, plus a local qualification loop that preserves the full API output for sales research.
Replace the four examples with a small reviewed account list, keep stable IDs, and adjust the industry, employee-count, and country rules to match your ideal customer profile. If your starting points are people rather than companies, use the LinkedIn profile scraper API guide. If you only have company names, start by finding company websites in Python.


