LinkedIn Scraper API
Send a LinkedIn handle — a profile slug, a company slug, or a full URL — and get the structured record back as JSON. No parsing, no browser automation, no IP management on your side. Billed per request from a wallet that is entirely separate from your proxy GB.
Every endpoint here returns 403 Forbidden until scraper access
is enabled on your account. Email support@globedata.io
to turn it on and to buy request bundles.
Rotating and sticky sessions, TTL, geo-targeting and the Reseller API live in the
Proxy & Reseller API reference. Same gd_ key,
different billing: proxies are metered in GB, scrapes in requests.
How it works
One call in, one record out. The only concept you need is the request wallet.
amazon, rbranson, or the full LinkedIn URL — both forms are equivalent.data, plus your remaining balance on every response.Your balance travels with every scrape response, so a well-written client
never has to poll /credits to know where it stands.
Quickstart
Three steps to your first record.
Create an API key
In the dashboard open Scraper →
API Keys → New API Key. The key looks like
gd_a1b2c3… and is shown exactly once — we keep only a
SHA-256 hash. Resellers can reuse an existing reseller key instead; it is the same credential
type.
Check your balance
Confirms both the entitlement and the wallet in one call. A 403 here means
scraper access is not enabled yet.
Scrape something
The response carries the record under data and your new balance under
requests_remaining.
Authentication
One header on every request. Same key format as the Reseller API.
A key inherits the permissions of the account that owns it. Keys never expire; revoke them from the dashboard when one is rotated or leaked, and revocation is immediate. Each key has its own rate-limit bucket, so a bulk enrichment job cannot starve your live app — use one key per consumer.
| Status | Reason |
|---|---|
401 | Header missing or malformed, key not found, key revoked, or account inactive |
403 | Scraper access is not enabled on the account — or a reseller-only endpoint was called by a non-reseller |
429 | More than 60 requests in the trailing 60 seconds for this key |
Endpoints
Two scrape endpoints, two account endpoints, and two reseller endpoints for distributing requests to sub-users.
Billing
Every scrape costs exactly 1 request, person or company. What matters is which outcomes are billable — we charge only for what our upstream charges us.
| Outcome | You receive | Charged | What to do |
|---|---|---|---|
| Profile found | 200 | Yes | Use data. Cache it. |
| Bad target, or profile does not exist | 400 / 404 | Yes | A valid lookup for a non-existent profile is still work. Do not retry — record the miss. |
| Upstream at capacity | 429 | No | Already retried internally and refunded. Wait a few seconds, retry. |
Upstream 5xx, timeout, transport error | 503 | No | Retry with backoff. |
| Empty wallet | 402 | No | Nothing was scraped. Top up. |
Responses carry both requests_* and credits_* fields.
requests_* is the current naming; credits_* is kept as an alias for
older integrations. 1 credit = 1 request — read whichever you already
parse, and do not add them together.
Billing errors in full
Re-reading the same handle costs another request every time. There is no free re-fetch and no deduplication window, so caching is the single biggest lever on your bill. Company records change slowly — a 7 to 30 day TTL on your side is usually safe; profiles change faster but rarely daily.
Best use cases
What this endpoint is genuinely good at, and how to run each job without burning requests.
| Use case | How to run it | Why it works |
|---|---|---|
| Lead enrichment filling in a CRM record from a handle |
Scrape on first sight, cache by handle, re-scrape on a schedule (30–90 days) rather than on every view. | One request per lead per quarter instead of one per page load. The cache is the product. |
| Inbound signup enrichment | Scrape the company handle at signup, inline, and store the result on the account. | One request per signup, at the moment the data is most valuable. Latency is a single call. |
| Recruiting / ATS pipelines | Scrape the person when a candidate enters the pipeline; refresh only on stage change. | Avoids re-scraping a whole pipeline nightly for records that did not move. |
| Account research and territory planning | Batch the company handles for a target list, cap concurrency at the rate limit, persist everything. | A finite, budgetable job: list size = request count. Run it once, query the copy locally. |
| Competitive and market tracking | Scrape a fixed set of companies on a weekly cron and diff against your last snapshot. | Predictable spend (companies × weeks) and the diff is where the signal is. |
| List hygiene | Treat a charged 404 as a real answer — mark the handle dead and stop asking. |
Misses cost the same as hits, so remembering them is what keeps the bill flat. |
| White-label resale | Allocate requests to sub-users with allocate-credits; each sub-user draws from their own balance. | Per-customer metering with no accounting on your side. |
Do this, not that
✓ Works well
- Cache by handle, keyed on your side. Every cache hit is a request you did not spend.
- Read the balance off the scrape response (
requests_remaining) instead of polling/credits. - Cap concurrency at your rate limit — 60/min per key means roughly one per second sustained.
- Persist charged misses (
400/404) so a dead handle is never looked up twice. - Retry only
429and503, with exponential backoff and jitter. Those cost nothing. - Alert on low balance before a batch job starts, not after it half-finishes.
✗ Causes problems
- Scraping on page render. A popular record will be re-bought on every view.
- Retrying a
404. It was charged and the answer will not change. - Retrying a
402. The wallet is empty; retrying cannot fill it. - Firing a whole list in parallel. You will hit
429and finish no faster. - Summing
requests_*andcredits_*. They are the same number twice. - Putting the key in a browser or mobile app. It spends real money.
Recipes
Runnable programs for the two jobs everyone writes first.
Batch enrichment with a cache, pacing and correct retries
Reads a list of handles, skips anything already cached, paces itself under the rate limit, retries only what is free to retry, and records charged misses so they are never re-bought.
Distribute requests to sub-users
Resellers only. Tops up any sub-user below a threshold from your free pool, and never over-allocates because it tracks the pool as it spends.
Error reference
Every error is JSON with at least error and message.
Billing-relevant errors also carry charged and upstream_status.
| Status | Meaning | Charged | What to do |
|---|---|---|---|
200 | Success — the record is under data | Yes | Cache it. |
400 | Missing or invalid id, or a charged upstream bad request | Depends — check charged | If charged is absent it was your payload; fix it. If present, record the miss. |
401 | Authentication failed | No | Check the key and that it is not revoked. |
402 | Insufficient request balance | No | Top up. Do not retry. |
403 | Scraper access not enabled, or a reseller-only endpoint | No | Contact support. |
404 | Profile does not exist — a valid lookup with a negative answer | Yes | Mark the handle dead. Never retry. |
409 | Allocation conflict on a reseller endpoint | No | Re-read balances; retrying unchanged will fail again. |
429 | Your key exceeded 60 req/min, or the upstream is at capacity | No | Back off with jitter and retry. |
503 | Upstream unavailable, or the scraper is not configured server-side | No | Retry after a short wait; if it persists, contact support. |
FAQ
Does a company scrape cost more than a person scrape?
No. Both cost exactly 1 request. cost_per_request on GET /credits
reports this, and costs breaks it out per type, so a client can price a batch before
running it.
Why was I charged for a 404?
Because the lookup happened. Determining that a profile does not exist is the same work as
finding one, and our upstream bills it. The response sets charged: true so you can
record the miss and never spend on that handle again.
Do I need to send a full LinkedIn URL?
No. rbranson and https://www.linkedin.com/in/rbranson are
equivalent, as are amazon and https://www.linkedin.com/company/amazon.
Send whichever you already have.
Can my sub-users call this API?
A sub-user can scrape against their own allocated balance if scraper access is enabled for
them, but only a reseller can allocate requests. The two reseller endpoints on this page return
403 for anyone else.
What happens if my balance runs out mid-batch?
The next call returns 402 with required and available,
and nothing is scraped. Nothing is corrupted — top up and resume from where your cache
left off. Checking the balance before a batch avoids the situation entirely.
Is the proxy GB balance related to this?
Not at all. Proxy traffic is metered in GB against a package; scrapes are metered in requests against a wallet. Running out of one has no effect on the other. Proxy documentation lives in the Proxy & Reseller API reference.