> **For coding agents and LLMs:** This is one page from the Social Fetch docs (markdown export). For curated orientation and workflow guidance, start with [`/llms.txt`](https://www.socialfetch.dev/llms.txt); for agent onboarding and crawl rules, use [`/agents.txt`](https://www.socialfetch.dev/agents.txt); for the full endpoint list with links to pages like this one, use [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt); for one platform's parameters and curls, use [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt); use [`/llms.json`](https://www.socialfetch.dev/llms.json) when you need structured JSON for tool registration.

## This page

- **On-site (HTML):** [https://www.socialfetch.dev/docs/api/v1/linkedin/migration](https://www.socialfetch.dev/docs/api/v1/linkedin/migration)
- **Markdown (.mdx) URL:** [https://www.socialfetch.dev/docs/api/v1/linkedin/migration.mdx](https://www.socialfetch.dev/docs/api/v1/linkedin/migration.mdx)

## API base URL and authentication

- **API origin (from OpenAPI `servers`):** `https://api.socialfetch.dev`
- **Authentication:** send `x-api-key: sfk_...` on `/v1/**` and `/v2/**` routes unless the operation is explicitly anonymous (check OpenAPI `security`, the [API reference hub](https://www.socialfetch.dev/docs/api.mdx), [`/llms.txt`](https://www.socialfetch.dev/llms.txt), or [`/llms.json`](https://www.socialfetch.dev/llms.json) for each route).
- **OpenAPI JSON:** [https://www.socialfetch.dev/openapi.json](https://www.socialfetch.dev/openapi.json)

## Recommended docs entrypoints (this site)

- [Documentation overview](https://www.socialfetch.dev/docs.mdx) — top-level orientation (markdown).
- [Quickstart](https://www.socialfetch.dev/docs/quickstart.mdx) — authenticate with `x-api-key`, validate auth with `whoami`, and understand the JSON envelope.
- [SDK](https://www.socialfetch.dev/docs/sdk.mdx) — official TypeScript SDK guide, including `SocialFetchClient`, `Result`, and `unwrap()`.
- [Capability matrix](https://www.socialfetch.dev/docs/capability-matrix.mdx) — every operation with identifiers, pagination, outcomes, media download, credits, and its SDK method. Generated from OpenAPI, so use it for route selection instead of scanning individual pages.
- [Recipes](https://www.socialfetch.dev/docs/recipes.mdx) — copyable workflows (brand monitoring, transcripts, Ad Library, creator scoring, Reddit research) with credit callouts and SDK examples.
- [Integrations](https://www.socialfetch.dev/docs/integrations.mdx) — MCP for AI clients, n8n verified node, Apify Store Actors, Make custom app, SDK, and REST API connection paths.
- [MCP product page](https://www.socialfetch.dev/mcp) — hosted MCP overview, OAuth, Skills install.
- [MCP integration](https://www.socialfetch.dev/docs/integrations/mcp.mdx) — hosted `/mcp` server, OAuth, Cursor/VS Code/Claude install snippets, 232 endpoint tools, plus docs_search/docs_read for implementation help.
- [n8n integration](https://www.socialfetch.dev/docs/integrations/n8n.mdx) — install `n8n-nodes-socialfetch`, credentials, and workflow examples.
- [Apify integration](https://www.socialfetch.dev/docs/integrations/apify.mdx) — Store Actors under @social-fetch, PPE billing, dataset export, and quick start.
- [Make integration](https://www.socialfetch.dev/docs/integrations/make.mdx) — custom app modules for Make scenarios, API key credentials, and module catalog.
- [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt) — every documented operation with a direct link to that route's agent-readable markdown page (prefer this over parsing OpenAPI).
- [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt) — per-platform endpoint files generated from OpenAPI (parameters, credits, curls).
- [`/agents.txt`](https://www.socialfetch.dev/agents.txt) — agent crawl/onboarding file with capabilities, auth rules, and allowlist.
- [`/llms.json`](https://www.socialfetch.dev/llms.json) — structured machine-readable operation inventory with parameter names, pagination, outcomes, credits, and SDK mapping.
- [API reference hub](https://www.socialfetch.dev/docs/api.mdx) — human-friendly index of operations with links into generated pages.
- [Errors](https://www.socialfetch.dev/docs/errors.mdx) — shared error envelope and HTTP status guidance.
- [Credits](https://www.socialfetch.dev/docs/credits.mdx) — metering, `402`, and planning batch jobs.
- Outcome semantics such as `found`, `not_found`, and `private` are documented in [Errors](https://www.socialfetch.dev/docs/errors.mdx) and on operation pages when present in the OpenAPI contract.

## Markdown docs convention

- Every docs page has a markdown twin: append **`.mdx`** to the docs pathname (for example `/docs/quickstart` → `/docs/quickstart.mdx`).
- Agents that send `Accept: text/markdown` on `/docs/**` HTML URLs may receive markdown directly (same URL, `Vary: Accept`).
- Published blog posts use the same convention: `/blog/{slug}` → `/blog/{slug}.mdx`, or `Accept: text/markdown` on the HTML URL (`Vary: Accept`).

---
# LinkedIn API v1 to v2 migration (https://www.socialfetch.dev/docs/api/v1/linkedin/migration)

# LinkedIn API v1 to v2 migration

The documented LinkedIn surface is v2: typed camelCase fields, explicit lookup outcomes, and one result page per request. Existing `/v1/linkedin` callers keep working. The 30-day HTTP retirement window has **not started**. For new work, use the v2 routes below.

Start with the [LinkedIn API reference](/docs/api/v2/linkedin) for identifiers, credits, and the current route list.

## Route changes

| v1 route                          | v2 route                                                                                                                              | Migration behavior                                                                                                                                            |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/linkedin/profiles`       | `GET /v2/linkedin/profiles` (`handle` or `entityId`) or `GET /v2/linkedin/profiles/batch`                                             | The v2 person record is projected into the legacy response during the compatibility window.                                                                   |
| `GET /v1/linkedin/organizations`  | `GET /v2/linkedin/organizations` (`id`), `GET /v2/linkedin/organizations/resolve` (`slug`), or `GET /v2/linkedin/organizations/batch` | Resolve when needed, enrich, then project into the legacy organization shape.                                                                                 |
| `GET /v1/linkedin/jobs`           | `GET /v2/linkedin/jobs/{jobId}` or `GET /v2/linkedin/jobs/batch`                                                                      | The typed v2 job is projected into the legacy response.                                                                                                       |
| `GET /v1/linkedin/people/search`  | `GET /v2/linkedin/people/search`                                                                                                      | Live discovery records are projected. The v1 response does not preserve v2 pagination availability or facts.                                                  |
| `GET /v1/linkedin/jobs/search`    | `GET /v2/linkedin/jobs/search`                                                                                                        | Use v2 for new work. Filters differ — there is no silent remap of v1 text-location or radius. v1 remains callable until the HTTP retirement window completes. |
| `GET /v1/linkedin/profiles/posts` | `GET /v2/linkedin/people/{entityId}/posts`                                                                                            | Use v2 for new work. Date, authorship, and limit semantics differ from v1. v1 remains callable until the HTTP retirement window completes.                    |

New integrations should call v2. The v1 replacements stay on the wire until the retirement window starts and completes. No sunset date is implied by local implementation or passing tests.

## Field and input changes

Both public API versions use camelCase. V2 introduces richer typed records and keeps stored snapshot IDs, LinkedIn numeric IDs, person entity IDs, handles, and slugs separate. Identifiers are strings; do not convert large activity IDs to JavaScript numbers. Callers use the documented v2 query names.

| v1 profile response                                      | v2 single profile response                                               |
| -------------------------------------------------------- | ------------------------------------------------------------------------ |
| Record inside `data.results[i].profile` for REST batches | Record in `data.profile` for single lookups                              |
| `profile.bio`                                            | `profile.summary`                                                        |
| `profile.avatarUrl`                                      | `profile.profilePictureUrl`, plus all supplied `profile.profilePictures` |
| `profile.experience`                                     | `profile.positions`, retaining nested fields and partial dates           |
| Required legacy arrays may be empty when unavailable     | Missing collection is `null`; observed empty collection is `[]`          |

Legacy rows include typed `compatibility.availability` and `compatibility.omittedEntries` when a projection is available. Use these to distinguish an unavailable section from a verified empty one, and to identify entries that cannot fit an old schema. For example, a publication without a title is retained in v2 and counted as a projection omission in v1. Do not treat a legacy empty array as proof that LinkedIn returned no records.

Partial dates preserve known components. A zero date component becomes `null`; it is not presented as a real year, month, or day. Public responses include `lookupStatus` where the route supports lookup outcomes, so a completed `not_found` or empty result is distinct from a technical failure.

## Requests, pages, and batches

Every request returns one page. When `data.page.nextCursor` is supplied, pass it as `cursor` to the same endpoint with the same entity and filters. The `start` and `page` response fields describe the current page, not the next one. Cursors are bound to the operation, entity, and filters. Unknown `hasMore` and totals remain `null`; do not infer completion from array length or invent an offset when continuation has not been established.

People search defaults to 20 records and accept at most 50 per page. Live people discovery defaults to 20 records; organization and job discovery default to 25. All accept at most 50. V2 rejects unsupported query parameters, including legacy job-search filters whose meaning cannot be preserved.

URL batch routes accept 1–50 repeated `url` parameters. They preserve input order and duplicates, and do not accept enrichment flags. A batch result records each completed input independently, so one unavailable URL does not erase successful rows for the other inputs.

The response limit is 4,000,000 UTF-8 bytes. An oversized response returns HTTP `413 response_too_large` without a charge. Use a smaller batch to reduce the response size. Technical failures are not charged. Completed empty and `not_found` outcomes remain billable at the route price.

Unknown query keys, including former `include*` flags on base profile and organization lookups, are rejected with HTTP `400` and no charge. Related data lives on dedicated routes: employment history, recommendations, similar people, interests, profile posts, organization headcount, similar organizations, affiliated organizations, organization posts, and organization jobs.

## Pricing and freshness

Use the published route price on each docs page and `meta.creditsCharged` as the accounting record.

* Person and job URL batches cost 3 credits per completed URL.
* Organization URL batches cost up to 9 credits per completed URL. A resolver miss costs 3 credits; a technical failure of the whole wrapper costs 0.
* A single profile or person lookup costs 3 credits. An organization costs 6 by ID or up to 9 by slug (3 on resolver miss). Dedicated related-data routes cost 3 credits each.

A cache hit still costs the full published price. The public response does not identify cache provenance; `sourceFamily` is not a cache indicator.

## Example

From SDK 0.30, `client.linkedin.*` calls the v2 routes. The old URL-based methods remain on `client.linkedin.v1`. SDK calls return a `Result`, so check `ok` before reading `value`:

```ts
const result = await client.linkedin.v1.getProfile({ url });
if (result.ok) {
  console.log(result.value.data.profile?.firstName);
} else {
  console.error(result.error.message);
}
```

The default method calls the single profile route directly:

```ts
const result = await client.linkedin.getProfile({
  handle: "ryanroslansky",
});
if (result.ok) {
  const { data, meta } = result.value;
  if (data.lookupStatus === "found" && data.profile) {
    console.log(data.profile.entityId, data.profile.firstName);
  }
  console.log(meta.creditsCharged);
} else {
  console.error(result.error.message);
}
```

Treat a `not_found` result as a completed outcome and inspect `meta.creditsCharged`. Retry technical failures according to the HTTP error and retry guidance rather than converting them into empty data.

Use `client.linkedin.getProfile({ entityId })` when an entity ID is already available. `client.linkedin.v2` is an alias for the same v2 methods. Other platform resources are unchanged.

## Retirement

The six v1 migration routes return `410 endpoint_retired` without a charge after the announced 30-day window. Responses during the window carry deprecation and sunset guidance. Remaining `/v1/linkedin` company, post, transcript, and Ad Library routes are not part of this retirement.