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

# Upload chunk

> Streams a chunk of file data to the underlying storage. Include a Content-Range header (e.g. `bytes 0-1048575/5242880`) and send the raw bytes as the request body. When the total is known and this is the final chunk, the upload completes and the status becomes `completed`.



## OpenAPI

````yaml /openapi/file-api.json put /v1/uploads/{uploadId}
openapi: 3.1.0
info:
  title: Adclear File Proxy API
  version: 1.0.0
  description: >
    File upload service for Adclear. Upload files here before creating
    promotions via the

    [Integration API](https://public-api.adclear.ai/v1/docs).


    ## Authentication


    All endpoints require a Bearer token (`Authorization: Bearer <token>`).

    Two authentication methods are supported:


    - **Clerk JWT** — User identity is extracted from the token.

    - **API Key** — Optionally pass `X-External-User-ID` to identify the
    end-user.
      `X-External-User-Email` is also optional but recommended for audit logging.

    ## Usage


    ### 1. Initiate an upload

    ```

    POST /v1/uploads  { fileName, fileSize, contentType }

    →  201 { uploadId, uploadUrl, maxChunkSize }

    ```


    ### 2. Upload the file in chunks

    PUT file chunks to the returned `uploadUrl` with a `Content-Range` header.

    Each chunk must be at most `maxChunkSize` bytes (default 50 MB).


    ```

    PUT /v1/uploads/{uploadId}

    Content-Range: bytes 0-52428799/123456789

    →  308  (more chunks needed)


    PUT /v1/uploads/{uploadId}

    Content-Range: bytes 52428800-123456788/123456789

    →  200  { status: "completed", uploadId }

    ```


    ### 3. Use the uploadId

    Pass the `uploadId` when creating a promotion or version via the Integration
    API.

    The file is verified automatically at that point.


    ## File size limits


    | Format | Max size |

    |--------|----------|

    | PDF | 30 MB |

    | Image (jpg, png, webp, etc.) | 30 MB |

    | Video (mp4, mov, etc.) | 2 GB |

    | Audio (mp3, wav, etc.) | 2 GB |

    | Document (docx, xlsx, etc.) | 10 MB |


    Files exceeding these limits are rejected at initiation (413 Payload Too
    Large).


    ## Chunk size


    The `maxChunkSize` returned by the initiate endpoint defines the maximum
    bytes per PUT request.

    The default is 50 MB. The final chunk may be smaller.


    ---
servers:
  - url: https://files.adclear.ai
    description: Production
  - url: https://files-staging.adclear.ai
    description: Staging
security:
  - BearerAuth: []
tags:
  - name: Upload
    description: File upload operations (initiate, status, delete)
  - name: Download
    description: File download and streaming (Bearer or signed URL token auth)
externalDocs:
  description: Integration API — create promotions, trigger evaluations
  url: https://public-api.adclear.ai/v1/docs
paths:
  /v1/uploads/{uploadId}:
    put:
      tags:
        - Upload
      summary: Upload chunk
      description: >-
        Streams a chunk of file data to the underlying storage. Include a
        Content-Range header (e.g. `bytes 0-1048575/5242880`) and send the raw
        bytes as the request body. When the total is known and this is the final
        chunk, the upload completes and the status becomes `completed`.
      operationId: uploadChunk
      parameters:
        - schema:
            type: string
            format: uuid
            description: Upload ID
          required: true
          name: uploadId
          in: path
        - schema:
            type: string
            format: uuid
            description: >-
              Workspace ID fallback. Required when authenticating with a Bearer
              token in environments where cookies cannot be shared (e.g.
              preview). Not needed for API key auth (workspace is embedded in
              the key metadata) or when the workspace cookie is present.
            example: 43dc2a1c-3384-41b5-a6e9-3b2d607d0fae
          required: false
          name: x-adclear-workspace-id
          in: header
        - schema:
            type: string
            description: >-
              Required when authenticating with an API key. Identifies the
              end-user making the request. Ignored when authenticating with a
              Bearer token (the user ID is extracted from the token).
            example: user_abc123
          required: false
          name: x-external-user-id
          in: header
        - schema:
            type: string
            format: email
            description: >-
              Optional. Email of the external user, used for audit logging. Only
              applicable when authenticating with an API key.
            example: user@example.com
          required: false
          name: x-external-user-email
          in: header
      responses:
        '200':
          description: Chunk accepted or upload completed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChunkUploadResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: VALIDATION_ERROR
                  message: >-
                    Missing or malformed Content-Range header. Expected: bytes
                    <start>-<end>/<total|*>
                  details:
                    - type: field_error
                      field: fileName
                      message: Required
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '401':
          description: Unauthorized — missing or invalid token/API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: UNAUTHORIZED
                  message: Missing or invalid Bearer token
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '404':
          description: Upload or session not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: NOT_FOUND
                  message: Upload not found
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '409':
          description: Upload already completed or failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST
                  message: Upload is already completed
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '413':
          description: File too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: PAYLOAD_TOO_LARGE
                  message: >-
                    File size 104857600 exceeds limit of 31457280 bytes for pdf
                    files
                  details:
                    - type: constraint_violation
                      constraint: max_file_size
                      limit: 31457280
                      actual: 104857600
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '429':
          description: Rate limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: RATE_LIMITED
                  message: Too many requests
                  details:
                    - type: retry_info
                      retryAfterSeconds: 30
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: INTERNAL_ERROR
                  message: Internal server error
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
        '502':
          description: Storage service error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: SERVICE_ERROR
                  message: Storage returned unexpected status 503
                correlationId: f47ac10b-58cc-4372-a567-0e02b2c3d479
      security:
        - BearerAuth: []
components:
  schemas:
    ChunkUploadResponse:
      type: object
      properties:
        uploadId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - uploading
            - completed
        bytesReceived:
          type: integer
          description: Total bytes the server has received so far
        correlationId:
          type: string
          format: uuid
          description: Correlation ID for request tracing. Include in support requests.
      required:
        - uploadId
        - status
        - bytesReceived
        - correlationId
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - VALIDATION_ERROR
                - INVALID_REQUEST
                - UNAUTHORIZED
                - FORBIDDEN
                - NOT_FOUND
                - PAYLOAD_TOO_LARGE
                - RATE_LIMITED
                - INTERNAL_ERROR
                - SERVICE_ERROR
            message:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  type:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                  constraint:
                    type: string
                  limit:
                    type: number
                  actual:
                    type: number
                  retryAfterSeconds:
                    type: number
                required:
                  - type
          required:
            - code
            - message
        correlationId:
          type: string
          format: uuid
      required:
        - error
        - correlationId
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: Clerk session JWT or Unkey API key passed as Bearer token

````