> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsales.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Search messages

> Read messages: LinkedIn and email, both directions, AI SDR drafts included (a draft is state pending_approval). Two jobs. Page one thread by filter.conversation_sid plus created_at { lt: the oldest row you hold }. Or work the cross-thread approval queue with filter.state { eq: "pending_approval" }, then approve / dismiss / regenerate. page_size 0 returns counts only, and counts.groups.state.pending_approval is the queue badge. Thread state, mode and reply rates are the conversations tools.

Contract:
- MCP tool `search_messages`, registry package `mcp.unibox/messages`, mount `unibox.inbox`.
- Operation `search`, response envelope `search`.
- Flags: read only.



## OpenAPI

````yaml /api-reference/unibox/openapi.yaml post /api/messages/search
openapi: 3.0.3
info:
  title: 'GetSales public contract: gs.service.unibox'
  description: >-
    The team inbox and the AI SDR: every LinkedIn and email thread in one place
    (conversations, messages, the timeline events), the manual tasks a thread
    spawns, the sender profiles the team speaks through with their LinkedIn
    account and mailboxes, and the one agent per team with its scenarios, plans
    and runs.


    GENERATED. This document is projected from the Zod MCP tool registry in
    `product/mcp/gs.mcp` (one tool per public endpoint, 1:1). Do not edit it by
    hand; edit the tool definition and regenerate with `pnpm openapi:public`.


    Surface: the public `/api` contract of `gs.service.unibox`, 125 operations.
    This is the only OpenAPI document the platform publishes. Internal
    (`/internal`) and health endpoints are deliberately absent: they are not
    part of any contract, they can change without notice, and the service source
    is their only description.


    Conventions:

    - Auth is a bearer JWT, optionally narrowed by the `Team-SID` header.

    - Every success body is an MCP envelope: `success: true` plus one typed
    `operation` shape (`search`, `get`, `create`, `update`, `delete`, `metrics`,
    `group_by`, `action`), and a `meta` block with `trace_id` for support.

    - Every failure is the same `McpError` envelope with a code from a fixed
    16-code taxonomy, so a client maps errors once.

    - Lists page with `page_size` (0 to 500, default 50) plus an opaque forward
    `cursor`; `page_size: 0` returns counts only.

    - On `GET` and `DELETE`, object-valued query parameters (`filter`, `sort`)
    travel as JSON text and array-valued ones repeat as `name[]=value`.

    - The MCP-only `_meta` field (usage analytics) never reaches the backend and
    is not part of this contract.
  version: '1.0'
  contact:
    name: GetSales
    url: https://getsales.io
    email: support@getsales.io
  license:
    name: Proprietary
    url: https://getsales.io/terms
servers:
  - url: https://beta.getsales.io/unibox/v1
    description: >-
      Production (the gateway path on the beta ring; the origin is provisioned
      per DEPLOY_MAP.md)
security:
  - BearerJwt: []
    TeamSid: []
tags:
  - name: agent_answers
    description: >-
      Registry package `mcp.unibox/agent_answers`, served on MCP mount
      `unibox.knowledge`.
  - name: agent_conversation_uploads
    description: >-
      Registry package `mcp.unibox/agent_conversation_uploads`, served on MCP
      mount `unibox.agent-memory`.
  - name: agent_examples
    description: >-
      Registry package `mcp.unibox/agent_examples`, served on MCP mount
      `unibox.agent-memory`.
  - name: agent_hints
    description: >-
      Registry package `mcp.unibox/agent_hints`, served on MCP mount
      `unibox.agent-memory`.
  - name: agent_plans
    description: >-
      Registry package `mcp.unibox/agent_plans`, served on MCP mount
      `unibox.agent`.
  - name: agent_runs
    description: >-
      Registry package `mcp.unibox/agent_runs`, served on MCP mount
      `unibox.agent-memory`.
  - name: agent_scenarios
    description: >-
      Registry package `mcp.unibox/agent_scenarios`, served on MCP mount
      `unibox.agent`.
  - name: agent_source_parses
    description: >-
      Registry package `mcp.unibox/agent_source_parses`, served on MCP mount
      `unibox.knowledge`.
  - name: agent_sources
    description: >-
      Registry package `mcp.unibox/agent_sources`, served on MCP mount
      `unibox.knowledge`.
  - name: agent_tests
    description: >-
      Registry package `mcp.unibox/agent_tests`, served on MCP mount
      `unibox.agent-memory`.
  - name: agents
    description: >-
      Registry package `mcp.unibox/agents`, served on MCP mount
      `unibox.website`.
  - name: conversation_events
    description: >-
      Registry package `mcp.unibox/conversation_events`, served on MCP mount
      `unibox.inbox`.
  - name: conversations
    description: >-
      Registry package `mcp.unibox/conversations`, served on MCP mount
      `unibox.inbox`.
  - name: messages
    description: >-
      Registry package `mcp.unibox/messages`, served on MCP mount
      `unibox.inbox`.
  - name: sender_profiles
    description: >-
      Registry package `mcp.unibox/sender_profiles`, served on MCP mount
      `unibox.sender-profiles`.
  - name: tasks
    description: Registry package `mcp.unibox/tasks`, served on MCP mount `unibox.inbox`.
  - name: timeline
    description: >-
      Registry package `mcp.unibox/timeline`, served on MCP mount
      `unibox.inbox`.
