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

# Delete a version

> Remove a draft or an old published version.

```http theme={"dark"}
DELETE /v1/agents/ag_7f3.../versions/4
```

`204`, no body.

<Warning>
  **Two versions cannot be deleted**, and both answer `409` rather than failing silently:

  * **The live one.** Take the agent off air with
    [`DELETE /v1/agents/{agent_id}/live`](/developers/agents/off-air) first, or make a different
    version live — deleting the version answering your calls would drop them.
  * **One an unfinished batch is pinned to.** A running batch holds the exact configuration it
    started with, so the version outlives the delete until the batch finishes.
</Warning>

Numbers are allocated `max + 1` across drafts and published versions alike, so **gaps are normal** —
a discarded draft leaves its number spent. The one case where a number comes back is deleting the
*highest* version: delete V4 when V4 is the newest and the next draft is V4 again. If you record
version numbers on your side, record them against the agent's state at the time, not as permanent
identifiers.


## OpenAPI

````yaml developers/openapi.json DELETE /v1/agents/{agent_id}/versions/{version_id}
openapi: 3.1.0
info:
  title: Vocily API
  description: >-
    Public REST API for Vocily. Build and configure an agent, publish a version
    and put it live, place outbound calls, and read back calls, chats and what
    the agent remembered. Authenticate with a workspace API key as a Bearer
    token.


    Some things stay in the dashboard, by design: creating an API key, buying or
    connecting a phone number, setting an agent's webhook URL, connecting
    WhatsApp and its templates, building HTTP tools, and running batch
    campaigns.
  version: v1
servers:
  - url: https://api.vocily.ai
    description: Production
security: []
paths:
  /v1/agents/{agent_id}/versions/{version_id}:
    delete:
      tags:
        - agent-versions
      summary: Delete Version
      description: Delete any version except the live one, or one an unfinished batch pins.
      operationId: delete_version_v1_agents__agent_id__versions__version_id__delete
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            title: Agent Id
          description: The agent's id, as `GET /v1/agents` returns it.
        - name: version_id
          in: path
          required: true
          schema:
            type: string
            title: Version Id
          description: >-
            A version **number** (`0`, `1`, `3`) or a version uuid — both
            resolve. Prefer the number: it is the version's identity to you, it
            is what every version read returns, and it needs no lookup first.
      responses:
        '204':
          description: Successful Response
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                detail: Invalid API key
                code: UNAUTHORIZED
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded — honor `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                code: rate_limited
      security:
        - bearerAuth: []
components:
  schemas:
    ApiError:
      type: object
      description: >-
        Error envelope. `code` is derived from the HTTP status, so branch on it
        for the CLASS of failure; the specific reason is `detail.code`. Every
        public refusal carries both.
      properties:
        detail:
          type: object
          description: >-
            The reason. `code` is the domain reason (e.g. `call_not_found`) and
            `message` is a sentence safe to log. On a `422` it also carries
            `errors[]`, one entry per rejected field — see
            `HTTPValidationError`.
          properties:
            code:
              type: string
              example: call_not_found
            message:
              type: string
              example: Call not found
          required:
            - code
            - message
        code:
          type: string
          description: Derived from the HTTP status, not the domain reason.
          example: NOT_FOUND
    HTTPValidationError:
      type: object
      title: HTTPValidationError
      description: >-
        A request the API could not read: a field of the wrong type, out of
        range, missing, or one we do not accept. Same envelope as every other
        error.
      properties:
        detail:
          type: object
          description: >-
            What was wrong, as `code`, a one-line `message`, and every offending
            field in `errors`.
          required:
            - code
            - message
            - errors
          properties:
            code:
              type: string
              enum:
                - validation_error
            message:
              type: string
              description: >-
                The first problem in one line, with a count of the rest — e.g.
                `model.temperature: Input should be less than or equal to 2 (and
                1 more)`.
            errors:
              type: array
              items:
                $ref: '#/components/schemas/ValidationError'
              description: >-
                One entry per offending field. **Every problem is reported at
                once**, not just the first, so a malformed body needs one round
                trip to fix rather than one per field.
        code:
          type: string
          enum:
            - VALIDATION_ERROR
          description: Derived from the HTTP status, as on every error.
    ValidationError:
      type: object
      title: ValidationError
      required:
        - field
        - message
        - type
      properties:
        field:
          type: string
          description: >-
            The offending field as a path from the root of your request —
            `voice.speed`, `variables[0].key`, or `query.limit` for a query
            parameter. **This is the field to read.**
        message:
          type: string
          description: What is wrong with it, in plain language.
        type:
          type: string
          description: >-
            A stable machine code for the kind of failure, e.g.
            `extra_forbidden` for a field we do not accept, `missing` for a
            required one, or `less_than_equal` for a number out of range. Switch
            on this rather than on `message`, which may be reworded.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Your API key as a Bearer token, e.g. `Authorization: Bearer vk_…`.'

````