openapi: 3.2.0 info: title: Gtm Linkedin Posting 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_posting 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_posting description: Registry package `mcp.linkedin/linkedin_posting`, served on MCP mount `linkedin.content`. paths: /api/linkedin-posting/check-sent: post: operationId: check_linkedin_posting_sent summary: Check whether a LinkedIn comment, post or repost went out description: 'Ask what a LinkedIn comment, post or repost came to, without sending: by the client_reference it went out under and its verb (comment, create-post, repost), optionally at one place (entity_urn: the post a comment or a repost went to, in any of its forms, or the comment a reply answers; parent_comment_urn for a reply; post_place for a post), or by the activity_log_sid a 409 named. result.outcome: sent (item is what it made, or null with reason result_pending or caller_confirmed), in_flight, unknown (LinkedIn has not shown it yet; retry_after, send_decisive_at), or not_sent (no_send_under_key, refused, not_on_linkedin, 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). A send in doubt has LinkedIn read now when the last look is old enough. A key sent to several places is 422 place_required, a place LinkedIn could not be read for 422 place_unmatched (context.places). Contract: - MCP tool `check_linkedin_posting_sent`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - Operation `action`, response envelope `action`. - Flags: none.' tags: - linkedin_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckLinkedinPostingSentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/CheckLinkedinPostingSentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: check_linkedin_posting_sent x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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-posting/comment: post: operationId: create_linkedin_comment summary: Create LinkedIn comment description: 'Leave ONE outbound comment on any LinkedIn post (wire create-comment): entity_urn takes a post urn in any family or a post URL carrying one, and the comment is written on the post''s social thread (see entity_urn). Outward and fire-on-success: the post does NOT need to be tracked or owned by us. Identity-bound: linkedin_account_sid REQUIRED, spends the comment_posts bucket (30/day at a 360 s floor), saturation returns 429. Reply to an existing comment via parent_comment_urn. mentions turns exact substrings of text into clickable profile links ({profile_id, name} pairs; a name missing or out of order is a 422 with no dispatch spent). Returns the created comment ref plus the activity-log row. Sends once per client_reference and place (the post as LinkedIn files it, or the comment a reply answers): a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. To react use react_linkedin_post; to resolve a post URL use get_activity_urn_by_url. Contract: - MCP tool `create_linkedin_comment`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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; mass action: this verb''s own request accepts a filter or targets[] set, which the owning service drains; step eligible: gtm.service.orchestration can run this verb as a mass-action plan step, once per item; paced: a call spends the `comment_posts` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateLinkedinCommentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/CreateLinkedinCommentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: create_linkedin_comment x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: true x-gtm-step-eligible: true x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: comment_posts servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/create-post: post: operationId: create_linkedin_post summary: Create LinkedIn post description: 'Publish ONE feed post - as the member, AS a company page it administers (author_organization_id), or INTO a group (group_id) - now or scheduled (scheduled_at) - wire create-post. Public; retract with delete_linkedin_post, or delete a scheduled draft with delete_linkedin_scheduled_post. Identity-bound: linkedin_account_sid REQUIRED, spends the posting bucket (20/day in series of 3 at a 1200 s pause; free plan 4), saturation returns 429. text is REQUIRED as a key but may be an EMPTY string when media is attached; no text, images or video at all is a 422. Media: up to 20 images XOR one video, each base64 or an https url, 35 MB total. Answers the published post (urn, url, time, body) and the activity-log row. Sends once per client_reference and place (your feed, the page or the group; a new scheduled_at is the same post): a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. 409 post_not_created is send_outcome unknown: repeat after retry_after. Contract: - MCP tool `create_linkedin_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `posting` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateLinkedinPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/CreateLinkedinPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: create_linkedin_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: posting servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/delete-comment: post: operationId: delete_linkedin_comment summary: Delete LinkedIn comment description: 'Delete one of OUR OWN LinkedIn comments, addressed by comment_urn (wire delete-comment). The counterpart of create_linkedin_comment. You already hold the handle: create_linkedin_comment returns comment_urn, and the linkedin-scraping get-post-comments rows carry the same compound urn, so a comment can be removed without any extra read. LinkedIn only deletes the account''s own comments and we do not pre-validate that. Identity-bound: linkedin_account_sid REQUIRED, spends the SAME comment_posts bucket as commenting (30/day), but an undo is paced 2 s, not the bucket delay, so a comment and its delete fit back to back; saturation returns 429. Nothing is stored on this service. Contract: - MCP tool `delete_linkedin_comment`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `comment_posts` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinCommentRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinCommentResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: delete_linkedin_comment x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: comment_posts servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/delete-post: post: operationId: delete_linkedin_post summary: Delete LinkedIn post description: 'Delete one of OUR OWN LinkedIn posts, addressed by activity_urn (wire delete-post). The counterpart of create_linkedin_post and the way to retract a post an agent published: pass the activity_urn that create_linkedin_post returned, or the post URL. LinkedIn only deletes the account''s own posts and we do not pre-validate that. Identity-bound: linkedin_account_sid REQUIRED, spends the SAME posting bucket as publishing (20/day in series of 3 at a 1200 s pause; free plan 4 - the series is what lets a publish and its delete fit back-to-back), saturation returns 429. Backend urns (urn:li:share:, urn:li:ugcPost:) are NOT accepted here even though create_linkedin_post returns one: the wire builds its payload from the numeric activity id. A refusal - not your post, already gone - comes back as 409 post_not_deleted with LinkedIn''s own toast in error.context, never as a success. Nothing is stored on this service, so nothing local is deleted either. Contract: - MCP tool `delete_linkedin_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `posting` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: delete_linkedin_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: posting servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/delete-scheduled-post: post: operationId: delete_linkedin_scheduled_post summary: Delete scheduled LinkedIn post description: 'Delete one SCHEDULED (never published) post from the account''s queue, addressed by the BACKEND urn get_linkedin_scheduled_posts returns as rows[].post_urn (wire delete-scheduled-post). NOT a variant of delete_linkedin_post: an unpublished share has no activity urn, and this verb runs a graphql mutation against the queue while delete-post drives an SDUI action on a live feed post - the two handles are not interchangeable. Spends the one Content bucket, posting (20/day in series of 3 with a 1200 s pause; free plan 4/day) - the same bucket publishing spends, sized so queue cleanup and publishing fit together. A refusal - not this account''s draft, or already gone - comes back as 409 scheduled_post_not_deleted, never as a success. Contract: - MCP tool `delete_linkedin_scheduled_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `posting` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinScheduledPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DeleteLinkedinScheduledPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: delete_linkedin_scheduled_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: posting servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/get-scheduled-posts: post: operationId: get_linkedin_scheduled_posts summary: Get scheduled LinkedIn posts description: 'One page of the account''s SCHEDULED-posts queue: drafts waiting for their publication time, each with post_urn, scheduled_at, text and LinkedIn''s own error_message (wire get-scheduled-posts). A PRIVATE read - nobody on LinkedIn sees it - but it spends the one Content bucket, posting (20/day in series of 3 with a 1200 s pause; free plan 4/day), shared with publishing. Pass author_organization_id (the bare numeric company id) to read a COMPANY PAGE''s queue the account administers instead of the member''s own. Offset-paged: page_size 1-100 (default 20), pass paging.next_cursor back as cursor. rows[].post_urn is the exact handle delete_linkedin_scheduled_post takes. Scheduling itself is not exposed through this API yet - posts are scheduled in LinkedIn''s own UI; this pair reads and cleans the queue. Contract: - MCP tool `get_linkedin_scheduled_posts`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - Operation `action`, response envelope `action`. - Flags: paced: a call spends the `posting` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GetLinkedinScheduledPostsRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetLinkedinScheduledPostsResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_linkedin_scheduled_posts x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: posting servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/react: post: operationId: react_linkedin_post summary: React to LinkedIn post description: 'Leave OUR reaction on any LinkedIn post OR comment (wire create-reaction): entity_urn takes a post urn in any family, a post URL carrying one, or a comment urn; a post is reacted on at its social thread (see entity_urn). The social-selling counterpart of create_linkedin_comment. Outward and fire-on-success: the post does NOT need to be tracked, nothing is persisted here. Identity-bound: linkedin_account_sid REQUIRED, spends the react_posts bucket (30/day at a 360 s floor), saturation returns 429. Returns reaction_urn (the reaction''s key, naming the entity it landed on; null on drift or when LinkedIn ignored it) plus the activity-log row. interested is the EVENT-post reaction: ordinary posts silently ignore it (success envelope, null reaction_urn, nothing lands - verified live). Takes no key: LinkedIn keeps one reaction per account and post, so repeating the same reaction changes nothing; every refusal still names error.context.send_outcome. To comment use create_linkedin_comment. Contract: - MCP tool `react_linkedin_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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; mass action: this verb''s own request accepts a filter or targets[] set, which the owning service drains; step eligible: gtm.service.orchestration can run this verb as a mass-action plan step, once per item; paced: a call spends the `react_posts` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReactLinkedinPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/ReactLinkedinPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: react_linkedin_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: true x-gtm-step-eligible: true x-gtm-schedule-required: false x-gtm-tool-class: typical x-gtm-paced-bucket: react_posts servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/repost: post: operationId: repost_linkedin_post summary: Repost LinkedIn post description: 'Repost a LinkedIn post from one of the team accounts (wire create-instant-repost / create-repost-with-thoughts): ONE tool, the body picks which. Without text it is the plain repost (the feed''s Repost button) and nothing else may be sent. With text it is a repost with your thoughts, a share of your own above the reposted post, which takes visibility, allowed_commenters_scope and mentions exactly as create_linkedin_post does. post_urn is the post being reposted as urn:li:activity, urn:li:share or urn:li:ugcPost (a group post cannot be reposted). Public and outward; retract with delete_linkedin_post on the answered activity_urn. Spends the posting bucket. Sends once per client_reference and reposted post (as LinkedIn files it, whichever of its urns you name): a repeat is answered, never sent twice; on a 409 read error.context.send_outcome, never resend under a new key. A plain repost has no deadline on LinkedIn''s side, so one whose answer was lost stays in doubt for an hour. Contract: - MCP tool `repost_linkedin_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `posting` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RepostLinkedinPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/RepostLinkedinPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: repost_linkedin_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: posting servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway /api/linkedin-posting/unreact: post: operationId: unreact_linkedin_post summary: Remove LinkedIn reaction description: 'Remove OUR reaction from a LinkedIn post or comment, addressed by the same entity_urn react_linkedin_post took (wire delete-reaction). Undo a reaction left by mistake or by a play that has been retargeted. Takes no reaction_type: LinkedIn holds at most one reaction per account per entity, so removal is unambiguous. Identity-bound: linkedin_account_sid REQUIRED, spends the SAME react_posts bucket as reacting (30/day), but an undo is paced 2 s, not the bucket delay, so a reaction and its removal fit back to back; saturation returns 429. A post is addressed at its social thread exactly like react_linkedin_post, so undoing with the value you reacted with removes the reaction that landed. removed: true means LinkedIn accepted the delete, not that a reaction existed (a delete with nothing to remove answered true live, 2026-09-16); a refused removal comes back 409 reaction_not_removed. Contract: - MCP tool `unreact_linkedin_post`, registry package `mcp.linkedin/linkedin_posting`, mount `linkedin.content`. - 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 `react_posts` 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_posting requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UnreactLinkedinPostRequest' responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/UnreactLinkedinPostResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: unreact_linkedin_post x-gtm-mcp-mount: linkedin.content x-gtm-entity: linkedin_posting 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: react_posts servers: - url: https://app.gtm-api.com/linkedin/v4 description: Production, through the app.gtm-api.com gateway components: schemas: ReactLinkedinPostRequest: type: object description: Request body of `react_linkedin_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' entity_urn: type: string minLength: 1 maxLength: 512 description: 'The post or comment to react on. LinkedIn files a reaction under the post''s social thread and silently drops one sent to any other key (success, null reaction_urn, nothing lands: captured live on the activity urn of a ugcPost company post), so a post handle is re-addressed at its thread before the wire. urn:li:ugcPost: and urn:li:groupPost:- are the thread and go as is. urn:li:activity: and urn:li:share: cost one post read first (the read enrich_linkedin_post_details makes, on this account, cached 7 days): a share post is reacted on at its activity urn, a ugcPost post at its ugcPost urn, a repost without commentary at the original. A post the read returns null for (deleted, or not visible to the account) is refused 422 post_not_resolvable. A COMMENT key targets a comment and passes verbatim, either form: urn:li:comment:((activity|share|ugcPost|groupPost):,) or urn:li:fsd_comment:(,). A post URL works when the id is in it: the feed permalink, the /posts/-activity-- share link, the -ugcPost-- share link. A link WITHOUT an id (a shortlink, a bare slug URL) is refused 422 entity_urn_not_resolvable: call enrich_linkedin_get_activity_urn_by_url first. A malformed urn is refused 422 before any dispatch. The post does NOT need to be tracked or owned by us.' reaction_type: type: - string - 'null' enum: - like - celebrate - support - love - insightful - funny - interested description: The reaction to leave, mapped to the plugin wire ReactionType. Defaults to like. interested (wire MAYBE) works on EVENT posts; ordinary posts silently ignore it (null reaction_urn back). required: - linkedin_account_sid - entity_urn CreateLinkedinCommentResponse: 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: comment_urn: type: string description: The created comment ref. activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. idempotent_replay: type: boolean description: 'true when this answers a repeat (under the key, or without one the same words at the same place) with what the first send made: nothing was sent now.' content_differs: type: boolean description: 'With idempotent_replay: true when this request''s words (or a post''s pictures or video) differ from those of the send that made it.' required: - comment_urn - activity_log 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 UnreactLinkedinPostResponse: 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: removed: type: boolean enum: - true activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - removed - activity_log 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 DeleteLinkedinScheduledPostRequest: type: object description: Request body of `delete_linkedin_scheduled_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' post_urn: type: string minLength: 1 maxLength: 512 description: 'The queued share to delete: urn:li:share:, urn:li:ugcPost: or urn:li:groupPost:-, exactly as rows[].post_urn hands it back. The grammar is enforced on the wire.' required: - linkedin_account_sid - post_urn DeleteLinkedinCommentRequest: type: object description: Request body of `delete_linkedin_comment`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' comment_urn: type: string minLength: 1 maxLength: 512 description: 'The comment to delete, as our comment readers return it: urn:li:comment:(,) over any post family. The fsd form urn:li:fsd_comment:(,) that LinkedIn''s own responses carry is accepted too and normalized on the wire side.' required: - linkedin_account_sid - comment_urn CreateLinkedinCommentRequest: type: object description: Request body of `create_linkedin_comment`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' entity_urn: type: string minLength: 1 maxLength: 512 description: 'The post to comment on. A comment is written on the post''s social thread, and LinkedIn refuses one sent to any other key (live 2026-09-16: the activity urn of a ugcPost company post answered linkedin_400, its ugcPost urn took the comment), so a post handle is re-addressed at its thread before the wire. urn:li:ugcPost: and urn:li:groupPost:- are the thread and go as is. urn:li:activity: and urn:li:share: cost one post read first (the read enrich_linkedin_post_details makes, on this account, cached 7 days): a share post is commented at its activity urn, a ugcPost post at its ugcPost urn, a repost without commentary at the original. A post the read returns null for (deleted, or not visible to the account) is refused 422 post_not_resolvable. To reply under a comment, pass parent_comment_urn (no post read then); a comment urn given here is a reply under that comment too. A post URL works when the id is in it: the feed permalink, the /posts/-activity-- share link, the -ugcPost-- share link. A link WITHOUT an id (a shortlink, a bare slug URL) is refused 422 entity_urn_not_resolvable: call enrich_linkedin_get_activity_urn_by_url first. The post does NOT need to be tracked or owned by us. Renamed from activity_urn on 2026-07-30; the old name is no longer accepted.' text: type: string minLength: 1 maxLength: 1250 description: The comment body (caller-supplied, no templates or AI in-app). parent_comment_urn: type: - string - 'null' maxLength: 512 description: 'Reply target: the comment URN to reply under. Omit or null for a top-level comment.' mentions: type: array items: type: object properties: profile_id: type: string minLength: 1 description: 'Who to mention: a bare ACoA… profile id (as get-post-comments and the profile readers return) or the full urn:li:fsd_profile:.' name: type: string minLength: 1 description: The exact substring of text that becomes the clickable link (usually the profile name). required: - profile_id - name description: Profile mentions (2026-08-21). Names are matched in text left to right in list order, each search starting after the previous mention. The node computes the character offsets itself. client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE comment (max 255, byte for byte): one key per comment, the same key on every repeat of it. The key and its place (the post as LinkedIn files it, named by any of its urns, or for a reply the comment it answers) are one comment whatever it says, and a repeat never goes out twice: it answers 200 with what the first send made (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 comment in doubt holds the place). The same key at another place is another comment. Without a key the same words at the same place count as a repeat for an hour after they went out. check_linkedin_posting_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 send is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_posting_sent, given only after someone looked on LinkedIn. 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 send''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 send 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 while what it made is not known (LinkedIn is read for it), or 200 with it once a read has found it. Another send''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - entity_urn - text UnreactLinkedinPostRequest: type: object description: Request body of `unreact_linkedin_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' entity_urn: type: string minLength: 1 maxLength: 512 description: 'The post or comment to react on. LinkedIn files a reaction under the post''s social thread and silently drops one sent to any other key (success, null reaction_urn, nothing lands: captured live on the activity urn of a ugcPost company post), so a post handle is re-addressed at its thread before the wire. urn:li:ugcPost: and urn:li:groupPost:- are the thread and go as is. urn:li:activity: and urn:li:share: cost one post read first (the read enrich_linkedin_post_details makes, on this account, cached 7 days): a share post is reacted on at its activity urn, a ugcPost post at its ugcPost urn, a repost without commentary at the original. A post the read returns null for (deleted, or not visible to the account) is refused 422 post_not_resolvable. A COMMENT key targets a comment and passes verbatim, either form: urn:li:comment:((activity|share|ugcPost|groupPost):,) or urn:li:fsd_comment:(,). A post URL works when the id is in it: the feed permalink, the /posts/-activity-- share link, the -ugcPost-- share link. A link WITHOUT an id (a shortlink, a bare slug URL) is refused 422 entity_urn_not_resolvable: call enrich_linkedin_get_activity_urn_by_url first. A malformed urn is refused 422 before any dispatch. The post does NOT need to be tracked or owned by us.' required: - linkedin_account_sid - entity_urn GetLinkedinScheduledPostsResponse: 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: rows: type: array items: type: object properties: post_urn: type: - string - 'null' description: 'The queued share''s BACKEND urn (urn:li:share:/ugcPost:/groupPost:) - the exact handle delete_linkedin_scheduled_post takes. NOT an activity urn: an unpublished post has no activity yet.' scheduled_at: type: - string - 'null' description: Planned publication time, ISO 8601; null when the preview did not carry it (best-effort field). text: type: string description: Draft body; empty string when the draft has no text. error_message: type: - string - 'null' description: LinkedIn's own preview error (e.g. failed media processing); normally null. required: - post_urn - scheduled_at - text - error_message paging: type: object properties: next_cursor: type: - string - 'null' description: Offset cursor for the next page; null when the queue is exhausted. total: type: - integer - 'null' description: The wire's total queue size, when it sends one. required: - next_cursor - total activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - rows - paging - activity_log 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 DeleteLinkedinPostResponse: 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: deleted: type: boolean enum: - true description: 'Always true on a 200: a refused delete is a 409, never a success body.' message: type: - string - 'null' description: LinkedIn's own confirmation toast, when it sends one. activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - deleted - message - activity_log 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 CheckLinkedinPostingSentResponse: 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: comment_urn: type: - string - 'null' description: 'A comment or a reply: the comment it made.' kind: type: string description: 'A repost: instant or with_thoughts.' activity_urn: type: - string - 'null' description: 'A post or a repost: its feed entry.' post_urn: type: - string - 'null' description: 'A post or a repost: the publication.' url: type: - string - 'null' created_at: type: - string - 'null' text: type: string parent_post_urn: type: - string - 'null' description: 'A repost: the post it reposted.' description: 'What the send made, in the shape its own verb answers: a comment the comment_urn; a post its urns, url, time and body; a repost its kind, urns, url, time, body and the reposted post.' 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 what it made), result_pending (it went out, what it made is read later), caller_confirmed (a person said so; no item). not_sent: no_send_under_key, refused, not_on_linkedin, caller_confirmed. unknown: answer_lost, may_still_land, unreadable, unexplained, unprovable (a group post, or a page post its page has not shown: no read can prove either absent).' retry_after: type: string description: 'ISO 8601: for a send in doubt, when LinkedIn is read for it next.' 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 comment, post and repost 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. A plain repost carries no deadline of its own, so it is an hour after its answer was lost.' 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 RepostLinkedinPostRequest: type: object description: Request body of `repost_linkedin_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' post_urn: type: string pattern: ^urn:li:(activity|share|ugcPost):\d+$ description: 'The post to repost: urn:li:activity:, urn:li:share: or urn:li:ugcPost:.' text: type: string maxLength: 3000 description: Your own words above the reposted post. Omit (or blank) for a plain repost. visibility: type: string enum: - ANYONE - CONNECTIONS_ONLY description: With text only. ANYONE (the default) or CONNECTIONS_ONLY. allowed_commenters_scope: type: string enum: - ALL - CONNECTIONS_ONLY - NONE description: With text only. ALL (the default), CONNECTIONS_ONLY, or NONE to disable comments. mentions: type: array items: type: object properties: profile_id: type: string minLength: 1 description: The mentioned member's profile id (ACoA... or urn:li:fsd_profile:). start: type: integer minimum: 0 description: Offset of the mention in text, UTF-16 code units. length: type: integer minimum: 1 description: Length of the mention span in UTF-16 code units. required: - profile_id - start - length description: 'With text only: profile mentions as ready positions over text, as create_linkedin_post takes them.' client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE repost (max 255, byte for byte): one key per repost, the same key on every repeat of it. The key and its place (the post it reposts, as LinkedIn files it) are one repost whatever it says, and a repeat never goes out twice: it answers 200 with what the first send made (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 repost in doubt holds the place). The same key at another place is another repost. Without a key a repost of the same post with the same words count as a repeat for an hour after they went out. check_linkedin_posting_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 send is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_posting_sent, given only after someone looked on LinkedIn. 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 send''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 send 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 while what it made is not known (LinkedIn is read for it), or 200 with it once a read has found it. Another send''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - post_urn DeleteLinkedinPostRequest: type: object description: Request body of `delete_linkedin_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' activity_urn: type: string minLength: 1 maxLength: 512 description: 'The post to delete: urn:li:activity:, a bare numeric activity id, or a post URL carrying the id (converted locally, same rule as entity_urn on the write verbs). urn:li:share: / urn:li:ugcPost: are refused by the wire.' required: - linkedin_account_sid - activity_urn CreateLinkedinPostResponse: 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: activity_urn: type: - string - 'null' description: The published post as an activity urn. post_urn: type: - string - 'null' description: The same post as urn:li:share:. url: type: - string - 'null' description: Public post URL, query string already stripped. created_at: type: - string - 'null' description: Publication time, ISO 8601. text: type: string description: The body LinkedIn actually published, read back off the wire. Empty for an image-only post. activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. idempotent_replay: type: boolean description: 'true when this answers a repeat (under the key, or without one the same words at the same place) with what the first send made: nothing was sent now.' content_differs: type: boolean description: 'With idempotent_replay: true when this request''s words (or a post''s pictures or video) differ from those of the send that made it.' required: - activity_urn - post_urn - url - created_at - text - activity_log 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 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 GetLinkedinScheduledPostsRequest: type: object description: Request body of `get_linkedin_scheduled_posts`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' page_size: type: integer minimum: 1 maximum: 100 description: Rows per page, the node's own [1, 100] gate. Defaults to 20. cursor: type: string minLength: 1 maxLength: 200 description: The previous page's paging.next_cursor, verbatim. Omit for the first page. author_organization_id: type: string maxLength: 30 pattern: ^\d+$ description: 'Read a company page''s queue instead of the member''s own: the bare numeric organization id (as in linkedin.com/company/). The account must administer that page or the queue comes back empty.' required: - linkedin_account_sid DeleteLinkedinScheduledPostResponse: 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: deleted: type: boolean enum: - true description: 'Always true on a 200: a refused delete is a 409 scheduled_post_not_deleted, never a success body.' activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - deleted - activity_log 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 RepostLinkedinPostResponse: 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: kind: type: string description: instant (a plain repost) or with_thoughts (a share with your text). activity_urn: type: - string - 'null' description: 'The feed entry the repost became: what delete_linkedin_post takes.' post_urn: type: - string - 'null' description: 'The publication: urn:li:instantRepost:(,) for a plain repost, the share (urn:li:ugcPost: live, urn:li:share: on older shares) for one with thoughts.' url: type: - string - 'null' description: Public URL of the repost, query string stripped. created_at: type: - string - 'null' description: ISO 8601. text: type: string description: The commentary LinkedIn published; empty for a plain repost. parent_post_urn: type: - string - 'null' description: The backend urn (share / ugcPost) that was reposted. message: type: - string - 'null' description: The plain repost's success toast, when LinkedIn showed one. activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. idempotent_replay: type: boolean description: 'true when this answers a repeat (under the key, or without one the same words at the same place) with what the first send made: nothing was sent now.' content_differs: type: boolean description: 'With idempotent_replay: true when this request''s words (or a post''s pictures or video) differ from those of the send that made it.' required: - kind - activity_urn - post_urn - url - created_at - text - parent_post_urn - message - activity_log 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 CreateLinkedinPostRequest: type: object description: Request body of `create_linkedin_post`. properties: linkedin_account_sid: type: string minLength: 18 maxLength: 18 pattern: ^ln_ac_ description: 'LinkedIn account sid (ln_ac_…), the authoring account. Identity-bound: REQUIRED, posts publish AS this account.' text: type: string maxLength: 3000 description: Post body, always present. Empty is legal ONLY alongside an image. 3000 is LinkedIn's own cap, refused here rather than burning a posting slot. Published byte for byte, blank lines included, and so is each image's alt_text. images: type: array items: type: object properties: file_base64: type: string minLength: 1 description: 'The image bytes of a PNG, JPEG, GIF or WEBP: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 or url. Checked before anything is dispatched: a damaged file, a non-image or invalid base64 is a 422 on this member (image_corrupt / image_format_unrecognized / image_not_base64) and spends nothing. Base64 typed out by hand is the usual source of damage: prefer url.' url: type: string maxLength: 2048 format: uri description: An https URL of the image file, downloaded by us (public hosts only, the same 35 MB post budget, typed and checked by content). Exactly one of file_base64 or url. A request_media_upload file_url works once its upload is done. A link to a web page that shows the image is refused (image_format_unrecognized); fetch problems are media_url_invalid / media_url_host_forbidden / media_url_fetch_failed / media_too_large. file_byte_size: type: - integer - 'null' minimum: 1 file_name: type: - string - 'null' minLength: 1 maxLength: 255 file_type: type: - string - 'null' minLength: 1 maxLength: 255 alt_text: type: - string - 'null' description: Accessibility alt text; may be empty. maxItems: 20 description: 'Up to 20 images (the node''s own cap; array order = carousel order). Mutually exclusive with video. The decoded bytes across ALL media must stay under 35 MB in total; over that is a 422, because a bigger body is refused by the node''s JSON parser as a bare 413 with no response envelope. For 2+ images the backend supplies the account''s own member id to the wire itself - no profile_id field exists here. Uploads are sequential node-side, so many large images make a SLOW synchronous call: the post can publish after your client times out, so repeat it only as the same request under the same client_reference, which is answered with the post (or held while LinkedIn is read), never published twice.' visibility: type: string enum: - ANYONE - CONNECTIONS_ONLY description: ANYONE (the node default) or CONNECTIONS_ONLY. Omit to let the node apply its own default. Mutually exclusive with group_id. allowed_commenters_scope: type: string enum: - ALL - CONNECTIONS_ONLY - NONE description: 'Who may comment: ALL (the node default), CONNECTIONS_ONLY, or NONE to disable comments. Works on group posts too.' video: type: object properties: file_base64: type: string minLength: 1 description: 'The video bytes: a data:;base64,<...> URL or bare base64. Exactly one of file_base64 or url.' url: type: string maxLength: 2048 format: uri description: An https URL of an MP4, MOV or WEBM file, downloaded by us (public hosts only, within the 35 MB budget). Exactly one of file_base64 or url; a request_media_upload file_url works once uploaded. file_byte_size: type: - integer - 'null' minimum: 1 file_name: type: - string - 'null' minLength: 1 maxLength: 255 file_type: type: - string - 'null' minLength: 1 maxLength: 255 description: 'ONE video, image-shaped minus alt_text. Mutually exclusive with images (LinkedIn does not mix them in a share - 422 here). Shares the 35 MB media budget. The upload is a single large PUT through the browser and is SLOW: the synchronous call can outlive your client timeout while the post still publishes, so repeat it only under the same client_reference.' scheduled_at: type: string description: 'Schedule the post instead of publishing now: ISO 8601 with timezone, must be in the future (a strictly-past time is a 422; within a minute of now is passed through for LinkedIn to judge). A SCHEDULED share legitimately answers with null activity_urn/url - post_urn is the handle. Read and clean the queue with get_linkedin_scheduled_posts / delete_linkedin_scheduled_post. Scheduling is LinkedIn-side: the draft lives in ITS queue, nothing is stored here. The slot is no part of a key: a retry under the same client_reference that computes a new scheduled_at is the same post. Without a key the slot tells two posts apart.' mentions: type: array items: type: object properties: profile_id: type: string minLength: 1 description: 'Who to mention: a bare ACoA… profile id or the full urn:li:fsd_profile:.' start: type: integer minimum: 0 description: Span start in text, in UTF-16 code units (JS String offsets). length: type: integer minimum: 1 description: Span length in UTF-16 code units. start+length must fit inside text - out of bounds is a 422 here, not a spent dispatch. required: - profile_id - start - length description: Profile mentions as READY POSITIONS over text (2026-08-21) - unlike create_linkedin_comment's {profile_id, name} search pairs. Require non-blank text. brand_partnership: type: boolean description: true adds LinkedIn's "Brand partnership" label (paid endorsement). false and absent both send nothing - the wire's own shape. author_organization_id: type: string pattern: ^\d+$ description: 'Post AS a company page the account administers: the bare numeric company id (same form get_linkedin_company_posts takes). Omit to post as the member.' group_id: type: string pattern: ^\d+$ description: 'Post INTO a group: the bare numeric group id. Mutually exclusive with visibility - a group post sets container visibility, not member-feed visibility. No read serves a group''s feed, so a group post whose answer was lost stays in doubt until a person gives their word.' client_reference: type: - string - 'null' maxLength: 255 description: 'Your key for this ONE post (max 255, byte for byte): one key per post, the same key on every repeat of it. The key and its place (where it lands: your own feed, the company page of author_organization_id or the group of group_id) are one post whatever it says, and a repeat never goes out twice: it answers 200 with what the first send made (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 post in doubt holds the place). The same key at another place is another post. Without a key the same words and pictures or video at the same place and slot count as a repeat for an hour after they went out. check_linkedin_posting_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 send is not on LinkedIn: its activity_log_sid (ln_al_...), from the 409 or check_linkedin_posting_sent, given only after someone looked on LinkedIn. 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 send''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 send 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 while what it made is not known (LinkedIn is read for it), or 200 with it once a read has found it. Another send''s sid is 422 not_this_message; an attempt already proved not sent is 409 confirmed_sent_contradicts.' required: - linkedin_account_sid - text DeleteLinkedinCommentResponse: 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: deleted: type: boolean enum: - true activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - deleted - activity_log 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 ReactLinkedinPostResponse: 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: reaction_urn: type: - string - 'null' activity_log: type: object properties: {} description: Full dispatch row (linkedin-account-activity-log) per §4.12a. Poll it there by sid for the terminal outcome. required: - reaction_urn - activity_log 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 CheckLinkedinPostingSentRequest: type: object description: Request body of `check_linkedin_posting_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 verb and no place. An attempt of another account, or one that is no comment, post or repost, is 404. verb: type: - string - 'null' enum: - comment - create-post - repost description: 'Required with client_reference: the verb the key was sent by (create_linkedin_comment, create_linkedin_post, repost_linkedin_post). A key is one send per verb.' entity_urn: type: - string - 'null' maxLength: 512 description: 'Place, next to client_reference: the post a comment or a repost went to, as the send took it or in any other of its forms (it is read for its thread, on the post-details cache), or a comment urn for a reply. Not with create-post.' parent_comment_urn: type: - string - 'null' maxLength: 512 description: 'Place, next to client_reference and verb comment: the comment a reply answers, in either of its forms.' post_place: type: - string - 'null' maxLength: 128 pattern: ^(?:feed:member|feed:org:\d+|group:\d+(?::org:\d+)?)(?::scheduled:\d+)?$ description: 'Place, next to client_reference and verb create-post: where the post landed: feed:member (your own feed), feed:org: (a company page it was posted as), group: (a group; group::org: when a page posted into it), optionally :scheduled: after it. A key is read at the feed, page or group whatever its slot.' required: - linkedin_account_sid 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