paths:
  /api/messages/search:
    post:
      tags:
        - messages
      summary: Search messages
      description: >-
        Read messages: LinkedIn and email, both directions, AI SDR drafts
        included (a draft is state pending_approval). Two jobs. Page one thread
        by filter.conversation_sid plus created_at { lt: the oldest row you hold
        }. Or work the cross-thread approval queue with filter.state { eq:
        "pending_approval" }, then approve / dismiss / regenerate. page_size 0
        returns counts only, and counts.groups.state.pending_approval is the
        queue badge. Thread state, mode and reply rates are the conversations
        tools.


        Contract:

        - MCP tool `search_messages`, registry package `mcp.unibox/messages`,
        mount `unibox.inbox`.

        - Operation `search`, response envelope `search`.

        - Flags: read only.
      operationId: search_messages
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchMessagesRequest'
      responses:
        '200':
          description: '`search` success envelope.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchMessagesResponse'
        4XX:
          $ref: '#/components/responses/McpClientError'
        5XX:
          $ref: '#/components/responses/McpServerError'
components:
  schemas:
    SearchMessagesRequest:
      type: object
      description: Request body of `search_messages`.
      properties:
        filter:
          type: object
          properties:
            sid:
              type: object
              properties:
                eq:
                  type: string
                  minLength: 18
                  maxLength: 18
                  pattern: ^ub_ms_
                  description: Message sid (ub_ms_…).
                in:
                  type: array
                  items:
                    type: string
                    minLength: 18
                    maxLength: 18
                    pattern: ^ub_ms_
                    description: Message sid (ub_ms_…).
              additionalProperties: false
              description: >-
                Message sid(s), ub_ms_ prefix - also the point-lookup path
                (there is no get tool).
            conversation_sid:
              type: object
              properties:
                eq:
                  type: string
                  minLength: 18
                  maxLength: 18
                  pattern: ^ub_cv_
                in:
                  type: array
                  items:
                    type: string
                    minLength: 18
                    maxLength: 18
                    pattern: ^ub_cv_
              additionalProperties: false
              description: Scope to one thread (or a handful); the thread-paging filter.
            channel:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - linkedin
                    - email
                in:
                  type: array
                  items:
                    type: string
                    enum:
                      - linkedin
                      - email
              additionalProperties: false
              description: linkedin | email.
            kind:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - linkedin_message
                    - linkedin_connection_note
                    - linkedin_inmail
                    - email
                in:
                  type: array
                  items:
                    type: string
                    enum:
                      - linkedin_message
                      - linkedin_connection_note
                      - linkedin_inmail
                      - email
              additionalProperties: false
              description: >-
                Channel-native form, e.g. { eq: "linkedin_connection_note" } for
                connection notes only.
            direction:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - inbound
                    - outbound
              additionalProperties: false
              description: inbound | outbound.
            state:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - pending_approval
                    - queued
                    - sent
                    - delivered
                    - failed
                    - canceled
                in:
                  type: array
                  items:
                    type: string
                    enum:
                      - pending_approval
                      - queued
                      - sent
                      - delivered
                      - failed
                      - canceled
                nin:
                  type: array
                  items:
                    type: string
                    enum:
                      - pending_approval
                      - queued
                      - sent
                      - delivered
                      - failed
                      - canceled
              additionalProperties: false
              description: >-
                The approval queue is { eq: "pending_approval" }; what actually
                left is { in: ["sent", "delivered"] }.
            author:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - contact
                    - user
                    - agent
                in:
                  type: array
                  items:
                    type: string
                    enum:
                      - contact
                      - user
                      - agent
              additionalProperties: false
              description: >-
                contact | user | agent - the audit filter for what the AI SDR
                wrote.
            origin:
              type: object
              properties:
                eq:
                  type: string
                  enum:
                    - synced
                    - native
              additionalProperties: false
              description: synced (imported history) | native (our pipeline).
            sent_at:
              type: object
              properties:
                gte:
                  type: string
                lte:
                  type: string
                is_null:
                  type: boolean
              additionalProperties: false
              description: >-
                ISO 8601 range over provider accept; is_null true = never handed
                over (draft, queued, failed).
            created_at:
              type: object
              properties:
                gte:
                  type: string
                lte:
                  type: string
                gt:
                  type: string
                lt:
                  type: string
              additionalProperties: false
              description: >-
                ISO 8601 range in thread order; { lt: oldest_row_you_hold } is
                the older-history page.
            deleted_at:
              type: object
              properties:
                is_null:
                  type: boolean
              additionalProperties: false
              description: >-
                Reserved column with no writer in v1, so every row is { is_null:
                true } and this changes nothing.
          description: >-
            Field filters, ANDed: {field: {eq | ne | in | nin | gte | lte | gt |
            lt | is_null}}; q inside it is free text. Omit for every row.
        include:
          type: array
          items:
            type: string
            enum:
              - conversation
            description: >-
              The owning thread, hydrated once per page under
              included.conversation.
          description: Relations to attach to every item; omit for the bare rows.
        sort:
          type: object
          properties:
            field:
              type: string
              enum:
                - created_at
                - sent_at
              description: The column to order by.
            direction:
              type: string
              enum:
                - asc
                - desc
              description: asc or desc; default desc.
          required:
            - field
          description: One column and its direction; omit for the default order.
        page_size:
          type: integer
          minimum: 0
          maximum: 500
          description: 0..500, default 50; 0 = counts only, 1 = the first row.
        cursor:
          type: string
          nullable: true
          description: pagination.next_cursor of the previous page.
    SearchMessagesResponse:
      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
                    description: Message sid (ub_ms_…).
                  team_sid:
                    type: string
                    description: Owning team (ts_tm_…, external - gs.service.id).
                  conversation_sid:
                    type: string
                    description: >-
                      The thread this row hangs on (ub_cv_…); re-pointed when
                      two threads merge.
                  channel:
                    type: string
                    enum:
                      - linkedin
                      - email
                    description: linkedin | email, inherited from the thread.
                  kind:
                    type: string
                    enum:
                      - linkedin_message
                      - linkedin_connection_note
                      - linkedin_inmail
                      - email
                    description: Channel-native form; must belong to `channel`.
                  direction:
                    type: string
                    enum:
                      - inbound
                      - outbound
                    description: >-
                      inbound = from the counterpart, outbound = from our sender
                      profile.
                  state:
                    type: string
                    enum:
                      - pending_approval
                      - queued
                      - sent
                      - delivered
                      - failed
                      - canceled
                    description: >-
                      pending_approval = an AI draft awaiting you; queued =
                      accepted, not out yet (it may be in the middle of its
                      hand-over to the provider); sent/delivered = out; failed =
                      the send did not leave (failure_reason says why,
                      retry_messages sends it again, cancel_messages drops it);
                      canceled = a dismissed draft, a withdrawn or canceled
                      send: it never went out, and it is not on the thread.
                  origin:
                    type: string
                    enum:
                      - synced
                      - native
                    description: >-
                      synced = imported by the sender profile history sync (any
                      tool sent it), native = it flowed through this pipeline
                      live.
                  body_text:
                    type: string
                    description: >-
                      The canonical body, normalized to plain text. It lives
                      here and nowhere else: events, webhooks and the playtables
                      mirror carry the sid only.
                  author:
                    type: string
                    enum:
                      - contact
                      - user
                      - agent
                    description: >-
                      contact | user | agent. The AI-disclosure fact, derived
                      from the acting JWT at send and never writable.
                  subject:
                    type: string
                    nullable: true
                    description: >-
                      Email only (max 998); null on LinkedIn rows and on email
                      replies that inherited the thread subject.
                  body_html:
                    type: string
                    nullable: true
                    description: >-
                      Email only, sanitized at render; null when the provider
                      gave no HTML part. body_text stays the canonical copy.
                  approved_by_user_sid:
                    type: string
                    nullable: true
                    description: >-
                      The user who approved this draft; null on anything that
                      was never a draft.
                  agent_run_sid:
                    type: string
                    nullable: true
                    description: >-
                      The agent run that wrote this draft (ub_rn_…); null on
                      human and orchestration sends. regenerate_message needs
                      it.
                  ai_confidence:
                    type: number
                    nullable: true
                    description: >-
                      0..1 on agent drafts, the model self-score the approval
                      queue sorts and colors by; null otherwise.
                  ai_source:
                    type: string
                    nullable: true
                    description: >-
                      One free-text provenance line for a draft, max 255
                      ("Knowledge: security pack", "Behavior:
                      reschedule_meeting"), shown under the draft. Not a closed
                      vocabulary.
                  workflow_task_sid:
                    type: string
                    nullable: true
                    description: >-
                      The playtables workflow task that commanded this send
                      (wf_tk_…), and the dedup key for it; null on
                      inbox-authored rows.
                  automation_ref:
                    type: object
                    nullable: true
                    properties:
                      workflow_sid:
                        type: string
                        nullable: true
                        description: >-
                          The playtables workflow (wf_wf_..., external); null
                          when a play sent the row.
                      workflow_name:
                        type: string
                        nullable: true
                        description: >-
                          Display denorm, frozen when playtables reported the
                          send.
                      step_id:
                        type: integer
                        nullable: true
                        minimum: 0
                        exclusiveMinimum: true
                        description: The workflow step that sent it; null when a play did.
                      play_sid:
                        type: string
                        nullable: true
                        description: >-
                          The playtables play that sent the row (pt_pl_...,
                          external, 2026-10-14); null when a workflow did,
                          absent on rows frozen before.
                      play_name:
                        type: string
                        nullable: true
                        description: >-
                          Display denorm, frozen when playtables reported the
                          send.
                    required:
                      - workflow_sid
                      - workflow_name
                      - step_id
                    description: >-
                      The workflow and the step, or the play, that sent this
                      row, frozen when playtables reported the send (the
                      provenance line "Automation · {workflow} · step {n}", or
                      "Play · {play}"); null on anything no automation sent. The
                      conversation's own automation_ref says which automation
                      owns the lead now.
                  provider_message_sid:
                    type: string
                    nullable: true
                    description: >-
                      The gtm-api side reference (max 64), and the upsert key
                      for inbound and synced rows; null until the provider
                      accepts an outbound one.
                  author_participant_sid:
                    type: string
                    nullable: true
                    description: >-
                      On a group thread, the participant (ub_pt_...) who wrote
                      an inbound row (2026-09-24); null on a one-to-one thread
                      (the primary counterpart wrote it) and on every outbound
                      row (the sender profile did). Read the thread's
                      participants include to name them.
                  reactions:
                    type: array
                    nullable: true
                    items:
                      type: object
                      properties:
                        emoji:
                          type: string
                          description: The emoji, e.g. "👍" (max 32 chars).
                        count:
                          type: integer
                          minimum: 0
                          description: >-
                            Everyone who reacted with it, the sender profile
                            included.
                        is_viewer_reacted:
                          type: boolean
                          description: >-
                            True when the sender profile's own LinkedIn account
                            is among them: react_to_message with remove takes it
                            back.
                        first_reacted_at:
                          type: string
                          nullable: true
                          description: >-
                            ISO 8601 UTC, when the first of them reacted; null
                            when LinkedIn did not say.
                      required:
                        - emoji
                        - count
                        - is_viewer_reacted
                        - first_reacted_at
                    description: >-
                      Emoji reactions on a LinkedIn message, one summary per
                      emoji in the order LinkedIn reports them; the one fact on
                      a sent row that keeps moving (people react long after
                      arrival). Null on email rows, drafts and rows LinkedIn has
                      not served with reactions; [] = seen, none. The sender
                      profile's own reaction is the entry with
                      is_viewer_reacted; the counterpart's reaction reaches this
                      row with gtm-api's next sync of the account. Written by
                      react_to_message and by every re-read of the thread.
                  attachments:
                    type: array
                    nullable: true
                    items:
                      type: object
                      properties:
                        kind:
                          type: string
                          enum:
                            - voice
                            - audio
                            - image
                            - video
                            - gif
                            - file
                          description: >-
                            voice (a LinkedIn voice message), audio, image,
                            video, gif (from LinkedIn's library, never fetched)
                            or file.
                        state:
                          type: string
                          enum:
                            - pending
                            - stored
                            - failed
                            - skipped
                          description: >-
                            stored = GetSales holds it
                            (get_message_attachment_link opens it); pending = on
                            its way; failed or skipped = not held, reason says
                            why.
                        name:
                          type: string
                          nullable: true
                          description: >-
                            The file name as sent; null when the channel gave
                            none (a voice message, most images).
                        mime:
                          type: string
                          nullable: true
                          description: >-
                            The file type, e.g. application/pdf; null until
                            known.
                        size:
                          type: integer
                          nullable: true
                          minimum: 0
                          description: Bytes; null until known.
                        pages:
                          type: integer
                          nullable: true
                          minimum: 0
                          exclusiveMinimum: true
                          description: A stored PDF's page count; null otherwise.
                        is_inline:
                          type: boolean
                          description: >-
                            A mail's inline part (a signature logo, a picture in
                            the HTML): never fetched, never shown as a file.
                        provider_attachment_id:
                          type: string
                          nullable: true
                          description: gtm-api's id of a mail part; null on LinkedIn.
                        reason:
                          type: string
                          nullable: true
                          description: >-
                            Why it failed or was skipped, a token: history,
                            outbound, inline, gif, too_large, listed_late,
                            mailbox_unsupported, not_found, refused, unreadable,
                            unavailable, unsupported, retries_exhausted.
                        storage_key:
                          type: string
                          nullable: true
                          description: >-
                            The object's key in the private store, internal:
                            read the file through get_message_attachment_link.
                        transcript:
                          type: string
                          nullable: true
                          description: >-
                            A voice message's words as transcribed; empty when
                            nothing was said.
                        transcript_state:
                          type: string
                          nullable: true
                          enum:
                            - pending
                            - done
                            - failed
                          description: >-
                            A voice message's words: pending, done or failed;
                            null on every other kind.
                      required:
                        - kind
                        - state
                        - name
                        - mime
                        - size
                        - pages
                        - is_inline
                        - provider_attachment_id
                        - reason
                        - storage_key
                        - transcript
                        - transcript_state
                    description: >-
                      The files the message carried (a voice message, an image,
                      a PDF), in the provider's order, the index
                      get_message_attachment_link takes. Null when it carried
                      none or was read before files were kept (2026-10-18).
                  is_wordless:
                    type: boolean
                    description: >-
                      True when the person sent files and no words: body_text is
                      then GetSales' sentence naming them ("Sent a voice
                      message"), never their words. A voice message's words are
                      in attachments[].transcript.
                  failure_reason:
                    type: string
                    nullable: true
                    description: >-
                      Why the last dispatch failed, as a reason TOKEN (gtm-api's
                      own: browser_unreachable = the sender's browser is not
                      running, delay_not_elapsed = too soon after the last send
                      from this sender profile, gtm_unavailable = the sending
                      service did not answer, gtm_connection_revoked = the
                      workspace connection the sender lives in was revoked (a
                      workspace admin links it again), retries_exhausted = the
                      queue gave up, send_unconfirmed = the sending service's
                      answer to the send never came, it answered that its
                      browser could not tell whether the message went out, or
                      the hand-over was cut off, and in 15 minutes nothing
                      showed whether it left; or the code of a refusal such as
                      not_connected), never a sentence: relay it in your own
                      words. Set with state failed and kept when a person
                      cancels the row (cancel_messages), null on every other
                      state and on rows that failed before the token existed;
                      retry_messages clears it, and so does the provider's own
                      record of the send arriving later (the row turns sent).
                  scheduled_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC. Holds a queued row until then; null =
                      dispatch as soon as the per-sender-profile queue allows.
                  sent_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC, provider accept; null while
                      pending_approval, queued or failed.
                  delivered_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC, provider delivery confirmation (email; on
                      LinkedIn sent is as good as delivered).
                  opened_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC, FIRST open only (email tracking rollup);
                      per-tick history is not stored here.
                  clicked_at:
                    type: string
                    nullable: true
                    description: ISO 8601 UTC, FIRST click only.
                  bounced_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC, email only; set once by the engagement
                      ingest.
                  recalled_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC: when this sent LinkedIn message was deleted
                      for everyone (LinkedIn's recall, 2026-10-07), by a person
                      through delete_message_on_linkedin or by its author on
                      LinkedIn, which the next sync of the thread observes. The
                      state stays sent or delivered and body_text keeps the
                      words for the team, while the thread's members see that a
                      message was deleted: never quote it to the lead as
                      something they have, and never answer a deleted message of
                      theirs. Null = never deleted.
                  recalled_by_user_sid:
                    type: string
                    nullable: true
                    description: >-
                      The person who deleted it from GetSales; null when the
                      deletion was observed on LinkedIn.
                  person_edited_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC: when a person changed the agent's words
                      before approving the draft (2026-10-19, read since
                      2026-10-20); null when it went as the agent wrote it, and
                      on a row the agent never wrote. approved_by_user_sid names
                      the person who sent it.
                  created_at:
                    type: string
                    description: >-
                      ISO 8601 UTC. For a synced row this is the PROVIDER
                      timestamp, so thread order survives a backfill; it is also
                      the default sort.
                  updated_at:
                    type: string
                    description: ISO 8601 UTC.
                  deleted_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC. Reserved: nothing writes it in v1 (a
                      dismissed draft is state canceled, a sent message is never
                      removed), so it is always null.
                required:
                  - sid
                  - team_sid
                  - conversation_sid
                  - channel
                  - kind
                  - direction
                  - state
                  - origin
                  - body_text
                  - author
                  - subject
                  - body_html
                  - approved_by_user_sid
                  - agent_run_sid
                  - ai_confidence
                  - ai_source
                  - workflow_task_sid
                  - automation_ref
                  - provider_message_sid
                  - author_participant_sid
                  - reactions
                  - attachments
                  - is_wordless
                  - failure_reason
                  - scheduled_at
                  - sent_at
                  - delivered_at
                  - opened_at
                  - clicked_at
                  - bounced_at
                  - recalled_at
                  - recalled_by_user_sid
                  - person_edited_at
                  - created_at
                  - updated_at
                  - deleted_at
              included:
                type: object
                properties:
                  conversation:
                    type: object
                    properties:
                      sid:
                        type: string
                        description: Thread sid (ub_cv_…).
                    required:
                      - sid
                    description: >-
                      The owning thread (ConversationDomain, 1:1) - see
                      ./conversations.md.
            required:
              - item
              - included
        pagination:
          type: object
          properties:
            next_cursor:
              type: string
              nullable: true
            has_more:
              type: boolean
            total_count:
              type: integer
              nullable: true
          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
              nullable: true
              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
              nullable: true
              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: integer
              minimum: 0
              description: Messages matching the filter (full filter scope, not the page).
            groups:
              type: object
              properties:
                state:
                  anyOf:
                    - type: object
                      properties:
                        pending_approval:
                          type: integer
                          minimum: 0
                        queued:
                          type: integer
                          minimum: 0
                        sent:
                          type: integer
                          minimum: 0
                        delivered:
                          type: integer
                          minimum: 0
                        failed:
                          type: integer
                          minimum: 0
                        canceled:
                          type: integer
                          minimum: 0
                    - type: array
                      items: {}
                  description: >-
                    groups.state.pending_approval is the approval-queue badge;
                    absent key = zero.
                channel:
                  anyOf:
                    - type: object
                      properties:
                        linkedin:
                          type: integer
                          minimum: 0
                        email:
                          type: integer
                          minimum: 0
                    - type: array
                      items: {}
                  description: Volume split across the two channels; absent key = zero.
                author:
                  anyOf:
                    - type: object
                      properties:
                        contact:
                          type: integer
                          minimum: 0
                        user:
                          type: integer
                          minimum: 0
                        agent:
                          type: integer
                          minimum: 0
                    - type: array
                      items: {}
                  description: 'Who wrote what: the AI-disclosure split; absent key = zero.'
              required:
                - state
                - channel
                - author
          required:
            - total_count
            - groups
      required:
        - success
        - operation
        - items
        - pagination
        - applied_filters
        - includes
        - 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
                    nullable: true
                  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
              nullable: true
              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
              nullable: true
              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
  responses:
    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'
    McpServerError:
      description: >-
        MCP error envelope with `error.code` internal_error or
        service_unavailable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/McpError'
  securitySchemes:
    BearerJwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Access token issued by gs.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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.