> ## 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.

# Create agent plan

> Commit the plan a strategize run produced for one thread: steps [{kind, params}] in order, 1..8, a message step's params carrying its text, each kind's payload in the params describe. ACCESS: the agent-extended toolset only; a user or public token is 403 forbidden (agent_toolset_only); a human approves or edits one with update_agent_plan.

It supersedes the plan the thread held and points the thread at this one, in one transaction; the agent's unsent messages there are withdrawn (the plan carries its own). Ids and step states are server-assigned. The requested state is a ceiling: under copilot the plan lands proposed, every step parked for approval. A run commits one plan: a second create by the same run answers 200 already_exists with the plan it made. A turn whose run no longer stands commits nothing (the lead wrote again, or the run was settled): 409 plan_turn_superseded, end the turn.

Steps are frozen here, texts included: each executes with no further LLM call, and a send_message step sends its text as written through the send door under the plan's approval (422 rule required without one). Write the reply; when a reply is expected end with a wait_for_reply, the follow-up with its own text, and a last wait_for_reply. A stage move sets the linked person to the outcome stage the step names; a people search starts a credit-billed search at that person's company; on a thread linked to no person both are skipped when due.

Contract:
- MCP tool `create_agent_plan`, registry package `mcp.unibox/agent_plans`, mount `unibox.agent`.
- Operation `create`, response envelope `create`.
- Flags: none.



## OpenAPI

````yaml /api-reference/unibox/openapi.yaml post /api/agent-plans
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/agent-plans:
    post:
      tags:
        - agent_plans
      summary: Create agent plan
      description: >-
        Commit the plan a strategize run produced for one thread: steps [{kind,
        params}] in order, 1..8, a message step's params carrying its text, each
        kind's payload in the params describe. ACCESS: the agent-extended
        toolset only; a user or public token is 403 forbidden
        (agent_toolset_only); a human approves or edits one with
        update_agent_plan.


        It supersedes the plan the thread held and points the thread at this
        one, in one transaction; the agent's unsent messages there are withdrawn
        (the plan carries its own). Ids and step states are server-assigned. The
        requested state is a ceiling: under copilot the plan lands proposed,
        every step parked for approval. A run commits one plan: a second create
        by the same run answers 200 already_exists with the plan it made. A turn
        whose run no longer stands commits nothing (the lead wrote again, or the
        run was settled): 409 plan_turn_superseded, end the turn.


        Steps are frozen here, texts included: each executes with no further LLM
        call, and a send_message step sends its text as written through the send
        door under the plan's approval (422 rule required without one). Write
        the reply; when a reply is expected end with a wait_for_reply, the
        follow-up with its own text, and a last wait_for_reply. A stage move
        sets the linked person to the outcome stage the step names; a people
        search starts a credit-billed search at that person's company; on a
        thread linked to no person both are skipped when due.


        Contract:

        - MCP tool `create_agent_plan`, registry package
        `mcp.unibox/agent_plans`, mount `unibox.agent`.

        - Operation `create`, response envelope `create`.

        - Flags: none.
      operationId: create_agent_plan
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAgentPlanRequest'
      responses:
        '200':
          description: '`create` success envelope.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateAgentPlanResponse'
        4XX:
          $ref: '#/components/responses/McpClientError'
        5XX:
          $ref: '#/components/responses/McpServerError'
