---
title: "Read a sender's LinkedIn connection"
method: GET
path: "/sender-profiles/{profile_id}/linkedin/"
tags: ["linkedin"]
---

# Read a sender's LinkedIn connection

`GET /sender-profiles/{profile_id}/linkedin/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/sender-profiles/{profile_id}/linkedin/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Returns whether a LinkedIn account is connected to this sender, and if so its live state: which browsers are connected and when each was last seen, today's usage against each ceiling, how much work is queued, and what the next step waits on and until when (the time between steps, a limit's reset). Not-connected is a normal state rather than a 404: it carries the connection token the person pastes into the extension, and reading it is what mints that token.

## Path parameters

- `profile_id` string, uuid, required

## Response `200`

Successful Response

- LinkedInAccountStateSchema: The sender's LinkedIn state, connected or not. A wrapper rather than a 404 on purpose: "no account yet" is the normal first render of this page, not an error. The connection token is present in BOTH states: shown by default before anything is connected, and available again afterwards for a second browser.
  - `account` LinkedInAccountReadSchema, required
    - `approvals_waiting` integer: How many of this sender's LinkedIn steps wait for a person on Tasks, less those a paused sequence or paused contact holds.
    - `checkpoint_status` 'ok' | 'checkpoint', required: Whether LinkedIn is currently challenging this account.
    - `connection_checks` LinkedInConnectionChecksReadSchema: How the readings of the sender's newest connections are doing. They are how an accepted connection request is noticed: a member found on the list has accepted. The sender's tab shows only the problem states.
      - `awaiting` integer, required: Connection requests a sequence is still waiting to hear an answer to.
      - `gaps` LinkedInConnectionsGapReadSchema[], required: The last week's stretches nobody watched, oldest first.
        - `ended_at` string, date-time, required: The reading that could not prove it missed nothing.
        - `problem` 'no_overlap' | 'short_overlap' | 'reordered' | 'unread_rows' | 'read_failed' | 'member_mismatch' | 'incomplete' | 'sort_unproven' | 'unstable', required: Why a connections reading was a gap or unjudged, as a closed vocabulary. The gaps: nothing shared with the last judged reading (``NO_OVERLAP``, LinkedIn's empty list after one that listed rows included), fewer than two rows shared in order (``SHORT_OVERLAP``), a row of the last reading above the first shared one (``REORDERED``), or more rows nobody could read above the overlap than the last reading had (``UNREAD_ROWS``). The unjudged: the read failed or was skipped (``READ_FAILED``), its keys were salted for a member other than the account's (``MEMBER_MISMATCH``), the list was not read in full (``INCOMPLETE``), its "Recently added" sort was not proven (``SORT_UNPROVEN``), or two snapshots disagreed (``UNSTABLE``). Members are only ever added; a stored value this build does not know reads as None rather than failing the read.
        - `started_at` string, date-time, required: The last reading that worked before it.
      - `last_checked_at` string, date-time, nullable, required: When a reading last worked; null when none has yet.
      - `next_check_at` string, date-time, nullable, required: When the next reading is due; null when none will run (nothing awaited, the browser cannot run one, or its limit is zero).
      - `problem` 'extension_outdated' | 'checks_failing' | 'turned_off', required: The one problem with an account's connection checks a person can do something about. Each is named only while invitations are waiting for an answer. ``EXTENSION_OUTDATED``: the browser driving the account runs a build that cannot read the connections list. ``CHECKS_FAILING``: readings keep failing, and ``last_checked_at`` names the last one that worked. ``TURNED_OFF``: the readings' daily or weekly limit is set to zero. The first and the last are named only once the readings are announced (out of ``UNANNOUNCED_KINDS``): before an extension that runs them is released there is nothing to update to and no limit shown to raise. ``EXTENSION_OUTDATED`` also needs a browser connected; with none, the account's sessions say why nothing runs.
      - `supported` boolean, required: Whether the browser driving the account runs a build that reads the list.
      - `watched_since` string, date-time, nullable, required: Since when every acceptance on this account would have been seen; null when no reading has worked yet.
    - `connection_token` string, nullable: What a person pastes into the extension to connect a browser. Several browsers may use it; Regenerate and Disconnect replace it.
    - `created_at` string, date-time, required
    - `daily_limit_check_connections` integer, required: Readings of the sender's newest connections a day: how accepted connection requests are noticed. Zero stops them.
    - `daily_limit_check_inbox` integer, required
    - `daily_limit_check_sent_invitations` integer, required
    - `daily_limit_connection_request` integer, required
    - `daily_limit_follow` integer, required
    - `daily_limit_like_post` integer, required
    - `daily_limit_profile_view` integer, required
    - `daily_limit_read_conversation` integer, required
    - `daily_limit_send_message` integer, required: Messages and InMails a day, counted together.
    - `daily_limit_withdraw` integer, required
    - `display_name` string, required
    - `effective_run_mode` 'manual' | 'auto', required: Whether a person approves a sender's LinkedIn steps before they run, or they run on their own. The sender's own LinkedIn setting, kept on the sender beside their email modes so the approval queue reads one home for both. The absence of one (``SenderProfileDTO.linkedin_approval_mode`` is None) reads as MANUAL: nothing runs on somebody's LinkedIn unattended until they have said so. The approval queue still tells "never set" apart from "chose manual", which is the level its settings surfaces name.
    - `headline` string, required
    - `id` string, uuid, required
    - `last_seen_at` string, date-time, nullable, required
    - `limit_maximums` LinkedInLimitMaximumsReadSchema, required: The most each of an account's limits may be set to. Keyed by the settings update's own field names, so a form reads the maximum for the field it is editing without a map of its own, and the numbers are the ones the update validates against.
      - `daily_limit_check_connections` integer, required
      - `daily_limit_check_inbox` integer, required
      - `daily_limit_check_sent_invitations` integer, required
      - `daily_limit_connection_request` integer, required
      - `daily_limit_follow` integer, required
      - `daily_limit_like_post` integer, required
      - `daily_limit_profile_view` integer, required
      - `daily_limit_read_conversation` integer, required
      - `daily_limit_send_message` integer, required
      - `daily_limit_withdraw` integer, required
      - `weekly_connection_request_cap` integer, required
      - `weekly_limit_check_connections` integer, required
      - `weekly_limit_check_inbox` integer, required
      - `weekly_limit_check_sent_invitations` integer, required
      - `weekly_limit_follow` integer, required
      - `weekly_limit_like_post` integer, required
      - `weekly_limit_profile_view` integer, required
      - `weekly_limit_read_conversation` integer, required
      - `weekly_limit_send_message` integer, required
      - `weekly_limit_withdraw` integer, required
    - `member_urn` string, nullable, required
    - `min_action_interval_seconds` integer, required: The least time between two steps on this LinkedIn account, in seconds, before a random widening of up to 40% is added. It holds across every sequence the account sends for.
    - `online` boolean, required
    - `photo_url` string, nullable, required
    - `presence` 'active' | 'idle' | 'not_seen', required: How recently ANY browser connected to this sender checked in. Three states, not two, because two different questions are asked of a connection. ``ACTIVE`` answers "can a step run right now": a browser is open and heartbeating. ``IDLE`` answers "is this still set up": the laptop was closed for the evening. ``NOT_SEEN`` is the one that needs a person: nothing has checked in for a day, and queued work is silently waiting.
    - `queued_count` integer
    - `replies_check` LinkedInRepliesCheckReadSchema: Whether the sender's LinkedIn inbox is being read, for the messages that wait on it. A message goes out only on an inbox read in full within the last few hours, so it never reaches somebody who has already replied. The sender's tab shows only the failing state.
      - `failing` boolean, required: Whether a message is waiting on a reading of the inbox while the checks keep failing since last_read_at.
      - `holding` boolean: Whether LinkedIn messages wait for a reading of the inbox right now; false once the checks have failed for long enough that they go without one.
      - `last_read_at` string, date-time, nullable, required: When the whole inbox was last read; null when no reading has worked yet.
    - `run_mode` 'manual' | 'auto', required: Whether a person approves a sender's LinkedIn steps before they run, or they run on their own. The sender's own LinkedIn setting, kept on the sender beside their email modes so the approval queue reads one home for both. The absence of one (``SenderProfileDTO.linkedin_approval_mode`` is None) reads as MANUAL: nothing runs on somebody's LinkedIn unattended until they have said so. The approval queue still tells "never set" apart from "chose manual", which is the level its settings surfaces name.
    - `sender_profile_id` string, uuid, required
    - `sessions` LinkedInAgentSessionReadSchema[]: Every browser currently connected, most recent first.
      - `browser_label` string, required
      - `connected_at` string, date-time, required
      - `extension_version` string, required
      - `id` string, uuid, required
      - `last_seen_at` string, date-time, nullable, required
      - `presence` 'active' | 'idle' | 'not_seen', required: How recently ANY browser connected to this sender checked in. Three states, not two, because two different questions are asked of a connection. ``ACTIVE`` answers "can a step run right now": a browser is open and heartbeating. ``IDLE`` answers "is this still set up": the laptop was closed for the evening. ``NOT_SEEN`` is the one that needs a person: nothing has checked in for a day, and queued work is silently waiting.
    - `status` 'pending' | 'active' | 'revoked', required: Pairing lifecycle. ``PENDING`` exists between "the user asked to connect" and "an extension actually bound a LinkedIn member to it", so the sender page can show a half-finished connection rather than nothing at all.
    - `updated_at` string, date-time, required
    - `usage` LinkedInKindUsageReadSchema[]
      - `daily_limit` integer, required
      - `kind` 'profile_view' | 'connection_request' | 'send_message' | 'inmail' | 'withdraw_connection_request' | 'follow_contact' | 'like_latest_post' | 'check_sent_invitations' | 'check_connections' | 'check_inbox' | 'read_conversation', required: What the browser agent is being asked to do. The four ``CHECK_*``/``READ_*`` kinds are housekeeping: they read our own outbound invitations, our own newest connections and our own conversations to detect what the contact did, so they are free and deliberately excluded from the priced kinds below. ``CHECK_CONNECTIONS`` reads the first batch of the sender's connections list, newest first: a person found there has accepted, whenever the invitation went out. It is how an acceptance is noticed at all once an invitation has fallen out of the ten rows the sent list shows a background tab. ``CHECK_INBOX`` scans the conversation list for threads with new inbound activity; ``READ_CONVERSATION`` opens one of them and reads it in full. The split keeps LinkedIn activity proportional to real replies: the cheap scan runs on every sweep, the expensive read only where the scan saw a change. ``LIKE_LATEST_POST`` targets the contact's most recent post at the moment the browser runs it. A contact with no posts is not a failure: the driver reports the action ``SKIPPED``, and the sequence advances either way. Every profile-targeted outcome carries the facts the browser read off the profile, including the three-state Premium "Open Profile" reading; see the section comment above the outcome models.
      - `remaining_today` integer, required: What may still run today: the daily limit's headroom, held to the weekly limit's when that is nearer.
      - `used_this_week` integer: Spent over today and the six days before it.
      - `used_today` integer, required
      - `weekly_limit` integer, nullable: The ceiling over any seven days; null when there is none.
    - `usage_resets_at` string, date-time, nullable: When today's counts in usage start over: 00:00 in the sender's timezone. Older servers leave it out, and a client then reads the next UTC midnight.
    - `vanity_name` string, nullable, required
    - `wait` LinkedInWaitReadSchema: What the account's next step is waiting on, and until when.
      - `next_at` string, date-time, nullable, required: When the next step may start: the end of the time between steps for pacing, the reset for daily_cap and weekly_cap, when the hours open for outside_window, and null otherwise.
      - `reason` 'not_connected' | 'checkpoint' | 'lease_held_elsewhere' | 'in_flight' | 'outside_window' | 'idle' | 'daily_cap' | 'weekly_cap' | 'kind_disabled' | 'checking_replies' | 'pacing' | 'ready' | 'insufficient_credits', required: Why an account's next step has not started, as one reason, highest first. ``OUTSIDE_WINDOW`` is work that could run but for its run window, shut now in the sender's timezone (2026-10-01); ``IDLE`` is nothing waiting in line. ``DAILY_CAP``, ``WEEKLY_CAP`` and ``KIND_DISABLED`` are named only when every kind that could be handed out is held by one. ``CHECKING_REPLIES`` is a message waiting for the inbox to be read first (2026-10-05): one is never sent on an inbox last read hours ago, or past a reply nobody has read yet. ``PACING`` is the time between steps, ``READY`` a step that may start now. ``INSUFFICIENT_CREDITS`` is a workspace with no credit left: the governor's own reading never names it (it reserves nothing), and the dashboard's account read puts it over the reasons a balance outranks (2026-10-06), as the side panel does off a refused claim.
      - `resets_at` string, date-time, nullable, required: The moment a daily or weekly limit next frees a slot, midnight in the sender's timezone; null for every other reason. A moment, never 'today' or 'tomorrow'.
    - `weekly_connection_request_cap` integer, required
    - `weekly_limit_check_connections` integer, nullable
    - `weekly_limit_check_inbox` integer, nullable
    - `weekly_limit_check_sent_invitations` integer, nullable
    - `weekly_limit_follow` integer, nullable
    - `weekly_limit_like_post` integer, nullable
    - `weekly_limit_profile_view` integer, nullable
    - `weekly_limit_read_conversation` integer, nullable
    - `weekly_limit_send_message` integer, nullable
    - `weekly_limit_withdraw` integer, nullable
  - `connected` boolean, required
  - `connection_token` string, required: Paste this into the Oneprofile extension to connect a browser as this sender.

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Sender not found.
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/4a6bd71e3f02?raw)
