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

# Upload Files to Case

> Generate upload URLs for adding files to an existing case.

Generate pre-signed upload URLs for adding files to an existing case. This endpoint allows you to upload additional files to cases that have already been created, as long as the case is not locked.

<Warning>
  **Case Locking**: Once you start uploading files to a case, the case becomes locked and you cannot add more files later. Upload all files you need in a single batch.
</Warning>

## When to Use This Endpoint

### Use Case Creation Upload (`POST /cases`)

* When creating a new case with initial files.
* For the first batch of files in a case.
* When you know all files upfront.

### Use Additional File Upload (`POST /cases/{caseId}/files`)

* When adding files to existing unlocked cases.
* For supplementary documents after initial case creation.
* When file requirements change during the process.


## OpenAPI

````yaml POST /cases/{caseId}/files
openapi: 3.1.0
info:
  title: Veridox Core API
  description: Veridox Core Platform API
  version: 0.0.1
  contact: {}
servers:
  - url: https://api.uk.veridox.ai
    description: Live (UK)
  - url: https://api.ca.veridox.ai
    description: Live (CA)
security: []
tags:
  - name: Status
    description: System status and health check endpoints
  - name: Cases
    description: Case and case file management
  - name: Organisations
    description: Organisation management
  - name: Document Requests
    description: Document request management
  - name: Search
    description: Search functionality
  - name: Admin
    description: Administrative endpoints
paths:
  /cases/{caseId}/files:
    post:
      tags:
        - Case Files
      summary: Generate file upload URLs for a case
      description: >-
        Generates SAS URLs for uploading files to an existing unlocked case.
        Each file must have a label. The case must be owned by the authenticated
        user and must not be locked. SAS URLs expire after a configured time
        period.
      operationId: CaseFilesController_generateFileUrls
      parameters:
        - name: caseId
          required: true
          in: path
          description: Case ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateFileUrlsDto'
      responses:
        '201':
          description: SAS URLs generated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SasUrlResponseDto'
        '400':
          description: Invalid file labels provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
        '401':
          description: Unauthorized (invalid or missing authentication token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
        '404':
          description: Case not found or not owned by user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
        '409':
          description: Case is already locked
        '429':
          description: Too many requests (rate limit exceeded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
      security:
        - api-key: []
components:
  schemas:
    GenerateFileUrlsDto:
      type: object
      properties:
        file_labels:
          minItems: 1
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 255
      required:
        - file_labels
    SasUrlResponseDto:
      type: object
      properties:
        files:
          type: array
          items:
            type: object
            properties:
              file_id:
                type: string
                format: uuid
                pattern: >-
                  ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$
              label:
                type: string
              sas_url:
                type: string
                format: uri
              expires_at:
                type: string
                format: date-time
                pattern: >-
                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            required:
              - file_id
              - label
              - sas_url
              - expires_at
      required:
        - files
    ErrorDto:
      type: object
      properties:
        error_code:
          type: string
          description: Machine-readable error code for programmatic handling
          examples:
            - request.cases.file.missing-risk-score
            - request.authentication.invalid-token
            - request.forbidden
            - request.cases.case.not-found
            - request.cases.case.already-locked
        error_message:
          type: string
          description: Human-readable error message explaining what went wrong
          example: >-
            User tried to perform an invalid operation on a file without a risk
            score.
        error_details:
          type: object
          example:
            field: email_address
      required:
        - error_code
        - error_message
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key

````