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

> ## Agent Instructions
> Start with /introduction/getting-started. Use the Direct Query API (POST /query) with the Newton Fusion model (text, image, and video reasoning) or the Newton Omega encoder (time-series embeddings). ATAI_API_ENDPOINT must include the version path: /v0.5 for most APIs, /v0.6 for the Fine-Tuning Service. Pages whose descriptions are marked (Archived) document the legacy Lens runtime — do not use them for new projects.

# Initiate Upload

> Begin a direct-to-cloud upload and receive presigned URLs for the file parts

## Overview

Begin a direct-to-cloud upload of a file. The server records the file metadata, splits the upload into parts, and returns presigned URLs that the client uploads each part to.

<Note>
  Direct-to-cloud file uploads support files up to **250 GB**. However, [Lenses](/core-concepts/lenses/overview) and the Lens API do not support files larger than 512 MB.
</Note>

The full direct-to-cloud upload flow is:

1. **Initiate** the upload (this endpoint) — receive `upload_id` and presigned `parts`.
2. **PUT** each part's bytes directly to its presigned `url`. Capture the `ETag` response header from each PUT — that is the part's `part_token`.
3. Optionally, **[checkpoint](./checkpoint-parts)** completed parts so they can be skipped on resume.
4. Optionally, **[generate fresh URLs](./generate-part-urls)** for parts whose presigned URLs are about to expire.
5. **[Complete](./complete-upload)** the upload, supplying a `part_token` for each non-checkpointed part.

If something goes wrong, **[abort](./abort-upload)** the upload to release server-side resources.

<Warning>
  **Part numbers are 1-based.** The first part returned by this endpoint has `part_number: 1`, not `0`. Using `part_number: 0` in any subsequent call (`/parts/urls`, `/parts/checkpoint`, `/complete`) is rejected with `400 invalid_upload_parts`.
</Warning>

## Request Body

<ParamField body="filename" type="string" required>
  Name of the file being uploaded
</ParamField>

<ParamField body="file_type" type="string" required>
  MIME type of the file (e.g. `image/png`, `text/csv`)
</ParamField>

<ParamField body="num_bytes" type="integer" required>
  Total size of the file in bytes
</ParamField>

<ParamField body="resume_if_started" type="boolean">
  When `true`, if a matching in-progress upload for this filename already exists for the organization, the server reuses it and returns only the parts that have not been checkpointed.

  "Matching" requires the existing record's `file_type` and `num_bytes` to equal the request's; a mismatch fails with `409`. If no in-progress upload exists, behavior is identical to `resume_if_started=false`.
</ParamField>

## Response

<ResponseField name="upload_id" type="string">
  Server-generated identifier for the upload. Use it in subsequent calls to checkpoint, generate URLs, complete, or abort.
</ResponseField>

<ResponseField name="file_uid" type="string">
  Internal unique identifier that will be assigned to the completed file
</ResponseField>

<ResponseField name="file_name" type="string">
  Name of the file being uploaded
</ResponseField>

<ResponseField name="total_bytes" type="integer">
  Total size of the file in bytes
</ResponseField>

<ResponseField name="num_parts" type="integer">
  Number of parts the file has been split into
</ResponseField>

<ResponseField name="part_size" type="integer">
  Size in bytes used to split the file into parts. May be omitted for some upload backends.
</ResponseField>

<ResponseField name="integrity_algorithm" type="string">
  Whole-file checksum algorithm supported by the storage backend. One of `crc32c` or `none`. If `crc32c`, the client may compute a CRC32C over the full file and pass it as `integrity_checksum` on [Complete Upload](./complete-upload) for server-side verification. If `none`, the backend does not support checksum verification — clients should not send one.
</ResponseField>

<ResponseField name="is_resume" type="boolean">
  `true` when the response reuses an existing in-progress upload (because the request specified `resume_if_started=true` and a matching record was found). `false` for a freshly created upload. When `true`, `parts` contains only the not-yet-checkpointed subset.
</ResponseField>

