---
title: "Retrieve a user's profile"
method: GET
path: "/v1/{account_id}/users/{user_id}"
tags: ["Users"]
---

# Retrieve a user's profile

`GET /v1/{account_id}/users/{user_id}`

## Request

- Base URL: `https://api.curviate.com`
- URL: `https://api.curviate.com/v1/{account_id}/users/{user_id}`
- Auth: HTTP bearer

Returns a LinkedIn user's profile. Use user_id="me" for the caller's own account, or another LinkedIn user's identifier for read-only access. Request extra sections via linkedin_sections.

## Path parameters

- `account_id` string, required
- `user_id` string, required

## Query parameters

- `linkedin_sections` string[]
- `mode` 'live' | 'auto' | 'refill' | 'cache_only'
- `max_age` integer

## Response `200`

The requested user's profile (classic variant). Section arrays are present only when requested via linkedin_sections.

- object: A LinkedIn user's profile (classic variant). Section arrays under specifics (skills, experience, education, etc.) are only present when the corresponding linkedin_sections value was requested. No inline quota; read quota from GET /v1/accounts/{account_id}.
  - `object` 'user_profile', required: Response type discriminator.
  - `id` string, required: The profile's opaque identifier.
  - `type` 'individual' | 'organization' | 'other', required: Profile type.
  - `display_name` string, required: The member's display name.
  - `first_name` string: First name.
  - `last_name` string: Last name.
  - `public_identifier` string: LinkedIn public URL slug (e.g. 'jane-doe').
  - `profile_url` string: Full LinkedIn profile URL.
  - `public_picture_url` string: Profile picture URL.
  - `public_picture_url_large` string: Large profile picture URL.
  - `private_picture_download_url` string: A private, time-limited picture download URL (present only in some responses).
  - `background_picture_url` string: Cover/background photo URL.
  - `description` string: Mirrors the profile headline (the short line shown under the member's name). NOT the About/Summary section; see `bio` for that.
  - `bio` string: The profile's About/Summary section (free text). Distinct from `description`, which mirrors the headline, not this field.
  - `location` string: Geographic location string.
  - `created_at` string: ISO-8601 timestamp for when this profile record was created on the platform.
  - `emails` string[]: Email addresses associated with the profile.
  - `phone_numbers` string[]: Phone numbers associated with the profile.
  - `social_handles` object: Self-declared social handles keyed by platform (e.g. 'github'), each an object naming the handle. Same sensitivity class as `emails`/`phone_numbers` (self-declared contact-class info).
  - `websites` string[]: Personal/professional website URLs associated with the profile.
  - `is_blocked` boolean: Whether the authenticated account has blocked this member.
  - `is_following` boolean: Whether the authenticated account follows this member.
  - `is_verified` boolean: Whether LinkedIn has verified this member.
  - `is_premium` boolean: Same value as specifics.is_premium; prefer the nested field.
  - `language` string: The member's profile language. Distinct from specifics.default_locale/specifics.supported_locales.
  - `followers_count` number: Total follower count.
  - `relations_count` number: Total 1st-degree connection count.
  - `specifics` object, required: Structured profile-lens data, incl. connection distance and (when requested) section arrays.
    - `network_distance` 'SELF' | 'FIRST_DEGREE' | 'SECOND_DEGREE' | 'THIRD_DEGREE' | 'OUT_OF_NETWORK': Connection distance from the operator account.
    - `member_id` string: The member's platform-native ID.
    - `can_send_inmail` boolean: Whether an InMail can be sent to this member.
    - `pronoun` string: The member's stated pronoun, when set.
    - `default_locale` string: The member's default locale.
    - `supported_locales` string[]: Locales supported for this profile.
    - `notify_visit_token` string: An opaque token observed on the wire; no documented consumer yet.
    - `is_open_profile` boolean: Whether the member has Open Profile enabled.
    - `is_premium` boolean: Whether the member has a LinkedIn Premium subscription.
    - `is_influencer` boolean: Whether the member is a LinkedIn influencer.
    - `is_creator` boolean: Whether the member is a LinkedIn creator.
    - `is_hiring` boolean: Whether the member has hiring mode active.
    - `is_open_to_work` boolean: Whether the member has Open to Work enabled.
    - `skills` object[]: Skill entries. Present only when linkedin_skills is requested via linkedin_sections.
      - `name` string: The skill name.
      - `endorsement_count` number: How many people have endorsed this skill.
      - `endorsed` boolean: Whether the operator account has already endorsed this skill.
      - `insights` string[]: LinkedIn-provided insight strings about the skill.
      - `endorsement_id` number: The value passed to POST /v1/{account_id}/users/{user_id}/endorse-skill to endorse this skill. Present ONLY for skills you are eligible to endorse, i.e. those of your 1st-degree connections. Omitted for users outside your network and on your own profile (the skill still lists name, endorsement_count, endorsed, and insights).
    - `experience` object[]: Work experience entries, most recent first. Present only when linkedin_experience is requested via linkedin_sections. An entry with no ended_on is the member's current role.
      - `id` string: Identifier of this work-experience entry. Not a company identifier.
      - `company` object: The employer. An object, not a name string.
        - `id` string, nullable: The organization's platform identifier, when known.
        - `name` string: The organization's name.
        - `public_identifier` string: The organization's public URL slug, when known.
        - `picture_url` string: The organization's logo URL.
        - `profile_url` string: Full LinkedIn URL for the organization.
        - `industries` string[]: The organization's industry labels.
      - `job_title` string: Job title held. This is the title field; there is no 'position' or 'title' key.
      - `started_on` string: Date the role started. Formatted MM/DD/YYYY, month first. The platform records month and year only. Every observed value uses day 01, so read the month and year and ignore the day.
      - `ended_on` string: Date the role ended. Absent while the role is ongoing, so an absent value means current, not unknown. Formatted MM/DD/YYYY, month first, and the day is a derived offset rather than a real date: observed values are the first of the end month plus 29 days, which stays inside the end month for a 30 or 31 day month but pushes a February end into the following March. Subtract 29 days before reading the month and year, otherwise a February end reads as March and overstates the tenure by a month.
      - `location` string: Where the role was based, as written on the profile.
      - `description` string: The member's own description of the role. Passes through verbatim, never stored.
      - `employment_type` string: Employment arrangement, e.g. PERMANENT, PERMANENT_PART_TIME, CONTRACT, CONTRACT_PART_TIME, FREELANCE, SELF_EMPLOYED, INTERNSHIP, APPRENTICESHIP, TEMPORARY, VOLUNTEERING. Not present on every entry.
      - `workplace_type` string: Working arrangement: ON_SITE, HYBRID, or REMOTE. Not present on every entry.
      - `skills` string[]: Skills the member associated with this role.
      - `skills_preview` string: A short summary line of the associated skills.
    - `education` object[]: Education entries. Present only when linkedin_education is requested via linkedin_sections.
      - `id` string: Identifier of this education entry.
      - `school` object: The institution. An object, not a name string.
        - `id` string, nullable: The organization's platform identifier, when known.
        - `name` string: The organization's name.
        - `public_identifier` string: The organization's public URL slug, when known.
        - `picture_url` string: The organization's logo URL.
        - `profile_url` string: Full LinkedIn URL for the organization.
        - `industries` string[]: The organization's industry labels.
      - `degree` string: Name of the degree or qualification.
      - `fields_of_study` string[]: Subjects studied. Plural and always an array, even for a single subject.
      - `grade` string: Grade or academic level reached.
      - `activities` string: Activities carried out during the studies.
      - `description` string: The member's own description of the studies. Passes through verbatim, never stored.
      - `started_on` string: Date the studies started. Formatted MM/DD/YYYY, month first. The platform records month and year only. Every observed value uses day 01, so read the month and year and ignore the day.
      - `ended_on` string: Date the studies ended. Absent while the entry is ongoing, so an absent value means current, not unknown. Formatted MM/DD/YYYY, month first. The platform records month and year only. The day component differs by field on this response: a work-experience end date carries a 29 day offset that can push the value into the following month, while a certification's expiry date uses day 01. Confirm against an entry whose real dates you know before deriving a month from the day here.
      - `skills` string[]: Skills the member associated with the studies.
      - `skills_preview` string: A short summary line of the associated skills.
    - `languages` object[]: Language entries. Present only when linkedin_languages is requested via linkedin_sections.
      - `language` string: Name of the language.
      - `proficiency` string: Stated fluency: ELEMENTARY, LIMITED_WORKING, PROFESSIONAL_WORKING, FULL_PROFESSIONAL, or NATIVE_OR_BILINGUAL.
    - `certifications` object[]: Certification entries. Present only when linkedin_certifications is requested via linkedin_sections.
      - `title` string: Name of the certification. This is the name field; there is no 'name' key.
      - `organization` object: The issuing body. An object, not a name string.
        - `id` string, nullable: The organization's platform identifier, when known.
        - `name` string: The organization's name.
        - `public_identifier` string: The organization's public URL slug, when known.
        - `picture_url` string: The organization's logo URL.
        - `profile_url` string: Full LinkedIn URL for the organization.
        - `industries` string[]: The organization's industry labels.
      - `issued_on` string: Date the certification was issued. Formatted MM/DD/YYYY, month first. The platform records month and year only.
      - `expires_on` string: Date the certification expires. Absent when it does not expire. Formatted MM/DD/YYYY, month first. The platform records month and year only.
      - `license` string: License or credential identifier.
      - `url` string: Public URL for the certification.
      - `skills` string[]: Skills the member associated with the certification.
      - `skills_preview` string: A short summary line of the associated skills.
    - `volunteer_experience` object[]: Volunteering entries. Present only when linkedin_volunteer_experience is requested via linkedin_sections.
      - `organization` object: The organization volunteered for. An object, not a name string.
        - `id` string, nullable: The organization's platform identifier, when known.
        - `name` string: The organization's name.
        - `public_identifier` string: The organization's public URL slug, when known.
        - `picture_url` string: The organization's logo URL.
        - `profile_url` string: Full LinkedIn URL for the organization.
        - `industries` string[]: The organization's industry labels.
      - `role` string: Role held while volunteering.
      - `cause` string: The cause supported, as categorised by the platform.
      - `description` string: The member's own description of the work. Passes through verbatim, never stored.
      - `started_on` string: Date the work started. Formatted MM/DD/YYYY, month first. The platform records month and year only. Every observed value uses day 01, so read the month and year and ignore the day.
      - `ended_on` string: Date the work ended. Absent while the entry is ongoing, so an absent value means current, not unknown. Formatted MM/DD/YYYY, month first. The platform records month and year only. The day component differs by field on this response: a work-experience end date carries a 29 day offset that can push the value into the following month, while a certification's expiry date uses day 01. Confirm against an entry whose real dates you know before deriving a month from the day here.
    - `projects` object[]: Project entries. Present only when linkedin_projects is requested via linkedin_sections.
      - `name` string: Name of the project.
      - `description` string: The member's own description of the project. Passes through verbatim, never stored.
      - `contributors` object[]: Other members credited on the project.
        - `id` string: The member's opaque identifier.
        - `object` string: Object discriminator for the embedded member.
        - `type` string: Profile type (e.g. individual).
        - `display_name` string: The member's display name.
        - `first_name` string: First name.
        - `last_name` string: Last name.
        - `public_identifier` string: LinkedIn public URL slug (e.g. 'jane-doe').
        - `profile_url` string: Full LinkedIn profile URL.
        - `public_picture_url` string: Profile picture URL.
        - `description` string: The member's professional headline.
      - `skills` string[]: Skills the member associated with the project.
      - `skills_preview` string: A short summary line of the associated skills.
      - `started_on` string: Date the project started. Formatted MM/DD/YYYY, month first. The platform records month and year only. Every observed value uses day 01, so read the month and year and ignore the day.
      - `ended_on` string: Date the project ended. Absent while the entry is ongoing, so an absent value means current, not unknown. Formatted MM/DD/YYYY, month first. The platform records month and year only. The day component differs by field on this response: a work-experience end date carries a 29 day offset that can push the value into the following month, while a certification's expiry date uses day 01. Confirm against an entry whose real dates you know before deriving a month from the day here.
    - `recommendations` object: Recommendations written about and by this member. An object with two arrays, not an array. Present only when linkedin_recommendations is requested via linkedin_sections.
      - `received` object[]: Recommendations written about this member.
        - `text` string: The recommendation text. Passes through verbatim, never stored.
        - `caption` string: How the two members worked together, as shown on the profile.
        - `created_on` string: When the recommendation was written.
        - `user` object: The other member involved. May be null when the platform withholds the identity.
          - `id` string: The member's opaque identifier.
          - `object` string: Object discriminator for the embedded member.
          - `type` string: Profile type (e.g. individual).
          - `display_name` string: The member's display name.
          - `first_name` string: First name.
          - `last_name` string: Last name.
          - `public_identifier` string: LinkedIn public URL slug (e.g. 'jane-doe').
          - `profile_url` string: Full LinkedIn profile URL.
          - `public_picture_url` string: Profile picture URL.
          - `description` string: The member's professional headline.
      - `given` object[]: Recommendations this member wrote for others.
        - `text` string: The recommendation text. Passes through verbatim, never stored.
        - `caption` string: How the two members worked together, as shown on the profile.
        - `created_on` string: When the recommendation was written.
        - `user` object: The other member involved. May be null when the platform withholds the identity.
          - `id` string: The member's opaque identifier.
          - `object` string: Object discriminator for the embedded member.
          - `type` string: Profile type (e.g. individual).
          - `display_name` string: The member's display name.
          - `first_name` string: First name.
          - `last_name` string: Last name.
          - `public_identifier` string: LinkedIn public URL slug (e.g. 'jane-doe').
          - `profile_url` string: Full LinkedIn profile URL.
          - `public_picture_url` string: Profile picture URL.
          - `description` string: The member's professional headline.
    - `interests` object: What this member follows, grouped by kind. An object, not an array. Present only when linkedin_interests is requested via linkedin_sections.
      - `top_voices` object[]: Followed LinkedIn Top Voices.
        - `id` string: The member's opaque identifier.
        - `object` string: Object discriminator for the embedded member.
        - `type` string: Profile type (e.g. individual).
        - `display_name` string: The member's display name.
        - `first_name` string: First name.
        - `last_name` string: Last name.
        - `public_identifier` string: LinkedIn public URL slug (e.g. 'jane-doe').
        - `profile_url` string: Full LinkedIn profile URL.
        - `public_picture_url` string: Profile picture URL.
        - `description` string: The member's professional headline.
        - `specifics` object: Follow-relationship detail for this member.
          - `is_following` boolean: Whether this member is followed.
          - `followers_count` number: How many members follow them.
      - `companies` object[]: Followed companies.
        - `object` string: Object discriminator for the followed company.
        - `id` string: The company's platform identifier.
        - `name` string: The company's name.
        - `profile_url` string: Full LinkedIn URL for the company.
        - `public_picture_url` string: The company's logo URL.
        - `followers_count` number: How many members follow the company.
        - `is_following` boolean: Whether this member follows the company.
      - `schools` object[]: Followed schools.
        - `id` string: The school's platform identifier.
        - `name` string: The school's name.
        - `object` string: Object discriminator for the followed school.
        - `profile_url` string: Full LinkedIn URL for the school.
        - `public_picture_url` string: The school's logo URL.
        - `followers_count` number: How many members follow the school.
        - `is_following` boolean: Whether this member follows the school.
      - `newsletters` object[]: Followed newsletters.
        - `id` string: The newsletter's platform identifier.
        - `title` string: The newsletter's title.
        - `description` string: The newsletter's description. Passes through verbatim, never stored.
        - `url` string: Full LinkedIn URL for the newsletter.
        - `posting_frequency` string: How often the newsletter publishes.
        - `public_picture_url` string: The newsletter's cover image URL.
        - `is_subscribed` boolean: Whether this member subscribes to the newsletter.
      - `groups` object[]: Groups joined.
        - `id` string: The group's platform identifier.
        - `name` string: The group's name.
        - `url` string: Full LinkedIn URL for the group.
        - `public_picture_url` string: The group's picture URL.
        - `is_member` boolean: Whether this member belongs to the group.
    - `throttled_sections` string[]: Section names that were requested but throttled by LinkedIn.
  - `observed_at` string, required: ISO-8601 timestamp for when this data was observed on LinkedIn. On a live fetch this is the time of the fetch; on a stored answer it is when the data was actually seen, not when you asked for it.
  - `source` 'store' | 'live', required: Whether this answer came from Curviate's stored copy or from a fresh LinkedIn fetch. A stored answer costs the connected account nothing and is never surfaced to the person being read. It also carries less: fields Curviate does not retain (message bodies, notes, attachments, third-party contact details) are only ever present on a live fetch. Pass mode=live when you need them.
  - `withdrawn` boolean, required: Whether LinkedIn has told us this resource no longer exists, such as a removed profile. When true, the answer above is the copy Curviate still holds and must not be treated as current. Always present; false is the normal case.
  - `withdrawn_at` string: ISO-8601 timestamp for when a fetch MOST RECENTLY found this resource gone on LinkedIn. Every later fetch that finds it gone again moves it. Present only when withdrawn is true.
  - `safety_warning` SafetyWarning: Present on a successful response when this account crossed an account-safety ceiling while the affected budget row is on the default warn posture. The action still happened. Field-identical to the BUDGET_EXHAUSTED error body except that blocked is false and hint.message describes the outcome, so one branch handles both postures and switching the account to enforce is a configuration change rather than a client rewrite.
    - `row` string, nullable, required: The budget row that breached, for example profile_views or pending_invites. Null when the breach is not about a row: an activity_window warning on an action that spends no budget of its own (editing a message, dismissing a notification, a Recruiter or Sales Navigator admin action) is still governed by the hours the account works in. Read hint.parameter for what to change; whenever this is null it names posture, because the activity window edges are set per action type and this action has none, so the levers that reach it are the account timezone and posture.
    - `reset_at` string, nullable, required: The instant the refusal lifts: the window roll on a ceiling refusal, the next window open on an activity-window one. Null in the two cases no clock frees, the pending_invites gauge and InMail credits (row inmail).
    - `hint` object, required
      - `parameter` string, required: The settable parameter on PATCH /v1/{account_id}/safety-policy.
      - `message` string, required: What the condition is and what changing that parameter would do. This is the one field whose text differs from the BUDGET_EXHAUSTED refusal: here it says the action went through, and on a ceiling breach how far past the ceiling this row now stands, rather than telling you to set posture to warn when it already is. Branch on parameter, reason and blocked, never on this text.
    - `reason` 'ceiling' | 'activity_window', required: Which rule was crossed. ceiling means the row's configured limit is spent; activity_window means the account is outside the hours it works in, which is a different fact with a different remedy. hint.parameter names the right setting for each.
    - `blocked` boolean, required: Always false here. True on the BUDGET_EXHAUSTED refusal carrying the same payload.

## Other responses

- `400`: Either a query param failed validation (the error details name the field), or the platform rejected the request for this target profile: The request was rejected as invalid. In the latter case the linkedin_sections value is not at fault, and the same request may succeed on another profile. INVALID_REQUEST also covers `mode=cache_only` sent together with `max_age`: that mode never reaches LinkedIn at any age, so a freshness threshold cannot change its answer, and the pair is refused rather than one of the two being ignored. Drop `max_age`, or use `mode=refill` (stored at any age, fetch only when nothing is stored).
- `401`: Missing or invalid API key.
- `403`: Forbidden. LINKEDIN_FEATURE_NOT_SUBSCRIBED: the connected LinkedIn account's own subscription level does not entitle it to view this person's profile. This is the same condition a people-search result reports in-band as visibility:"hidden" on GET/POST .../search/..., reading a hidden result back always ends here. It is not a bug or a misconfiguration; retrying will not help, and there is no request shape that makes this person readable from this account.
- `404`: The account_id does not belong to this tenant, or the requested user was not found. An id whose connection was replaced or removed also stops resolving here, and it is already absent from the list, so re-read `GET /v1/accounts` for the current id.
- `422`: The account is restricted and cannot be queried (ACCOUNT_RESTRICTED). Nothing is stored for this resource and `mode=cache_only` never fetches (NOT_STORED). Not the same as a 404: the resource may exist, and this API holds no copy of it. Re-read with `mode=refill` or `mode=auto` to fetch it.
- `429`: Rate limited, slow down and retry after the hinted delay.
- `500`: Internal error.
- `502`: A temporary error occurred. Please try again. Under `mode=cache_only` this specifically means the stored copy could not be read: no request was made to LinkedIn, and the same read is worth retrying.
- `503`: Service unavailable.
- `504`: Gateway timeout.

---

[API](https://skmtc.dev/curviate/apis/curviate-api.md) · [All operations](https://skmtc.dev/curviate/apis/curviate-api/llms.txt) · [OpenAPI document](https://skmtc.dev/curviate/apis/curviate-api/revisions/eab848801d95?raw)
