openapi: 3.2.0 info: title: Gtm Linkedin Messages API version: '1.0' contact: name: GTM API url: https://gtm-api.com email: support@gtm-api.com license: name: Proprietary url: https://gtm-api.com/license description: 'Operations tagged linkedin_messages across 2 of this provider''s published API definitions: gtm-api-openapi-openapi.yml, gtm-api-linkedin-openapi.yaml. Each path carries the servers of the definition it was published in.' servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway security: - BearerJwt: [] TeamSid: [] tags: - name: linkedin_messages description: Registry package `mcp.linkedin/linkedin_messages`, served on MCP mount `linkedin.messaging`. paths: /api/linkedin-messages/check-sent: post: operationId: check_linkedin_message_sent summary: Check whether a LinkedIn message went out description: 'Ask what a LinkedIn message send came to, without sending: by the client_reference it went out under (optionally at one place: linkedin_conversation_sid, ln_member_id or profile_urn), or by the activity_log_sid a 409 named. result.outcome: sent (item is the message, or null with reason message_row_pending or caller_confirmed), in_flight, unknown (the thread has not shown it yet; retry_after, send_decisive_at), or not_sent (no_send_under_key, refused, not_in_thread, caller_confirmed). Send the same request again only on not_sent, under the same key. result.activity_log_sid is the attempt a person''s word names (confirmed_not_sent / confirmed_sent on the send tools). A send in doubt has its thread read now when a look is due, so a call can be slow. A key sent to several places is 422 place_required, a place in another form than the sends recorded 422 place_unmatched (context.places). Invitations: check_linkedin_connection_request_sent; comments, posts, reposts: check_linkedin_posting_sent. Contract: - MCP tool `check_linkedin_message_sent`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: none.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckLinkedinMessageSentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/CheckLinkedinMessageSentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: check_linkedin_message_sent x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/download-attachment: post: operationId: download_linkedin_message_attachment summary: Download message attachment description: 'Download one inbound attachment of a basic-messenger message, returned inline as a base64 data_url (nothing is persisted, no row changes). This verb is addressed by RAW LinkedIn ids, not by our message sid, so assemble it from a message row you already hold (search_linkedin_messages): linkedin_account_sid = that row''s linkedin_account_sid; message_id = that row''s message_hash (must be the 2-… form); attachment_urn = attachments[i].urn on the same row. profile_id is the ACTING account''s own LinkedIn URN: read ln_id off that linkedin_account_sid via search_linkedin_accounts, NOT the other party''s URN. 120 s budget, up to ~50 MB; spends the messaging_general bucket. Contract: - MCP tool `download_linkedin_message_attachment`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: read only; paced: a call spends the `messaging_general` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DownloadLinkedinMessageAttachmentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DownloadLinkedinMessageAttachmentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: download_linkedin_message_attachment x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: messaging_general servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/download-sales-nav-attachment: post: operationId: download_linkedin_sales_nav_message_attachment summary: Download Sales Navigator attachment description: 'Sales Navigator variant of download_linkedin_message_attachment: one inbound attachment of an SN message, inline as a base64 data_url. Same raw-id addressing, one field fewer (the SN wire verb takes no profile_id): linkedin_account_sid must be an account with Sales Navigator, message_id is the message row''s message_hash, attachment_urn is attachments[i].urn on that row. The row must be messenger_type=''sales_navigator'' (an account without SN is refused before dispatch). Same 120 s budget and messaging_general bucket. Contract: - MCP tool `download_linkedin_sales_nav_message_attachment`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: read only; paced: a call spends the `messaging_general` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DownloadLinkedinSalesNavMessageAttachmentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DownloadLinkedinSalesNavMessageAttachmentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: download_linkedin_sales_nav_message_attachment x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: messaging_general servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/get-my-latest: post: operationId: get_my_latest_linkedin_messages summary: Get my latest LinkedIn messages description: 'Always-fresh head read of ONE basic-messenger thread (§5.8 refresh of that conversation from LinkedIn, then the last N messages, sent_at DESC). Never stale: it 429s with bucket_saturated / sync_in_progress. Use before drafting a reply; use search_linkedin_messages for stored history. Runs through the account''s browser: a stopped or idle one is cold-started first (about 50 s, or 503 browser_starting), which also releases that account''s overdue syncs. Contract: - MCP tool `get_my_latest_linkedin_messages`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `search`. - Flags: paced: a call spends the `self_account_sync` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_my_latest_linkedin_messages x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: self_account_sync servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/get-my-latest-recruiter: post: operationId: get_my_latest_linkedin_messages_recruiter summary: Get my latest Recruiter messages description: 'LinkedIn Recruiter variant of get_my_latest_linkedin_messages: always-fresh head read of ONE recruiter thread''s messages (§5.8 refresh-then-return over the talent wire, dispatched with the account''s seat). Requires a messenger_type=''recruiter'' conversation (a 422 messenger_type_mismatch names the right tool otherwise) and a Recruiter seat with its stamped seat number; same hard-429 guards. Rows: linkedin_type=''inmail'', type outbox for the seat''s own messages and inbox for the candidate''s. Runs through the account''s browser: a stopped or idle one is cold-started first (about 50 s, or 503 browser_starting), which also releases that account''s overdue syncs. Contract: - MCP tool `get_my_latest_linkedin_messages_recruiter`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.recruiter`. - Operation `action`, response envelope `search`. - Flags: paced: a call spends the `self_account_sync` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesRecruiterRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesRecruiterResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_my_latest_linkedin_messages_recruiter x-gtm-mcp-mount: linkedin.recruiter x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: self_account_sync servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/get-my-latest-sales-nav: post: operationId: get_my_latest_linkedin_messages_sales_nav summary: Get my latest Sales Navigator messages description: 'Sales Navigator variant of get_my_latest_linkedin_messages: always-fresh head read of ONE SN thread''s messages (§5.8 refresh-then-return). Requires a messenger_type=''sales_navigator'' conversation; same hard-429 guards. Runs through the account''s browser: a stopped or idle one is cold-started first (about 50 s, or 503 browser_starting), which also releases that account''s overdue syncs. Contract: - MCP tool `get_my_latest_linkedin_messages_sales_nav`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `search`. - Flags: paced: a call spends the `self_account_sync` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesSalesNavRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetMyLatestLinkedinMessagesSalesNavResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_my_latest_linkedin_messages_sales_nav x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: self_account_sync servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/metrics: post: operationId: get_linkedin_messages_metrics summary: Get LinkedIn messages metrics description: 'Period-bound message aggregates for one account (reply_rate_pct, avg_time_to_reply_seconds, avg_thread_depth) with an optional group_by axis. Requires period {from,to} (≤ 90 days) and filter.linkedin_account_sid - that is the ONLY filter axis the aggregation applies, unlike search. Returns the counts block alongside. Contract: - MCP tool `get_linkedin_messages_metrics`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `metrics`, response envelope `metrics`. - Flags: read only.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GetLinkedinMessagesMetricsRequest' responses: '200': description: '`metrics` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetLinkedinMessagesMetricsResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_linkedin_messages_metrics x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: metrics x-gtm-envelope: metrics x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/search: post: operationId: search_linkedin_messages summary: Search LinkedIn messages description: 'List LinkedIn messages (basic DM + Sales Navigator + InMail) with operator-object filters (account, conversation, channel, direction, contact ids, date ranges) and filter.q, a LIKE (substring) over body + subject (message text, not contact names). Supports include[], sort, cursor pagination. page_size:0 for count-only. To read a single message, filter by {sid:{eq:"ln_ms_…"}}. Contract: - MCP tool `search_linkedin_messages`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `search`, response envelope `search`. - Flags: read only.' tags: - linkedin_messages requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/SearchLinkedinMessagesRequest' responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SearchLinkedinMessagesResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: search_linkedin_messages x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: search x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/send: post: operationId: send_linkedin_message summary: Send LinkedIn message description: 'Send one outbound regular LinkedIn DM on the basic messenger (outward action). Reply to an existing thread via linkedin_conversation_sid, or open a new thread to a 1st-degree connection via ln_id / sn_id or by public_identifier (slug or linkedin.com/in/ URL). Guards run first: send_messages daily cap, 8000-char body cap, block guard (a member who blocked this account is refused 422 target_blocked, no browser call), connection guard, attachment https:// reachability, basic-messenger surface guard. Fire-on-success: a row only on terminal success. Sends once per client_reference and place (the thread, else the person): a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. When NOT: InMail to a non-connection → send_linkedin_inmail; voice note → send_linkedin_voice_message; Sales Navigator thread → send_linkedin_sales_nav_message; the connection note lives on linkedin-connection-requests. Bulk: loop client-side within the daily cap. Contract: - MCP tool `send_linkedin_message`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; step eligible: gtm.service.orchestration can run this verb as a mass-action plan step, once per item; paced: a call spends the `send_messages` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLinkedinMessageRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SendLinkedinMessageResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: send_linkedin_message x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: true x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_messages servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/send-inmail: post: operationId: send_linkedin_inmail summary: Send LinkedIn InMail description: 'Send one premium InMail to a person (outward action). Person-addressed only via ln_id / sn_id, subject required (≤ 200), body ≤ 1900. Sends once per client_reference and person: a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. Guards: send_inmails daily cap, Premium guard, InMail-credits guard (422 no_inmail_credits when the account''s pool is known empty: the seat''s grant inmail_credits with a Sales Navigator seat, premium_inmail_credits without; a balance never read does not block). Fire-on-success; the plugin''s inmail_credits_remaining is written back onto that pool, and LinkedIn''s own NOT_ENOUGH_INMAIL_CREDIT answers 422 no_inmail_credits and zeroes it (it is not a block of the target). When NOT: 1st-degree connection → send_linkedin_message (free); no Premium / zero credits → the guards 422; SN thread continuation → send_linkedin_sales_nav_message. Contract: - MCP tool `send_linkedin_inmail`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `send_inmails` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLinkedinInmailRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SendLinkedinInmailResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: send_linkedin_inmail x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_inmails servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/send-recruiter: post: operationId: send_linkedin_recruiter_message summary: Send Recruiter InMail description: 'Send one LinkedIn Recruiter InMail (outward action): open a NEW recruiter thread via recruiter_id (AEMAA… id; ln_id / sn_id work too), or reply INTO an existing thread via linkedin_conversation_sid (messenger_type=''recruiter''). Guards, in order: Recruiter seat (422 recruiter_required); live Recruiter session (409 recruiter_reauth_required: only the seat holder renews Recruiter''s 30-day session, by signing in again in the account''s browser; tell the user, do not retry); stamped seat on a reply (422 recruiter_seat_unresolvable); LinkedIn''s one InMail per candidate per 24 h (429 recruiter_inmail_cooldown, cooldown_ends_at: refresh the thread with get_my_latest_linkedin_messages_recruiter if a reply may have landed, else wait). Spends send_inmails and an InMail credit. Sends once per client_reference and place: a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. When NOT: basic threads → send_linkedin_message; SN → send_linkedin_sales_nav_message. Contract: - MCP tool `send_linkedin_recruiter_message`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.recruiter`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `send_inmails` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLinkedinRecruiterMessageRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SendLinkedinRecruiterMessageResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: send_linkedin_recruiter_message x-gtm-mcp-mount: linkedin.recruiter x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_inmails servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/send-sales-nav: post: operationId: send_linkedin_sales_nav_message summary: Send Sales Navigator message description: 'Send one Sales Navigator message (outward action): continue an SN thread via linkedin_conversation_sid (messenger_type=sales_navigator), or open a new one via ln_id / sn_id. Guards: send_inmails daily cap, SN seat and surface, and on a NEW thread outside the network the InMail-credits guard (422 no_inmail_credits when the seat''s inmail_credits are known to be 0). Fire-on-success. Sends once per client_reference and place: a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. LinkedIn''s 403 SALES_SEAT_REQUIRED is a stale SN session, not a lost seat: the send re-arms it once and retries; a second refusal is 409 sales_session_stale (run check_linkedin_account_premium_subscription with checks ["sales_nav"], retry), a seat the probe finds gone 422 sales_nav_required. When NOT: basic threads → send_linkedin_message / send_linkedin_voice_message; cold InMail outside SN → send_linkedin_inmail; no SN seat is 422, so check linkedin-accounts.has_sn first. Contract: - MCP tool `send_linkedin_sales_nav_message`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `send_inmails` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLinkedinSalesNavMessageRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SendLinkedinSalesNavMessageResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: send_linkedin_sales_nav_message x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_inmails servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/send-voice: post: operationId: send_linkedin_voice_message summary: Send LinkedIn voice message description: 'Send one voice note on the basic LinkedIn messenger (outward action). audio arrives as a https:// url or base64 (any common format) and is normalized server-side to AAC/m4a, hard-capped at 60 s. Same guard chain as send_linkedin_message plus audio validation. Fire-on-success: a row is inserted only on terminal success; no text body. Sends once per client_reference and place (the thread, else the person): a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. A keyed repeat is answered before its audio is read. When NOT: text DM → send_linkedin_message; SN threads → send_linkedin_sales_nav_message; audio longer than 60 s is rejected, so trim client-side first. Contract: - MCP tool `send_linkedin_voice_message`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `send_messages` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendLinkedinVoiceMessageRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/SendLinkedinVoiceMessageResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: send_linkedin_voice_message x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_messages servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/start-group: post: operationId: start_linkedin_group_conversation summary: Start group conversation description: 'Start a new multi-attendee (group) chat on the basic messenger and send an opening message (outward action). Provide the executor account, 2..20 attendee URNs and the opening body (1..8000 chars, optional attachments, optional conversation_title to name the group); mints the group thread and dispatches the first message. Spends the send_messages bucket. Sends once per client_reference and attendee set: a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. A group has no place check_linkedin_message_sent takes: ask it by the key alone or by activity_log_sid. Contract: - MCP tool `start_linkedin_group_conversation`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `send_messages` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StartLinkedinGroupConversationRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/StartLinkedinGroupConversationResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: start_linkedin_group_conversation x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: complex x-gtm-paced-bucket: send_messages servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/{sid}/delete-on-linkedin: post: operationId: delete_linkedin_message_on_linkedin summary: Recall message on LinkedIn description: 'Recall one of OUR OWN sent messages: it disappears for EVERY participant, not just for us. Addressed by the message sid, like react_linkedin_message. Irreversible - a wrong sid destroys a real conversation, so confirm the message first. LinkedIn allows a recall only WITHIN AN HOUR of sending; past that it refuses, so an older message comes back as 409 message_too_old_to_recall with nothing dispatched and no limit spent. The stored row is NOT removed: it stays in the thread marked is_deleted with an emptied body, which is what LinkedIn serves afterwards, so the operator still sees that something was withdrawn. Basic messenger only; an SN message, a non-2-… message_hash, or a row already marked is_deleted is refused before dispatch. Recallability is otherwise not pre-validated, so ''not yours'' arrives as a wire error. Spends messaging_general, the reaction verbs'' bucket. Contract: - MCP tool `delete_linkedin_message_on_linkedin`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `messaging_general` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages parameters: - name: sid in: path required: true description: LinkedIn message sid (ln_ms_…). schema: type: string minLength: 18 maxLength: 18 pattern: ^ln_ms_ description: LinkedIn message sid (ln_ms_…). responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinMessageOnLinkedinResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: delete_linkedin_message_on_linkedin x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: messaging_general servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-messages/{sid}/react: post: operationId: react_linkedin_message summary: React to message description: 'Add or remove an emoji reaction on one stored message on LinkedIn (outward action). Pass the message sid + a reaction_type; the reaction is dispatched to LinkedIn and mirrored onto the stored row. Set remove:true to take YOUR reaction back (pass the same reaction_type you reacted with). Basic messenger only: an SN message or a non-2-… message_hash is refused before dispatch. Spends the messaging_general bucket. Contract: - MCP tool `react_linkedin_message`, registry package `mcp.linkedin/linkedin_messages`, mount `linkedin.messaging`. - Operation `action`, response envelope `action`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API; paced: a call spends the `messaging_general` smart-limit bucket of the account it runs on, and calls of one bucket are spaced per account. A short wait is slept by the server; a longer one answers 429 `rate_limited` with `context.retry_after`, and the same call succeeds from that moment. Parallel calls on one account queue behind each other.' tags: - linkedin_messages parameters: - name: sid in: path required: true description: LinkedIn message sid (ln_ms_…). schema: type: string minLength: 18 maxLength: 18 pattern: ^ln_ms_ description: LinkedIn message sid (ln_ms_…). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReactLinkedinMessageRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/ReactLinkedinMessageResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: react_linkedin_message x-gtm-mcp-mount: linkedin.messaging x-gtm-entity: linkedin_messages x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: messaging_general servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway components: schemas: ReactLinkedinMessageRequest: type: object description: Request body of `react_linkedin_message`. properties: reaction_type: type: string minLength: 1 maxLength: 32 description: Single emoji or LinkedIn reaction identifier. remove: type: - boolean - 'null' description: true = unreact (drives the unreact-on-message verb) with the SAME reaction_type. Default false = react. required: - reaction_type SendLinkedinVoiceMessageResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta SendLinkedinSalesNavMessageRequest: type: object description: Request body of `send_linkedin_sales_nav_message`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). linkedin_conversation_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: Existing SN thread (messenger_type='sales_navigator'); provide this OR a profile URN. ln_id: type: - string - 'null' maxLength: 128 description: Regular-profile URN for a new SN thread. sn_id: type: - string - 'null' maxLength: 64 description: Sales Navigator URN (preferred on the SN surface); interchangeable with ln_id. text: type: string minLength: 1 maxLength: 8000 description: 'Message body; 1..8000 chars. Sent verbatim: the platform renders no merge fields, a {{first_name}} goes out as those braces.' attachments: type: array items: type: object properties: file_base64: type: string minLength: 1 description: 'The file itself: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 / file_url.' file_url: type: string maxLength: 2048 format: uri description: 'An https URL of the file, downloaded by the backend and encoded for you (public hosts on port 443 only, no credentials in the URL; a request_media_upload file_url works once uploaded). Exactly one of file_base64 / file_url. Refused 422 on this member before anything is dispatched: attachment_url_invalid (not https, a port other than 443, credentials), attachment_url_host_forbidden (a private or reserved address), attachment_fetch_failed, attachments_too_large.' file_name: type: string minLength: 1 maxLength: 255 description: Display filename shown to the recipient. Derived from the URL path when omitted on the file_url arm. file_type: type: string minLength: 1 maxLength: 255 description: 'MIME type. Read off the data: prefix or the fetched Content-Type when omitted.' file_byte_size: type: integer minimum: 1 description: 'Advisory only: the backend measures the real size and sends that.' description: Exactly one of file_base64 / file_url per item. Decoded bytes across ALL attachments of one send may not exceed 35 MB, derived from the node's own 50 MB body limit and base64's 4/3 inflation; over it the send is refused with attachments_too_large before a browser dispatch is spent. description: Exactly one of file_base64 / file_url per item; 35 MB decoded total per send. client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the thread, else the person) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - text GetLinkedinMessagesMetricsResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - metrics metrics: type: object properties: filter: type: object additionalProperties: {} period: type: object properties: from: type: string to: type: string required: - from - to aggregated: type: object properties: counts: type: object additionalProperties: {} metrics: type: object properties: reply_rate_pct: type: - number - 'null' avg_time_to_reply_seconds: type: - number - 'null' avg_thread_depth: type: - number - 'null' required: - reply_rate_pct - avg_time_to_reply_seconds - avg_thread_depth metrics: type: object properties: reply_rate_pct: type: - number - 'null' avg_time_to_reply_seconds: type: - number - 'null' avg_thread_depth: type: - number - 'null' required: - reply_rate_pct - avg_time_to_reply_seconds - avg_thread_depth applied_filters: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - metrics - meta SendLinkedinVoiceMessageRequest: type: object description: Request body of `send_linkedin_voice_message`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). linkedin_conversation_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: Existing basic-messenger thread; provide this OR a profile URN. ln_id: type: - string - 'null' maxLength: 128 description: Regular-profile URN for a new thread. sn_id: type: - string - 'null' maxLength: 64 description: Sales Navigator URN; interchangeable with ln_id. audio: type: object properties: url: type: string description: 'An https URL of the audio file, downloaded by the backend (public hosts on port 443 only, no credentials in the URL, up to 32 MB before normalization). Refused 422 before anything is dispatched: audio_url_invalid (not https, a port other than 443, credentials), audio_url_host_forbidden (a private or reserved address), audio_fetch_failed, audio_too_large.' base64: type: string description: Inline payload (~15 MB cap pre-normalization). description: Exactly one of url / base64; normalized server-side to AAC/m4a ≤ 60 s. client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the thread, else the person) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - audio GetMyLatestLinkedinMessagesRecruiterResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object properties: total_count: type: number inbox_count: type: number outbox_count: type: number message_count: type: number inmail_count: type: number connection_note_count: type: number with_attachments_count: type: number groups: type: object additionalProperties: {} required: - total_count - inbox_count - outbox_count - message_count - inmail_count - connection_note_count - with_attachments_count - groups refresh: type: object properties: performed: type: boolean pages_fetched: type: number items_seen: type: number items_upserted: type: number stop_reason: type: - string - 'null' required: - performed - pages_fetched - items_seen - items_upserted - stop_reason pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - items - pagination - applied_filters - includes - meta - refresh DownloadLinkedinMessageAttachmentRequest: type: object description: Request body of `download_linkedin_message_attachment`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'Mailbox owner that received the message: the message row''s linkedin_account_sid.' profile_id: type: string maxLength: 128 description: The acting account's OWN profile URN (ln_id of linkedin_account_sid from search_linkedin_accounts), not the sender's. message_id: type: string maxLength: 255 description: 'Raw LinkedIn MessageId: the message row''s message_hash (2-… form; the conversation id is decoded from it).' attachment_urn: type: string maxLength: 512 description: 'Which attachment of that message: attachments[i].urn on the stored row (urn:li:digitalmediaAsset:…).' required: - linkedin_account_sid - profile_id - message_id - attachment_urn GetMyLatestLinkedinMessagesRecruiterRequest: type: object description: Request body of `get_my_latest_linkedin_messages_recruiter`. properties: linkedin_conversation_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: REQUIRED; must be a messenger_type='recruiter' thread. page_size: type: integer minimum: 1 maximum: 100 description: N returned, 1..100, default 50. cursor: type: - string - 'null' description: Opaque; pagination over the refreshed tail. required: - linkedin_conversation_sid SendLinkedinRecruiterMessageRequest: type: object description: Request body of `send_linkedin_recruiter_message`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). linkedin_conversation_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: Existing recruiter thread (messenger_type='recruiter'); provide this OR a recipient. A reply dispatches with the thread's own counterpart as the recipient. recruiter_id: type: - string - 'null' maxLength: 64 description: The recipient's Recruiter (talent) profile id (AEMAA…), from a recruiter thread's recruiter_id or participants[].recruiter_id. New-thread mode. ln_id: type: - string - 'null' maxLength: 128 description: A regular-profile URN (ACoAA…) for a new thread; the wire resolves it too. sn_id: type: - string - 'null' maxLength: 64 description: A Sales Navigator URN (ACwAA…) for a new thread; the wire resolves it too. subject: type: string minLength: 1 maxLength: 200 description: InMail subject; 1..200 chars, required on both wires. text: type: string minLength: 1 maxLength: 1900 description: 'InMail body; 1..1900 chars, \n line breaks. Sent verbatim: the platform renders no merge fields, a {{first_name}} goes out as those braces.' attributes: type: array items: type: object properties: start: type: integer minimum: 0 description: Offset into text in UTF-16 code units (JS String offsets). length: type: integer minimum: 1 description: Run length in UTF-16 code units; start + length must fit inside text. kind: type: object additionalProperties: {} description: 'The formatting, an object with exactly one key: {"bold":{}}, {"italic":{}}, {"listItem":{}}, {"list":{"ordered":false}}, {"hyperlink":{"url":"https://..."}}.' required: - start - length - kind maxItems: 200 description: 'Rich-text runs over text. NEW THREAD ONLY: a reply with attributes is refused 422 attributes_not_supported_in_thread.' client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the thread, else the person) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - subject - text GetMyLatestLinkedinMessagesSalesNavRequest: type: object description: Request body of `get_my_latest_linkedin_messages_sales_nav`. properties: linkedin_conversation_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: REQUIRED; must be a messenger_type='sales_navigator' thread. page_size: type: integer minimum: 1 maximum: 100 description: N returned, 1..100, default 50. cursor: type: - string - 'null' description: Opaque; pagination over the refreshed tail. required: - linkedin_conversation_sid CheckLinkedinMessageSentRequest: type: object description: Request body of `check_linkedin_message_sent`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: The account that sent (ln_ac_…). A key is looked up on this account only. client_reference: type: - string - 'null' minLength: 1 maxLength: 255 description: 'The key the send went out under, byte for byte. Exactly one of client_reference / activity_log_sid. Found at any age: a send in doubt never ages out of its key.' activity_log_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: The attempt a 409 or an earlier check named (ln_al_…); it takes no place. An attempt of another account is 404. linkedin_conversation_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: 'Place, next to client_reference: the thread the send named or landed in. One place at most; a thread of another account is 404.' ln_member_id: type: - string - 'null' maxLength: 64 description: 'Place, next to client_reference: the person''s member id (digits).' profile_urn: type: - string - 'null' maxLength: 128 description: 'Place, next to client_reference: the recipient id the send was given (ln_id ACoAA…, sn_id ACwAA…, or a Recruiter id).' required: - linkedin_account_sid SendLinkedinInmailRequest: type: object description: Request body of `send_linkedin_inmail`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). ln_id: type: - string - 'null' maxLength: 128 description: Regular-profile URN (ACoAA…); one URN required. sn_id: type: - string - 'null' maxLength: 64 description: Sales Navigator URN; interchangeable with ln_id. subject: type: string minLength: 1 maxLength: 200 description: REQUIRED InMail subject; 1..200 chars. text: type: string minLength: 1 maxLength: 1900 description: 'InMail body; 1..1900 chars. Sent verbatim: the platform renders no merge fields, a {{first_name}} goes out as those braces.' attachments: type: array items: type: object properties: file_base64: type: string minLength: 1 description: 'The file itself: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 / file_url.' file_url: type: string maxLength: 2048 format: uri description: 'An https URL of the file, downloaded by the backend and encoded for you (public hosts on port 443 only, no credentials in the URL; a request_media_upload file_url works once uploaded). Exactly one of file_base64 / file_url. Refused 422 on this member before anything is dispatched: attachment_url_invalid (not https, a port other than 443, credentials), attachment_url_host_forbidden (a private or reserved address), attachment_fetch_failed, attachments_too_large.' file_name: type: string minLength: 1 maxLength: 255 description: Display filename shown to the recipient. Derived from the URL path when omitted on the file_url arm. file_type: type: string minLength: 1 maxLength: 255 description: 'MIME type. Read off the data: prefix or the fetched Content-Type when omitted.' file_byte_size: type: integer minimum: 1 description: 'Advisory only: the backend measures the real size and sends that.' description: Exactly one of file_base64 / file_url per item. Decoded bytes across ALL attachments of one send may not exceed 35 MB, derived from the node's own 50 MB body limit and base64's 4/3 inflation; over it the send is refused with attachments_too_large before a browser dispatch is spent. description: Exactly one of file_base64 / file_url per item; 35 MB decoded total per send. An item whose file_type is video/* is delivered as a playable video in the thread; any other type arrives as a generic file attachment. stop_if_replied_after: type: - string - 'null' format: date-time description: 'ISO 8601 UTC moment. When given, the thread is read from LinkedIn before the send and the send is refused with 409 replied if the person wrote after this moment (context.linkedin_message_sid names their message: read it before you send again); 503 reply_check_unavailable when that read fails, nothing sent, retry after retry_after. Omit or null to send regardless.' client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the thread, else the person) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - subject - text SearchLinkedinMessagesRequest: type: object description: Request body of `search_linkedin_messages`. properties: filter: type: object properties: sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false linkedin_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false linkedin_conversation_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false messenger_type: type: object properties: eq: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' in: type: array items: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' additionalProperties: false linkedin_type: type: object properties: eq: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' ne: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' in: type: array items: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' nin: type: array items: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' additionalProperties: false type: type: object properties: eq: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' in: type: array items: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' additionalProperties: false automation: type: object properties: eq: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ne: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' in: type: array items: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' nin: type: array items: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' additionalProperties: false ln_id: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string is_null: type: boolean additionalProperties: false ln_member_id: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string additionalProperties: false sn_id: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string is_null: type: boolean additionalProperties: false recruiter_id: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string is_null: type: boolean additionalProperties: false recruiter_contract_id: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string is_null: type: boolean additionalProperties: false description: The Recruiter contract the thread was synced or sent under (a seat holder with several contracts switches with select_recruiter_contract; each contract is its own inbox). Null off the recruiter surface and on rows synced before 2026-09-19. nickname: type: object properties: eq: type: string in: type: array items: type: string is_null: type: boolean additionalProperties: false message_hash: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false client_reference: type: object properties: eq: type: string ne: type: string in: type: array items: type: string nin: type: array items: type: string is_null: type: boolean additionalProperties: false description: 'The caller''s own key given at send time. The way to ask whether a send landed before repeating it: search by the key you sent.' subject: type: object properties: eq: type: string in: type: array items: type: string is_null: type: boolean additionalProperties: false description: The InMail subject, exact match; is_null:false = every message that carried one. For a text search use q. q: type: string maxLength: 128 description: 'A LIKE (substring, case-insensitive) over message text + InMail subject. Message text only: it does not search contact names.' sent_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false created_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false updated_at: type: object properties: gte: type: string lte: type: string gt: type: string lt: type: string additionalProperties: false deleted_at: type: object properties: gte: type: string lte: type: string is_null: type: boolean additionalProperties: false include: type: array items: type: string enum: - linkedin_conversation - linkedin_account description: Relations to eager-load (see entity Includes). sort: type: object properties: field: type: string enum: - sent_at - created_at - updated_at direction: type: string enum: - asc - desc description: Default desc. required: - field page_size: type: integer minimum: 0 maximum: 200 description: 0..200, default 50. page_size=0 = count-only, page_size=1 = getFirst. cursor: type: - string - 'null' description: Opaque forward cursor from a previous response pagination.next_cursor. SendLinkedinMessageRequest: type: object description: Request body of `send_linkedin_message`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). linkedin_conversation_sid: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: 'Existing basic-messenger thread; provide this OR a profile URN. Our sid only: a raw LinkedIn 2-…== thread id is NOT accepted here, resolve it first with search_linkedin_conversations filter.conversation_hash.eq.' ln_id: type: - string - 'null' maxLength: 128 description: Regular-profile URN (ACoAA…) for a new thread. sn_id: type: - string - 'null' maxLength: 64 description: Sales Navigator URN (ACwAA…); interchangeable with ln_id. public_identifier: type: - string - 'null' maxLength: 2048 description: 'For a new thread when all you have is the person''s vanity slug or linkedin.com/in/ URL: resolved server-side to the URN (own rows, then the corpus, then a lite-profile read on the sender that spends enrichment). One addressing form per call: linkedin_conversation_sid, ln_id / sn_id, or public_identifier.' text: type: string minLength: 1 maxLength: 8000 description: 'Message body; 1..8000 chars. Sent verbatim: the platform renders no merge fields, a {{first_name}} goes out as those braces.' attachments: type: array items: type: object properties: file_base64: type: string minLength: 1 description: 'The file itself: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 / file_url.' file_url: type: string maxLength: 2048 format: uri description: 'An https URL of the file, downloaded by the backend and encoded for you (public hosts on port 443 only, no credentials in the URL; a request_media_upload file_url works once uploaded). Exactly one of file_base64 / file_url. Refused 422 on this member before anything is dispatched: attachment_url_invalid (not https, a port other than 443, credentials), attachment_url_host_forbidden (a private or reserved address), attachment_fetch_failed, attachments_too_large.' file_name: type: string minLength: 1 maxLength: 255 description: Display filename shown to the recipient. Derived from the URL path when omitted on the file_url arm. file_type: type: string minLength: 1 maxLength: 255 description: 'MIME type. Read off the data: prefix or the fetched Content-Type when omitted.' file_byte_size: type: integer minimum: 1 description: 'Advisory only: the backend measures the real size and sends that.' description: Exactly one of file_base64 / file_url per item. Decoded bytes across ALL attachments of one send may not exceed 35 MB, derived from the node's own 50 MB body limit and base64's 4/3 inflation; over it the send is refused with attachments_too_large before a browser dispatch is spent. description: Exactly one of file_base64 / file_url per item; 35 MB decoded total per send. An item whose file_type is video/* is delivered as a playable video in the thread; any other type arrives as a generic file attachment. stop_if_replied_after: type: - string - 'null' format: date-time description: 'ISO 8601 UTC moment. When given, the thread is read from LinkedIn before the send and the send is refused with 409 replied if the person wrote after this moment (context.linkedin_message_sid names their message: read it before you send again); 503 reply_check_unavailable when that read fails, nothing sent, retry after retry_after. Omit or null to send regardless.' client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the thread, else the person) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - text StartLinkedinGroupConversationRequest: type: object description: Request body of `start_linkedin_group_conversation`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: LinkedIn account sid (ln_ac_…). attendees: type: array items: type: object properties: ln_id: type: - string - 'null' maxLength: 128 description: Regular-profile URN. sn_id: type: - string - 'null' maxLength: 64 description: Sales Navigator URN; interchangeable with ln_id. minItems: 2 maxItems: 20 description: 2..20 other participants; each needs a URN. text: type: string minLength: 1 maxLength: 8000 description: 'Opening message; 1..8000 chars. Sent verbatim: the platform renders no merge fields, a {{first_name}} goes out as those braces.' conversation_title: type: - string - 'null' maxLength: 100 description: Optional group name, max 100 chars; omitted leaves the thread unnamed. attachments: type: array items: type: object properties: file_base64: type: string minLength: 1 description: 'The file itself: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 / file_url.' file_url: type: string maxLength: 2048 format: uri description: 'An https URL of the file, downloaded by the backend and encoded for you (public hosts on port 443 only, no credentials in the URL; a request_media_upload file_url works once uploaded). Exactly one of file_base64 / file_url. Refused 422 on this member before anything is dispatched: attachment_url_invalid (not https, a port other than 443, credentials), attachment_url_host_forbidden (a private or reserved address), attachment_fetch_failed, attachments_too_large.' file_name: type: string minLength: 1 maxLength: 255 description: Display filename shown to the recipient. Derived from the URL path when omitted on the file_url arm. file_type: type: string minLength: 1 maxLength: 255 description: 'MIME type. Read off the data: prefix or the fetched Content-Type when omitted.' file_byte_size: type: integer minimum: 1 description: 'Advisory only: the backend measures the real size and sends that.' description: Exactly one of file_base64 / file_url per item. Decoded bytes across ALL attachments of one send may not exceed 35 MB, derived from the node's own 50 MB body limit and base64's 4/3 inflation; over it the send is refused with attachments_too_large before a browser dispatch is spent. description: Exactly one of file_base64 / file_url per item; 35 MB decoded total per send. client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE message (max 255, byte for byte): one key per message, the same key on every repeat of it. The key and its place (the attendee set) are one message whatever it says, and a repeat never goes out twice: it answers 200 with the row the first send stored (result.idempotent_replay, result.content_differs when this request says something else) or 409 naming error.context.send_outcome (in_flight, unknown with retry_after and send_decisive_at, or sent; not_sent with blocking_activity_log_sid when another message holds the place). The same key at another place is another message. Without a key the same words to the same place count as a repeat for an hour after they went out. Stored on the row and searchable; check_linkedin_message_sent asks by it.' confirmed_not_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_message_sent, given only after someone looked at the conversation. Taken once the attempt can no longer land (before that: 409 send_outcome_unknown, waiting_for may_still_land, retry_after and send_decisive_at that moment): it settles that attempt not_sent and this request goes out. Moot when the attempt is no longer in doubt; another message''s sid is 422 not_this_message.' confirmed_sent: type: - string - 'null' minLength: 18 maxLength: 18 pattern: ^ln_al_ description: 'A person''s word that an earlier attempt of THIS message IS on LinkedIn: its activity_log_sid, as for confirmed_not_sent (never both). Taken at once; it settles the attempt sent and sends nothing: the answer is 409 concurrent_send_in_flight with send_outcome sent, or 200 with the row once it is stored. Another message''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - attendees - text McpError: type: object properties: success: type: boolean enum: - false error: type: object properties: code: type: string enum: - 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 - internal_error - service_unavailable - not_implemented message: type: string recoverable: type: boolean suggestion: type: string field_errors: type: object additionalProperties: type: array items: type: object properties: rule: type: string message: type: string required: - rule - message blockers: type: array items: type: object properties: type: type: string description: Machine-readable blocker type (active_flow, pending_tasks, …). severity: type: string enum: - hard - soft description: hard = external action required; soft = acknowledge is enough. description: type: string entity_sid: type: - string - 'null' count: type: integer resolution: type: string description: 'Hard: tool name to call. Soft: code for acknowledge[].' resolution_hint: type: string required: - type - severity - description - entity_sid - resolution - resolution_hint context: type: object additionalProperties: {} required: - code - message - recoverable meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - error GetMyLatestLinkedinMessagesSalesNavResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object properties: total_count: type: number inbox_count: type: number outbox_count: type: number message_count: type: number inmail_count: type: number connection_note_count: type: number with_attachments_count: type: number groups: type: object additionalProperties: {} required: - total_count - inbox_count - outbox_count - message_count - inmail_count - connection_note_count - with_attachments_count - groups refresh: type: object properties: performed: type: boolean pages_fetched: type: number items_seen: type: number items_upserted: type: number stop_reason: type: - string - 'null' required: - performed - pages_fetched - items_seen - items_upserted - stop_reason pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - items - pagination - applied_filters - includes - meta - refresh DownloadLinkedinSalesNavMessageAttachmentResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: {} result: type: object properties: data_url: type: string description: data:;base64,… . The whole payload, inline. content_type: type: string description: MIME type LinkedIn served the asset with. file_byte_size: type: number description: Decoded size in bytes. required: - data_url - content_type - file_byte_size meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta SendLinkedinMessageResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta StartLinkedinGroupConversationResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta GetMyLatestLinkedinMessagesRequest: type: object description: Request body of `get_my_latest_linkedin_messages`. properties: linkedin_conversation_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_cv_ description: REQUIRED; must be a messenger_type='linkedin' thread. page_size: type: integer minimum: 1 maximum: 100 description: N returned, 1..100, default 50. cursor: type: - string - 'null' description: Opaque; pagination over the refreshed tail. required: - linkedin_conversation_sid DeleteLinkedinMessageOnLinkedinResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta SendLinkedinSalesNavMessageResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta SearchLinkedinMessagesResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object additionalProperties: {} required: - success - operation - items - pagination - applied_filters - includes - meta ReactLinkedinMessageResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta SendLinkedinInmailResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta GetLinkedinMessagesMetricsRequest: type: object description: Request body of `get_linkedin_messages_metrics`. properties: filter: type: object properties: linkedin_account_sid: type: object properties: eq: type: string in: type: array items: type: string additionalProperties: false description: Row scope; linkedin_account_sid is REQUIRED (422 without it). period: type: object properties: from: type: string format: date-time description: ISO 8601 UTC start (inclusive). to: type: string format: date-time description: ISO 8601 UTC end (exclusive); must be after from; window ≤ 90 days. required: - from - to description: Metrics time window. group_by: type: string enum: - linkedin_account_sid - linkedin_conversation_sid - type - linkedin_type - automation - messenger_type description: Optional single split axis. required: - filter - period GetMyLatestLinkedinMessagesResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object properties: total_count: type: number inbox_count: type: number outbox_count: type: number message_count: type: number inmail_count: type: number connection_note_count: type: number with_attachments_count: type: number groups: type: object additionalProperties: {} required: - total_count - inbox_count - outbox_count - message_count - inmail_count - connection_note_count - with_attachments_count - groups refresh: type: object properties: performed: type: boolean pages_fetched: type: number items_seen: type: number items_upserted: type: number stop_reason: type: - string - 'null' required: - performed - pages_fetched - items_seen - items_upserted - stop_reason pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - items - pagination - applied_filters - includes - meta - refresh DownloadLinkedinSalesNavMessageAttachmentRequest: type: object description: Request body of `download_linkedin_sales_nav_message_attachment`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'Mailbox owner (Sales Navigator required): the SN message row''s linkedin_account_sid.' message_id: type: string maxLength: 255 description: 'Raw LinkedIn MessageId: the message row''s message_hash.' attachment_urn: type: string maxLength: 512 description: 'Which attachment of that message: attachments[i].urn on the stored row (urn:li:digitalmediaAsset:…).' required: - linkedin_account_sid - message_id - attachment_urn SendLinkedinRecruiterMessageResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object additionalProperties: {} meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta CheckLinkedinMessageSentResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: type: - object - 'null' properties: sid: type: string team_sid: type: string linkedin_account_sid: type: string linkedin_conversation_sid: type: string messenger_type: type: string enum: - linkedin - sales_navigator - recruiter description: 'Messenger surface: the basic LinkedIn messenger, Sales Navigator, or the LinkedIn Recruiter inbox.' linkedin_type: type: string enum: - message - inmail - connection_note - system description: 'Channel sub-kind: regular DM / premium InMail / system-seeded connection note / a notice LinkedIn posted into the thread on someone''s action (system: a rename, a member added or removed, a member leaving; the body is LinkedIn''s own sentence, the sender the acting member; not a message: it takes no reaction and no recall, draw it as history).' type: type: string enum: - inbox - outbox description: 'Direction relative to our account: received / sent.' automation: type: string enum: - auto - manual - synced description: 'Writer provenance: a sequence runner (auto), a person through a send tool (manual), or the messages sync (synced). An invitation note is a synced row labelled linkedin_type=connection_note; the ''connect'' value left on 2026-09-20 with the seeders that were its only writer and never shipped.' ln_member_id: type: - string - 'null' description: The counterpart's member id, decoded from whichever LinkedIn id the thread carries. Null only on a thread with an organization (a Message Ads page names nobody). ln_id: type: - string - 'null' sn_id: type: - string - 'null' recruiter_id: type: - string - 'null' description: The counterpart's LinkedIn Recruiter (talent) profile id, denormalized from the parent recruiter thread. Null off the recruiter surface. nickname: type: - string - 'null' subject: type: - string - 'null' text: type: string client_reference: type: - string - 'null' attachments: type: array items: type: object properties: id: type: string urn: type: string description: digitalmediaAsset URN; the attachment_urn the download tools take. name: type: string content_type: type: string content_url: type: string file_byte_size: type: number file_name: type: string description: 'Rows our send verbs wrote: the file name as sent.' file_type: type: string description: 'Rows our send verbs wrote: the MIME type as sent.' reactions: type: - array - 'null' items: type: object properties: emoji: type: string count: type: number is_viewer_reacted: type: boolean first_reacted_at: type: - string - 'null' required: - emoji - count - is_viewer_reacted - first_reacted_at is_deleted: type: boolean message_hash: type: string sent_at: type: string custom_content: type: - object - 'null' additionalProperties: {} created_at: type: string updated_at: type: string deleted_at: type: - string - 'null' required: - sid - team_sid - linkedin_account_sid - linkedin_conversation_sid - messenger_type - linkedin_type - type - automation - ln_member_id - ln_id - sn_id - recruiter_id - nickname - subject - text - client_reference - attachments - reactions - is_deleted - message_hash - sent_at - custom_content - created_at - updated_at - deleted_at result: type: object properties: outcome: type: string description: sent | not_sent | in_flight | unknown. Send the same request again only on not_sent; on in_flight or unknown ask again after retry_after. reason: type: - string - 'null' description: 'Why. sent: null (item is the row), message_row_pending (it went out, its row comes later), caller_confirmed (a person said so; no row). not_sent: no_send_under_key, refused, not_in_thread, caller_confirmed. unknown: answer_lost, may_still_land, thread_unreadable, unexplained_message, unprovable.' retry_after: type: string description: 'ISO 8601: for a send in doubt, when its thread is read next or the moment it can no longer land.' activity_log_sid: type: string description: 'The attempt the answer is about (in flight, in doubt or landed): what confirmed_not_sent / confirmed_sent name on the send tools.' send_decisive_at: type: string description: 'ISO 8601: the moment a send in doubt can no longer land; a person''s confirmed_not_sent is taken from then on.' required: - outcome - reason meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - action - item - result - meta DownloadLinkedinMessageAttachmentResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: {} result: type: object properties: data_url: type: string description: data:;base64,… . The whole payload, inline. content_type: type: string description: MIME type LinkedIn served the asset with. file_byte_size: type: number description: Decoded size in bytes. required: - data_url - content_type - file_byte_size meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: 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: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms pacing: type: object properties: linkedin_account_sid: type: string description: The account whose bucket the call spent. limit_type: type: string description: The smart-limit bucket the call spent, e.g. send_messages. next_call_after: type: string description: 'ISO 8601, the same form as retry_after: the moment this same call goes through again without waiting. The next pacing slot while the day has budget left, the daily reset when it has none, the end of a LinkedIn lock while one stands.' remaining_today: type: integer minimum: 0 description: daily_limit minus done_today_count of that bucket, after this call. required: - linkedin_account_sid - limit_type - next_call_after - remaining_today required: - success - operation - action - item - result - meta responses: McpServerError: description: MCP error envelope with `error.code` internal_error or service_unavailable. content: application/json: schema: $ref: '#/components/schemas/McpError' McpClientError: description: 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. content: application/json: schema: $ref: '#/components/schemas/McpError' securitySchemes: BearerJwt: type: http scheme: bearer bearerFormat: JWT description: Access token issued by gtm.service.id. Its `access_identity` claim carries `team_sid`, `actor_sid` and `actor_type`, and that team scope is authoritative. TeamSid: type: apiKey in: header name: Team-SID description: Team scope for tokens that do not carry one. Ignored when the token already names a team. x-refined-from: - gtm-api-openapi-openapi.yml - gtm-api-linkedin-openapi.yaml