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

# Publish an agent

> Put an agent's draft live as a new version, the same as Publish in Studio

> [!WARNING]
>
> **A publish puts the whole draft live, not only the guidelines.** Any unpublished change made in Studio goes live with it. If other people edit the agent, check **Review Changes** in Studio, or `needs_publish` from [Get guidelines](https://docs.squawkvoice.ai/api-reference/agents/get-guidelines.md), before you publish.

## Update and Publish Guidelines

**1. Replace the guidelines**

Send the new text with [Replace guidelines](https://docs.squawkvoice.ai/api-reference/agents/replace-guidelines.md). It saves to the draft.

**2. Publish**

Call this endpoint. It answers `202` straight away with the new version's `version_id` and number, and a `poll_url`.

**3. Wait for it to finish**

Call the `poll_url` every few seconds until `status` is `published` or `failed`. A publish that makes no progress for about 15 minutes is ended and reads `failed`. See [Get publish status](https://docs.squawkvoice.ai/api-reference/agents/get-publish-status.md).

**4. Check what's live**

Once it is `published`, new phone calls, website chats and emails use the new version, and each of them records its `version_id` in `interaction.AGENT_VERSION_ID`. [Get live version](https://docs.squawkvoice.ai/api-reference/agents/get-live-version.md) tells you which version is live.

* **Nothing to publish.** If the draft is the same as the live version, you get a `400` naming the live version, and no version is created.
* **One publish at a time.** A publish started while another is running gets a `409` with the running one's `poll_url`. Wait for that publish to finish, then call this endpoint again: a publish includes only what was saved before it started, so a change saved while it ran is still waiting. If nothing is left to publish, you get the `400`.
* **A failed publish changes nothing.** What was live stays live, the new version is never created and its number is skipped.
* **It's recorded.** The publish appears in [Audit Logs](https://docs.squawkvoice.ai/manage/audit-logs.md#publishes) with the key's creator as the **Actor**, and the new version appears in [Version History](https://docs.squawkvoice.ai/build/ai-agents.md#version-history) in Studio.
* **Going back is in Studio.** To put an earlier version live again, use [Make this version active](https://docs.squawkvoice.ai/build/ai-agents.md#make-an-earlier-version-live) in Studio.


## OpenAPI

````yaml api-reference/openapi.yaml POST /api/v1/assistants/{assistantId}/publish
openapi: 3.1.0
info:
  title: SquawkVoice API
  version: '1.0'
  description: >-
    Place on-demand campaign calls, and manage and publish an agent's
    guidelines, from your own systems. Every request is authenticated with an
    API key sent in the `X-API-Key` header.
servers:
  - url: https://api.squawkvoice.ai
security:
  - apiKey: []
tags:
  - name: on-demand-calls
    x-group: On-Demand Calls
    description: Place a campaign call for one contact, and cancel it before it is dialed.
  - name: agents
    x-group: Agents
    description: >-
      Read and replace an agent's guidelines, publish the agent, and see which
      version is live.
paths:
  /api/v1/assistants/{assistantId}/publish:
    post:
      tags:
        - agents
      summary: Publish an agent
      description: >-
        Starts a publish of the agent's draft, the same publish as **Publish**
        in Studio. It puts the whole draft live, not only the guidelines, and
        creates the next numbered version. The publish runs in the background:
        the response names the version it will create and a `poll_url` to follow
        it with [Get publish status](/api-reference/agents/get-publish-status).
      operationId: publishAgent
      parameters:
        - $ref: '#/components/parameters/assistantId'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                version_name:
                  type:
                    - string
                    - 'null'
                  maxLength: 120
                  description: >-
                    A name for the version this publish creates, shown in
                    **Version History**, up to 120 characters once spaces at the
                    start and end are removed. Leave it out, or send `null`, an
                    empty string or only spaces, and Studio shows **Version N**.
                    This is the only field accepted; any other field returns a
                    `400`.
            example:
              version_name: November pricing update
      responses:
        '202':
          description: The publish started.
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    const: true
                  data:
                    type: object
                    required:
                      - job_id
                      - poll_url
                      - status
                      - version
                    properties:
                      job_id:
                        type: string
                        format: uuid
                        description: The publish's ID.
                      poll_url:
                        type: string
                        format: uri
                        description: >-
                          The full URL of [Get publish
                          status](/api-reference/agents/get-publish-status) for
                          this publish. Call it as it is, with the same API key.
                      status:
                        type: string
                        const: publishing
                        description: Always `publishing` here.
                      version:
                        $ref: '#/components/schemas/PublishVersion'
              example:
                success: true
                data:
                  job_id: 0c4f8e2a-6b1d-4a39-9e57-2f8d1c3b6a90
                  poll_url: >-
                    https://api.squawkvoice.ai/api/v1/assistants/3c7e1a52-8d4f-4b9a-a0e6-5f2d9c8b1e74/publish-jobs/0c4f8e2a-6b1d-4a39-9e57-2f8d1c3b6a90
                  status: publishing
                  version:
                    version_id: a71d3e95-2c8b-4f04-8d6a-9b1e5c7f2d38
                    version_number: 4
                    name: November pricing update
        '400':
          description: >-
            Nothing to publish, because the draft is the same as the live
            version (`data.live_version` names it), or the body is invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                noChanges:
                  summary: Nothing to publish
                  value:
                    success: false
                    error: No changes to publish
                    data:
                      live_version:
                        version_id: 5e0b9c41-7a2d-4f6e-b8c3-1d9a0e4f7b62
                        version_number: 3
                        name: null
                        published_at: '2026-10-29T14:02:11.000Z'
                        activated_at: null
                invalidBody:
                  summary: Unknown field
                  value:
                    success: false
                    error: Invalid request body
                    details: 'Unknown field(s): name. Only "version_name" can be set.'
                nameTooLong:
                  summary: Name too long
                  value:
                    success: false
                    error: Invalid request body
                    details: version_name must be at most 120 characters
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AgentForbidden'
        '404':
          $ref: '#/components/responses/AgentNotFound'
        '409':
          description: >-
            A publish of this agent is already running. `data` names it, when it
            can, so you can follow it instead.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: A publish is already running for this assistant
                data:
                  job_id: 0c4f8e2a-6b1d-4a39-9e57-2f8d1c3b6a90
                  poll_url: >-
                    https://api.squawkvoice.ai/api/v1/assistants/3c7e1a52-8d4f-4b9a-a0e6-5f2d9c8b1e74/publish-jobs/0c4f8e2a-6b1d-4a39-9e57-2f8d1c3b6a90
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  parameters:
    assistantId:
      name: assistantId
      in: path
      required: true
      description: >-
        The agent's ID. Open the agent in Studio and select **Copy ID** in its
        header.
      schema:
        type: string
        format: uuid
  schemas:
    PublishVersion:
      type: object
      description: The version a publish creates.
      required:
        - version_id
        - version_number
        - name
      properties:
        version_id:
          type: string
          format: uuid
          description: >-
            The new version's ID, known from the start. Wait for the publish's
            `status` to be `published` before you rely on it: a failed publish
            never creates it.
        version_number:
          type: integer
          description: >-
            The new version's number. A failed publish leaves its number unused,
            so numbers can skip.
        name:
          type:
            - string
            - 'null'
          description: The `version_name` you sent, or `null`.
    Error:
      type: object
      description: >-
        Most errors have `success: false` and a readable `error`. Some agent
        errors and rate-limit errors carry `message` instead.
      properties:
        success:
          type: boolean
          const: false
        error:
          type: string
          description: What went wrong.
        details:
          description: More detail, when there is any.
        message:
          type: string
          description: What went wrong, on errors that don't use `error`.
        data:
          type: object
          description: >-
            Extra detail on a few errors, such as the live version when there is
            nothing to publish, or the running publish on a `409`.
  responses:
    Unauthorized:
      description: >-
        The API key is missing, unknown, revoked or expired. The reply is the
        same in every case.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            success: false
            error: 'Unauthorized: Invalid credentials'
    AgentForbidden:
      description: The agent isn't in your account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: 'Forbidden: Workspace does not belong to your account.'
    AgentNotFound:
      description: Agent not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: Assistant not found.
    TooManyRequests:
      description: >-
        Too many requests. Wait for the number of seconds in the `Retry-After`
        header, then retry.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                const: error
              message:
                type: string
          example:
            status: error
            message: Too many requests, please try again later.
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        An API key from **Manage → API Keys** in Studio. See
        [Authentication](/api-reference/authentication).

````

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