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

# Upload a file

> Add a file your agents can send to customers.

A multipart form with `file`, plus an optional `name` and `description`. The name defaults to
the filename.

The **label** is generated for you: the filename slugified, plus a short random suffix —
`Autumn Brochure 2026.pdf` becomes `autumn-brochure-2026_7bq2xk`. It is unique in the workspace
and never changes, so a prompt pointing at it always resolves to the same bytes.

> [!NOTE]
>
> **The response's `label` is the point.** Paste it into an agent's prompt — for example
> `When a customer asks for the brochure, send autumn-brochure_7bq2xk.` — and that agent can
> send that file. An agent can only send files its own prompt names.

**The file's type is read from its contents**, not from its name or the content type you declare.
A file whose real type cannot be delivered on WhatsApp is refused here, rather than stored and
found undeliverable later with a customer waiting. Call
[File limits](https://docs.vocily.ai/developers/files/limits.md) for the accepted list.

Every upload is scanned for malware before it is stored. A file that fails the scan is refused
and its contents are never kept.


## OpenAPI

````yaml developers/openapi.json POST /v1/files
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/files:
    post:
      tags:
        - files
      summary: Upload File
      description: >-
        Add a file your agents can send to customers.


        A multipart form with `file`, plus an optional `label` and
        `description`. The label defaults to the filename.


        The response carries a **handle**. Paste it into an agent's prompt — for
        example `When a customer asks for the brochure, send file_7bq2xk.` — and
        that agent can send that file. An agent can only send files its own
        prompt names.


        The file's type is read from its contents, not from its name or the
        content type you declare, so a file that cannot be delivered on WhatsApp
        is refused here rather than stored and found undeliverable later. Every
        upload is scanned for malware before it is stored.
      operationId: upload_file_v1_files_post
      parameters: []
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicFile'
              example:
                label: autumn-brochure_7bq2xk
                id: 00000001-0000-4000-8000-000000000001
                name: Autumn brochure
                description: Two-page product brochure, updated October.
                filename: autumn-brochure.pdf
                mime_type: application/pdf
                kind: document
                size_bytes: 184320
                status: ready
                created_at: '2026-10-16T09:14:02Z'
        '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:
    PublicFile:
      properties:
        label:
          type: string
          title: Label
          description: >-
            Identifier for this file: its filename slugified, plus a short
            random suffix. Paste it into an agent's prompt to let that agent
            send the file. It never changes.
          examples:
            - autumn-brochure_7bq2xk
        id:
          type: string
          title: Id
          description: >-
            The file's unique id. Either this or the label works wherever a path
            takes a file reference.
        name:
          type: string
          title: Name
          description: What the file is called in your library. Editable; the label is not.
          examples:
            - Autumn brochure
        description:
          type: string
          title: Description
          description: >-
            Your note about what the file is for. Agents read it when choosing
            which file to send.
          default: ''
        filename:
          type: string
          title: Filename
          description: >-
            The file's original name. This is the document name the recipient
            sees on WhatsApp.
          default: ''
          examples:
            - autumn-brochure.pdf
        mime_type:
          type: string
          title: Mime Type
          description: The file's type, read from its contents rather than its name.
          examples:
            - application/pdf
        kind:
          type: string
          title: Kind
          description: One of `image`, `video`, `audio` or `document`.
          examples:
            - document
        size_bytes:
          type: integer
          title: Size Bytes
          description: The file's size in bytes.
          examples:
            - 184320
        status:
          type: string
          title: Status
          description: >-
            `ready` when the file can be sent. A file that failed its malware
            scan is `quarantined` and holds no contents; a deleted file is
            `deleted`.
          examples:
            - ready
        created_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Created At
          description: When the file was uploaded.
      type: object
      required:
        - label
        - id
        - name
        - mime_type
        - kind
        - size_bytes
        - status
      title: PublicFile
      example:
        created_at: '2026-10-16T09:14:02.511Z'
        description: Two-page product brochure, updated October.
        filename: autumn-brochure.pdf
        id: 8f14e45f-ea1c-4b31-9a2b-7c3d5e6f1a20
        kind: document
        label: autumn-brochure_7bq2xk
        mime_type: application/pdf
        name: Autumn brochure
        size_bytes: 184320
        status: ready
    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_…`.'

````

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