---
title: "Read LinkedIn person"
method: POST
path: "/api/people/read-linkedin"
tags: ["people"]
---

# Read LinkedIn person

`POST /api/people/read-linkedin`

## Request

- Base URL: `https://beta.getsales.io/playtables/v1`
- URL: `https://beta.getsales.io/playtables/v1/api/people/read-linkedin`
- Auth: HTTP bearer and API key in header `Team-SID`

Read one LinkedIn profile by its slug or pasted link, for the person's own card: name, photo (avatar_url), headline, the current role and company (its slug or company_ln_id for read_linkedin_company), location, positions, languages, the identity axes; nothing written. The corpus answers free; a pool read is comped for a workspace's first three, then 5 credits. alive false with reason profile_not_found, profile_unreadable or pool_unavailable (retry_after). A person row is update_person.

Contract:
- MCP tool `read_linkedin_person`, registry package `mcp.playtables/people`, mount `playtables.people`.
- Operation `action`, response envelope `action`.
- Flags: read only.

## Request body

- ReadLinkedinPersonRequest: Request body of `read_linkedin_person`.
  - `ln_nickname` string, required: The profile slug (public identifier), or the linkedin.com/in/ link as the person pasted it; parsed at the edge, never stored.

## Response `200`

`action` success envelope.

- ReadLinkedinPersonResponse
  - `success` true, required
  - `operation` 'action', required
  - `action` string, required: kebab-case verb; matches the route segment.
  - `item` unknown, required
  - `result` object, required
    - `alive` boolean, required: LinkedIn served the profile.
    - `comped` boolean: The read ran on the onboarding allowance at price 0 (the first three pool reads of a team).
    - `person` object, nullable: The profile's words and axes when alive.
      - `full_name` string, nullable, required
      - `headline` string, nullable, required
      - `role_title` string, nullable, required: The current position's title.
      - `company_name` string, nullable, required: The current company's name.
      - `company_ln_nickname` string, nullable, required: The current company's page slug: what read_linkedin_company takes.
      - `company_ln_id` string, nullable, required: The current company's numeric LinkedIn id, as digits: what read_linkedin_company takes as ln_id when the slug is unknown.
      - `location` string, nullable, required
      - `avatar_url` string, nullable, required: The photo, as an https address on our own store (never a LinkedIn address); null when the page shows none. update_user_profile takes it as avatar_url.
      - `positions` object[], required: The experience, newest first.
        - `title` string, nullable, required
        - `company` string, nullable, required
        - `company_ln_nickname` string, nullable, required: This position's company page slug, when the profile names it: what read_linkedin_company takes when the person runs two companies and picks this one.
        - `company_ln_id` string, nullable, required: This position's company id, as digits, when the profile names it: read_linkedin_company's ln_id when the slug is unknown.
        - `from` string, nullable, required: As LinkedIn wrote it ("Mar 2021").
        - `to` string, nullable, required: Null on the position still running: two or more such positions under different companies is the person running two companies, and which one the workspace is for is theirs to say.
      - `languages` string[], required: The Languages card when the profile carries one; empty otherwise.
      - `ln_member_id` integer, nullable, required
      - `ln_id` string, nullable, required: The profile URN.
      - `ln_nickname` string, nullable, required: The public identifier (slug), never a URL.
    - `reason` string: Why alive is false: profile_not_found (no profile at the identifier), profile_unreadable (LinkedIn would not serve it) or pool_unavailable (no capacity: ask again after retry_after).
    - `retry_after` union: With pool_unavailable: when to ask again.
      - string
      - number
      - unknown
  - `meta` object, required
    - `trace_id` string, required: UUID v7; same 128-bit value as the X-Trace-Id header.
    - `span_id` string, required: 16 hex chars, root span of this request.
    - `timestamp` string, required: ISO 8601 UTC (Y-m-dTH:i:sZ), response time.
    - `duration_ms` integer, required: Server-side wall clock.
    - `team_sid` string, nullable: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends.
    - `actor_type` string, nullable: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends.

## Other responses

- `4XX`: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented.
- `5XX`: MCP error envelope with `error.code` internal_error or service_unavailable.

---

[API](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables.md) - [All operations](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables/llms.txt) - [OpenAPI document](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables/revisions/aa394506515d?raw)
