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

# Upload attachment

> Uploads a file and returns a `signed_id` for it. Pass that id in `attachments` on
[Create ticket](/api-reference/tickets/create) or
[Create comment](/api-reference/comments/create) to attach the file.

The upload is a two-step flow because a file has no home until the record it belongs
to exists. An uploaded file that is never attached is cleaned up automatically.

A `signed_id` can only be attached in the workspace that uploaded it.

Two different size limits apply, so it is worth knowing both. This endpoint accepts
a file up to the workspace upload limit, 50 MB by default. Attaching it to a ticket
or comment applies the smaller attachment limit, 10 MB by default, and a file over
that is rejected at attach time rather than silently dropped.


<Info>Replace `{your-subdomain}` with your workspace's subdomain. <br /> Learn how to find your subdomain in [Workspace subdomain](/getting-started/workspace-subdomain).</Info>


## OpenAPI

````yaml bundled/attachments.yaml POST /attachments
openapi: 3.0.3
info:
  title: NeetoDesk APIs
  version: 2.0.0
servers:
  - description: NeetoDesk APIs
    url: https://{your-subdomain}.neetodesk.com/api/external/v2
    variables:
      your-subdomain:
        default: spinkart
        description: >-
          Replace **spinkart** with your [workspace's
          subdomain](/getting-started/workspace-subdomain).
security: []
paths:
  /attachments:
    post:
      summary: Upload attachment
      description: >
        Uploads a file and returns a `signed_id` for it. Pass that id in
        `attachments` on

        [Create ticket](/api-reference/tickets/create) or

        [Create comment](/api-reference/comments/create) to attach the file.


        The upload is a two-step flow because a file has no home until the
        record it belongs

        to exists. An uploaded file that is never attached is cleaned up
        automatically.


        A `signed_id` can only be attached in the workspace that uploaded it.


        Two different size limits apply, so it is worth knowing both. This
        endpoint accepts

        a file up to the workspace upload limit, 50 MB by default. Attaching it
        to a ticket

        or comment applies the smaller attachment limit, 10 MB by default, and a
        file over

        that is rejected at attach time rather than silently dropped.
      parameters:
        - $ref: '#/components/parameters/api_key_header'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UploadAttachmentRequest'
      responses:
        '201':
          description: Created - File uploaded successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Attachment'
        '422':
          description: >
            Unprocessable Entity - no file was sent, or the file is larger than
            the

            workspace upload limit (50 MB by default).
components:
  parameters:
    api_key_header:
      in: header
      name: X-Api-Key
      description: >-
        Use the X-Api-Key header to provide your workspace API key. Refer to
        [Authentication](/getting-started/authentication) for more information.
      required: true
      schema:
        type: string
        default: your-api-key
  schemas:
    UploadAttachmentRequest:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          format: binary
          description: The file to upload. Sent as `multipart/form-data`.
    Attachment:
      type: object
      properties:
        id:
          type: string
          example: aaaabbbb-cccc-dddd-eeee-ffff00004444
        signed_id:
          type: string
          description: >
            Pass this to `attachments` on ticket or comment create to attach the
            file.

            It is only accepted in the workspace that uploaded it.
          example: eyJfcmFpbHMiOnsiZGF0YSI6IjEyMyJ9fQ==
        filename:
          type: string
          example: report.pdf
        content_type:
          type: string
          example: application/pdf
        byte_size:
          type: integer
          example: 20481
        checksum:
          type: string
          example: Y2hlY2tzdW1leGFtcGxl
        blob_url:
          type: string
          description: URL the uploaded file can be fetched from.
          example: https://spinkart.neetodesk.com/rails/active_storage/blobs/report.pdf
        created_at:
          type: string
          format: date-time
          readOnly: true
          example: '2025-12-01T10:15:00Z'

````