components:
  schemas:
    CreateAgentPlanRequest:
      type: object
      description: Request body of `create_agent_plan`.
      properties:
        conversation_sid:
          type: string
          minLength: 18
          maxLength: 18
          pattern: ^ub_cv_
          description: >-
            The thread being planned for. Its previous live plan is superseded
            in the same transaction and conversations.active_plan_sid is
            re-pointed here.
        goal:
          type: string
          minLength: 1
          maxLength: 255
          description: >-
            The plan's intent in one human-readable line, 1..255 chars. It is
            what the thread and the context panel render.
        state:
          type: string
          enum:
            - proposed
            - active
          description: >-
            Default proposed. The mode gate is server-side, so a plan asked for
            as active under copilot is still parked for approval, and a
            post-goal plan, or one that carries a reach_objective step, is
            floored to proposed whatever is sent.
        behavior:
          type: string
          nullable: true
          enum:
            - answer_interested
            - meeting_request_book
            - answer_info_request
            - referral_capture
            - not_now_defer
            - ooo_delay_ping
            - auto_reply_skip
            - wrong_person_referral
            - reschedule_meeting
            - cancel_meeting
            - return_to_orchestration
            - close_not_interested
            - handle_objection
            - stoplist_do_not_contact
            - vendor_pitch_skip
            - acknowledge_low_signal
            - followup_no_reply
            - signal_followup
            - followup_after_person
          description: >-
            The built-in competence module that planned; null when a matched
            custom scenario drove the plan on its own.
        behavior_version:
          type: integer
          nullable: true
          minimum: 1
          description: >-
            Version of that module, taken from its manifest. Stamped for audit,
            never interpreted.
        custom_scenario_sid:
          type: string
          nullable: true
          minLength: 18
          maxLength: 18
          pattern: ^ub_sc_
          description: The custom scenario (ub_sc_…) that matched this reply, when one did.
        run_sid:
          type: string
          minLength: 18
          maxLength: 18
          pattern: ^ub_rn_
          description: >-
            The strategize run committing this plan (ub_rn_…). It is the audit
            anchor: the plan is later explained through this run.
        steps:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                enum:
                  - send_message
                  - wait_until
                  - wait_for_reply
                  - create_task
                  - move_stage
                  - find_people
                  - react
                  - like_post
                  - reach_objective
                  - resume_orchestration
                  - stoplist_person
                  - use_playbook
                description: >-
                  What this step should do. Validated against the behavior
                  module's allowed kinds.
              params:
                type: object
                nullable: true
                additionalProperties: {}
                description: >-
                  The step payload, frozen here; omit or send {} where the kind
                  takes nothing. send_message {intent, text, subject}: intent is
                  the message's direction in a sentence; text is required and
                  sent as written (422 on steps.N.params.text: rule required,
                  max 8000, reveals_tracking for a text telling the lead what
                  our tracking saw); subject is an email's, optional, max 998;
                  the approval approves the text, no draft round. A message step
                  passes the playbook's purpose, link and length through (each
                  from its dictionary, 422 rule in); with link always the text
                  must carry the goal's link (rule booking_link_missing; a
                  thread with no link is 422 on params.link, rule
                  no_booking_link). wait_until {until, reason}; wait_for_reply
                  {timeout_days}. create_task {title, due_in_days}. move_stage
                  {target_stage_key}: required, one of soft_interest,
                  strong_interest, meeting_requested, meeting_scheduled,
                  closed_won, wrong_decision_maker, not_now, unresponsive,
                  not_interested, disqualified (422 rules required, in).
                  find_people {prompt (1..2000), per_company_limit (1..25,
                  default 5)}: company_sid, company_name and estimated_credits
                  are the server's stamp; 422 on steps.N.kind (not_linked,
                  no_company, no_company_anchor, person_not_found,
                  playtables_unavailable) when the search cannot run or price.
                  react {emoji (one emoji, rules required, max), message_sid? (a
                  LinkedIn message of theirs here, rule message_not_reactable;
                  absent = their newest; no_message when they have none)}.
                  like_post {} (not_on_linkedin on a thread with no LinkedIn
                  account, no_linkedin_profile when the lead has none).
                  reach_objective {} (rules no_dialog,
                  objective_already_reached). resume_orchestration {reason};
                  stoplist_person {}. use_playbook {from}: the stage the
                  Playbook enters the dialog at, one of engage, discover,
                  bridge, offer, after_yes (422 rule in; discover when none is
                  named); once per plan (422 on steps.N.kind, rule
                  playbook_twice); from it the Playbook's turns write the
                  replies, the plan none.
            required:
              - kind
          minItems: 1
          maxItems: 8
          description: >-
            The ordered steps, 1 to 8. Ids and step states are assigned
            server-side; a plan born proposed parks every step as
            awaiting_approval.
      required:
        - conversation_sid
        - goal
        - run_sid
        - steps
    CreateAgentPlanResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        operation:
          type: string
          enum:
            - create
        item:
          type: object
          properties:
            sid:
              type: string
              description: Agent plan sid (ub_pl_…).
            team_sid:
              type: string
              description: Owning team (ts_tm_…, external - gs.service.id).
            agent_sid:
              type: string
              nullable: true
              description: >-
                The AI SDR the plan was made by (ub_ag_…, block 10, 2026-10-30);
                null on a row from before.
            conversation_sid:
              type: string
              description: >-
                The thread this plan belongs to (ub_cv_…). At most one plan per
                thread is live (proposed or active).
            state:
              type: string
              enum:
                - proposed
                - active
                - completed
                - superseded
                - canceled
              description: >-
                proposed = waiting for one-click approval, no step runs; active
                = executing or waiting on a timer; completed / superseded /
                canceled are terminal.
            goal:
              type: string
              description: >-
                Human-readable intent of the plan, 1..255 chars, e.g. "Re-engage
                after OOO on Aug 5".
            steps:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: integer
                    minimum: 1
                    description: >-
                      Plan-local step id, stable across edits. Assigned by the
                      server, counting from 1.
                  kind:
                    type: string
                    enum:
                      - send_message
                      - wait_until
                      - wait_for_reply
                      - create_task
                      - move_stage
                      - find_people
                      - react
                      - like_post
                      - reach_objective
                      - resume_orchestration
                      - stoplist_person
                      - use_playbook
                    description: What the step does.
                  params:
                    anyOf:
                      - type: object
                        additionalProperties: {}
                      - type: array
                        items: {}
                    description: >-
                      The step payload, frozen at planning time. Per kind:
                      send_message { intent, text, subject }, the message's
                      direction and, since 2026-10-05, its text exactly as it
                      goes out (an email's subject when it needs one): approving
                      the plan approves the text and the step sends it as
                      written, while a step with no text has its message written
                      when it comes due; wait_until { until, reason };
                      wait_for_reply { timeout_days, until }, until stamped by
                      the server when the wait begins; a message step also
                      carries the playbook's three product parameters since
                      2026-10-12, purpose (reply, follow_up, nudge, closing,
                      holding), link (none, when_natural, always: the text
                      carries the effective booking link, the campaign's or the
                      table's AI SDR setup over the team's) and length (short,
                      normal, full_picture), and the booking link is a
                      send_message with link always, the booking-link kind
                      retired and its stored plans rewritten; create_task {
                      title, due_in_days }; move_stage { target_stage_key }, one
                      of soft_interest, strong_interest, meeting_requested,
                      meeting_scheduled, closed_won, wrong_decision_maker,
                      not_now, unresponsive, not_interested, disqualified;
                      find_people { prompt, per_company_limit, company_sid,
                      company_name, estimated_credits }, where the last three
                      are stamped by the server (the company the search runs on
                      and the credits it is expected to spend; a step the CRM
                      could not price is refused, never stored); react { emoji,
                      message_sid }, the sender profile's reaction on the
                      LinkedIn message of theirs the step names (their newest
                      when the writer named none): the agent plans it on the
                      lead's first reply and when the stage move takes them
                      forward in the pipeline, and on a later reply only when
                      the lead made an effort in it (the heart on a warm reply,
                      a thumbs-up on any other; never on an automatic reply or a
                      do-not-contact); like_post {}, the sender profile's Like
                      on the lead's own latest LinkedIn post, picked when the
                      step runs (no plain repost, at most 90 days old, never one
                      the account liked already); reach_objective {}, the mark
                      of the live dialog's objective, run once the plan is
                      approved; resume_orchestration { reason }; stoplist_person
                      {}; use_playbook { from, outcome }, the stage the Playbook
                      starts the dialog at (engage, discover, bridge, offer,
                      after_yes; 2026-10-19) and, once the step is done, how the
                      Playbook's lead ended (said_yes, booked, signed_up,
                      registered, stalled_out, handed, left, cap).
                  state:
                    type: string
                    enum:
                      - pending
                      - awaiting_approval
                      - waiting
                      - done
                      - skipped
                      - failed
                    description: Where this step stands.
                  executed_at:
                    type: string
                    nullable: true
                    description: >-
                      ISO 8601 UTC, stamped when the step reached a terminal
                      state; null before that.
                  cause:
                    type: string
                    nullable: true
                    description: >-
                      Why the step was skipped or failed, or what a pending step
                      waits for, as a reason token (snake_case, 64 chars at
                      most, never a sentence: say it in your own words); null on
                      a step in any other state, and on one that ended before
                      2026-10-02. A pending step carries one only while the turn
                      that writes its message is held because the message could
                      not leave now: sender_unavailable (no sender profile
                      carries the account, or the account is signed out,
                      disconnected, stopped or paused; nothing is lost, the step
                      runs by itself once the account can send, so point the
                      user at the sender profile; after seven days of waiting
                      the step fails under the same token),
                      subscription_required (the workspace is on the billing
                      hold). A skipped step: not_linked (the thread is linked to
                      no person: move_stage, find_people, resume_orchestration);
                      already_beyond, stage_unknown, person_gone,
                      playtables_refused, target_stage_key_unknown (move_stage:
                      the person already stands further along the pipeline than
                      the stage and the agent never moves a person back, the
                      team has no stage under the key, the person is gone from
                      the CRM, the CRM refused, the step names no outcome
                      stage); no_company, no_company_anchor, person_not_found,
                      prompt_missing (find_people); sender_unavailable,
                      message_not_reactable, linkedin_refused, gtm_unavailable,
                      gtm_bridge_unavailable, gtm_busy, step_job_failed (react:
                      the account cannot act, the message takes no reaction,
                      LinkedIn said no, gtm-api did not answer or stayed busy,
                      the job that runs the reaction died; a reaction never
                      fails, whatever keeps it from landing is a skip and the
                      plan goes on); no_recent_post, already_liked,
                      not_on_linkedin, no_linkedin_profile, post_not_likeable,
                      gtm_scope_missing, gtm_access_lost, and, as for a
                      reaction, sender_unavailable, linkedin_refused,
                      gtm_unavailable, gtm_busy, step_job_failed (like_post: the
                      lead shows the account no recent post of their own (a
                      plain repost or a post older than 90 days does not count),
                      the account liked their latest post already, the thread
                      runs on no LinkedIn account, the lead has no profile the
                      account can open, LinkedIn takes no Like on the post, the
                      workspace connection lacks the engagements permission or
                      no longer shows the account; a Like never fails either, it
                      is skipped and the plan goes on); no_booking_link
                      (send_booking_link: the team lost its link after
                      planning); no_dialog, objective_already_reached
                      (reach_objective); no_step_transport (stoplist_person: the
                      block itself was applied when the reply was read). A
                      failed step carries the error code of the run that died on
                      it: playtables_unreachable (the CRM did not answer through
                      three tries), no_message_sent (the turn wrote no message),
                      turn_timeout, budget_exceeded, runner_error; or the reason
                      the send door refused the step's message with: stoplisted,
                      agent_disabled_on_thread (refused for good, the turn is
                      not tried again), send_refused (the door named no reason,
                      usually the thread has no account on the channel),
                      sender_unavailable or subscription_required (the step
                      waited for its sender for seven days, or the account
                      dropped on each of three tries). unknown stands for a
                      cause that was not a token. The list is open: read a token
                      you do not know as "it could not run".
                required:
                  - id
                  - kind
                  - params
                  - state
                  - executed_at
                  - cause
              description: >-
                Ordered steps, 1..8. They run in order; a failed one stops the
                plan.
            created_by_run_sid:
              type: string
              description: >-
                The strategize run that produced this plan (ub_rn_…). Its
                reason, confidence and LLM log ref answer "why this plan".
            behavior:
              type: string
              nullable: true
              enum:
                - answer_interested
                - meeting_request_book
                - answer_info_request
                - referral_capture
                - not_now_defer
                - ooo_delay_ping
                - auto_reply_skip
                - wrong_person_referral
                - reschedule_meeting
                - cancel_meeting
                - return_to_orchestration
                - close_not_interested
                - handle_objection
                - stoplist_do_not_contact
                - vendor_pitch_skip
                - acknowledge_low_signal
                - followup_no_reply
                - signal_followup
                - followup_after_person
              description: >-
                The built-in competence module that planned; null when a matched
                custom scenario drove the plan on its own.
            behavior_version:
              type: integer
              nullable: true
              minimum: 1
              description: >-
                Version of that module at planning time (the audit stamp,
                rendered as "answer_interested v3"); null when behavior is null.
            custom_scenario_sid:
              type: string
              nullable: true
              description: >-
                The custom scenario that matched (ub_sc_…), which takes
                precedence over the built-in behavior; null when none did. The
                sid survives the scenario being deleted.
            approved_by_user_sid:
              type: string
              nullable: true
              description: >-
                User that approved a proposed plan; null while unapproved or
                when the plan was born active under autopilot.
            created_at:
              type: string
              description: ISO 8601 UTC.
            updated_at:
              type: string
              description: ISO 8601 UTC.
            deleted_at:
              type: string
              nullable: true
              description: >-
                ISO 8601 UTC. Always null in practice: plans have no delete
                path, the terminal states cover removal.
          required:
            - sid
            - team_sid
            - agent_sid
            - conversation_sid
            - state
            - goal
            - steps
            - created_by_run_sid
            - behavior
            - behavior_version
            - custom_scenario_sid
            - approved_by_user_sid
            - created_at
            - updated_at
            - deleted_at
        already_exists:
          type: boolean
        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
        - operation
        - item
        - already_exists
        - 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.