> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datacircle.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# LinkedIn Profile API

> Up2Data's, HarvestAPI's and Fetchin's own APIs, through your Datacircle key, with no markup.

Send the provider's own request to `api.datacircle.dev`. Only two things change: the host, and the `X-Data-Provider` header that names the provider. Your Datacircle key goes in `Authorization`. What each one costs, side by side: [Pricing](/pricing).

Every call is live: Datacircle asks the provider when you call, every time, so you get the profile as it is today, a profile you asked for last week included.

## Up2Data

```bash theme={null}
curl -X POST "https://api.datacircle.dev/v1/profiles/enrich" \
  -H "Authorization: Token $DATACIRCLE_API_KEY" \
  -H "X-Data-Provider: up2data" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.linkedin.com/in/williamhgates"}'
```

| Body field | Meaning |
| - | - |
| `url` | required: the profile's LinkedIn URL (`https://www.linkedin.com/in/williamhgates`). Up2Data refuses a bare public identifier (`400`) |
| `fields` | only these top-level fields of `data`, same price |
| `with_followers_and_connections` | adds `followers_count` and `connections_count`, same price, slower |
| `with_full_skills_and_endorsements` | every skill (not just the first 20) plus `skill_endorsements`, same price, slower |

The answer is Up2Data's own (`data`, `meta`), minus `meta.creditsRemaining`, `meta.requestId`, `meta.latencyMs` and `error.requestId` (our account with Up2Data), plus `datacircle_meta`. Every field is in the API reference: [Enrich one LinkedIn profile](/api-reference/up2data/enrich-one-linkedin-profile).

## HarvestAPI

```bash theme={null}
curl "https://api.datacircle.dev/linkedin/profile?url=https://www.linkedin.com/in/williamhgates" \
  -H "Authorization: Token $DATACIRCLE_API_KEY" \
  -H "X-Data-Provider: harvestapi"
```

| Query parameter | Meaning |
| - | - |
| `url` | required: the profile's LinkedIn URL (`https://www.linkedin.com/in/williamhgates`) |

HarvestAPI takes other parameters too. Datacircle passes only `url` on and refuses any other with a `400`, not charged.

The answer is HarvestAPI's own (`element`, `status`, `query`, `cost`, `payments`, ...), minus `user` and `requestId` (our account with HarvestAPI), plus `datacircle_meta`. HarvestAPI answers a `200` even when it can't find the profile: then `element` is `null`, `status` is `404`, and the lookup is billed (\$0.0023). Every field is in the API reference: [Get one LinkedIn profile](/api-reference/harvestapi/get-one-linkedin-profile).

## Fetchin

```bash theme={null}
curl "https://api.datacircle.dev/api/v1/profile?profileUrlOrUrn=https://www.linkedin.com/in/williamhgates" \
  -H "Authorization: Token $DATACIRCLE_API_KEY" \
  -H "X-Data-Provider: fetchin"
```

| Query parameter | Meaning |
| - | - |
| `profileUrlOrUrn` | required: the profile's LinkedIn URL (`https://www.linkedin.com/in/williamhgates`) |

Fetchin also takes a public identifier or a profile URN in `profileUrlOrUrn`, and `fullProfile`, a call billed twice. Datacircle passes on only a LinkedIn profile URL in `profileUrlOrUrn` and refuses anything else with a `400`, not charged.

The answer is Fetchin's own profile object (`firstName`, `title`, `experiences`, `educations`, `skills`, ...), plus `datacircle_meta`. A profile Fetchin can't find is its `404` (`code: PROFILE_NOT_FOUND`), and the lookup is billed (\$0.001485). Every field is in the API reference: [Get one LinkedIn profile](/api-reference/fetchin/get-one-linkedin-profile).

## What Datacircle adds

One object in every JSON answer:

```json theme={null}
"datacircle_meta": {"provider": "up2data", "cost_usd": 0.002375, "balance_usd": 4.997625}
```

| `datacircle_meta` field | Meaning |
| - | - |
| `provider` | which provider answered |
| `cost_usd` | what this call cost, in dollars: the provider's price, no markup |
| `balance_usd` | your balance after the call, in dollars |

| Status | When |
| - | - |
| `200` | the profile, and HarvestAPI's answer for a profile it can't find (`element: null`, `status: 404`, charged \$0.0023: HarvestAPI bills the lookup) |
| `400` | an `X-Data-Provider` value that isn't `up2data`, `harvestapi` or `fetchin`. Up2Data: a body that isn't a JSON object, or Up2Data's own `400`, passed on (`error.type: invalid_request`: a `url` that isn't a LinkedIn profile URL, a field it doesn't take). HarvestAPI: no `url`, a `url` that isn't a LinkedIn profile URL, or a query parameter other than `url`. Fetchin: no `profileUrlOrUrn`, one that isn't a LinkedIn profile URL, or a query parameter other than `profileUrlOrUrn`. Not charged |
| `404` | no `X-Data-Provider` header, or a path Datacircle doesn't call for that provider (e.g. `X-Data-Provider: harvestapi` on `/v1/profiles/enrich`), and Fetchin's answer for a profile it can't find (`code: PROFILE_NOT_FOUND`, charged \$0.001485: Fetchin bills the lookup) |
| `401` | missing or invalid API key |
| `402` | your balance can't cover the call |
| `422` | Up2Data can't reach that profile (private or deleted). Not charged |
| `429` | Datacircle's daily Up2Data limit, Up2Data's own rate limit, or Fetchin's (5 requests a second for all Datacircle customers together, so send the same request again in a second). Not charged |
| `502` | the provider's own server failed: Up2Data's gateway answered an error page three times in a row (Datacircle sent the same request again twice first), or HarvestAPI's, passed on as it came. Not charged. Send the same request again. A gateway's `503` or `504` page passes on the same way |
| `503` | the provider hasn't answered within 45 s, retries included, or can't be reached, or HarvestAPI or Fetchin refused Datacircle's own account: Datacircle stops waiting and answers `error` and `balance_usd`, as for a `402`. Not charged. Send the same request again in a few seconds |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.