<ResponseField name="parts" type="array">
  Presigned descriptors for each part of the upload

  <Expandable title="part properties">
    <ResponseField name="part_number" type="integer">
      1-based part index. The first part is `1`.
    </ResponseField>

    <ResponseField name="url" type="string">
      Presigned URL the client should `PUT` the part bytes to
    </ResponseField>

    <ResponseField name="offset" type="integer">
      Byte offset into the file where this part begins
    </ResponseField>

    <ResponseField name="length" type="integer">
      Length of the part in bytes
    </ResponseField>

    <ResponseField name="expires_at" type="string">
      ISO 8601 timestamp at which the presigned URL expires
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={"system"}
  curl -X POST https://api.u1.archetypeai.app/v0.5/files/uploads/initiate \
    -H "Authorization: Bearer $ATAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "filename": "training-data.parquet",
      "file_type": "application/x-parquet",
      "num_bytes": 1073741824,
      "resume_if_started": false
    }'
  ```

  ```python Python theme={"system"}
  import requests
  import os

  api_key = os.environ.get("ATAI_API_KEY")

  response = requests.post(
      "https://api.u1.archetypeai.app/v0.5/files/uploads/initiate",
      headers={
          "Authorization": f"Bearer {api_key}",
          "Content-Type": "application/json",
      },
      json={
          "filename": "training-data.parquet",
          "file_type": "application/x-parquet",
          "num_bytes": 1_073_741_824,
          "resume_if_started": False,
      },
  )

  result = response.json()
  print(f"upload_id: {result['upload_id']}")
  print(f"num_parts: {result['num_parts']}")
  ```

  ```javascript JavaScript theme={"system"}
  const response = await fetch(
    "https://api.u1.archetypeai.app/v0.5/files/uploads/initiate",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.ATAI_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        filename: "training-data.parquet",
        file_type: "application/x-parquet",
        num_bytes: 1_073_741_824,
        resume_if_started: false,
      }),
    }
  );

  const result = await response.json();
  console.log(`upload_id: ${result.upload_id}`);
  console.log(`num_parts: ${result.num_parts}`);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Success theme={"system"}
  {
    "upload_id": "upl_1mehceg8cn80qsekh46143whrx",
    "file_uid": "fil_5hx819ysp38n2rt1f5fv0wsxgh",
    "file_name": "training-data.parquet",
    "total_bytes": 1073741824,
    "num_parts": 128,
    "part_size": 8388608,
    "integrity_algorithm": "crc32c",
    "is_resume": false,
    "parts": [
      {
        "part_number": 1,
        "url": "https://storage.example.com/upload/upl_1mehceg8cn80qsekh46143whrx/1?X-Amz-Signature=...",
        "offset": 0,
        "length": 8388608,
        "expires_at": "2026-04-28T15:32:18Z"
      },
      {
        "part_number": 2,
        "url": "https://storage.example.com/upload/upl_1mehceg8cn80qsekh46143whrx/2?X-Amz-Signature=...",
        "offset": 8388608,
        "length": 8388608,
        "expires_at": "2026-04-28T15:32:18Z"
      }
    ]
  }
  ```

  ```json 400 - Invalid request theme={"system"}
  {
    "errors": [
      {
        "code": "invalid_request",
        "message": "num_bytes must be greater than zero.",
        "suggestion": "Specify the total file size in bytes and retry.",
        "error_uid": "err-xxxxxxxx"
      }
    ]
  }
  ```

  ```json 401 - Unauthorized theme={"system"}
  {
    "errors": [
      {
        "code": "unauthorized_request",
        "message": "Unauthorized or invalid access.",
        "suggestion": "Provide valid authentication credentials and ensure they have the required permissions.",
        "error_uid": "err-xxxxxxxx"
      }
    ]
  }
  ```

  ```json 409 - Resume mismatch theme={"system"}
  {
    "errors": [
      {
        "code": "resume_mismatch",
        "message": "An in-progress upload exists for this filename but file_type or num_bytes do not match.",
        "suggestion": "Abort the existing upload or retry with the original file_type and num_bytes.",
        "error_uid": "err-xxxxxxxx"
      }
    ]
  }
  ```
</ResponseExample>
