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

# Upload a file

> Start uploading an input file so the agent can use it in a Task.

Uploads go **straight to cloud storage** — the API only hands you a presigned
target and never receives the bytes. The response's `upload_type` tells you which
of two flows to run; it's picked automatically from the `bytes` you declare
(large files use multipart), and there's **no maximum file size**.

### Small files — `upload_type: "single"`

1. **`POST /files/uploads`** (this call) — returns a `file_id`, a presigned
   `upload_url`, and the `fields` to send with the bytes.
2. **Upload the bytes** — POST them to `upload_url` as multipart form-data, with
   every key in `fields` included as a form field (`204 No Content` on success).
3. **`POST /files/{file_id}/finalize`** — confirm the upload (empty body).

### Large files — `upload_type: "multipart"`

1. **`POST /files/uploads`** returns a `file_id`, an `upload_id`, a `part_size`,
   and a `part_count` (no `upload_url`).
2. Split the file into `part_count` chunks of `part_size` bytes (the last chunk
   is whatever's left).
3. **`POST /files/{file_id}/parts`** with the `upload_id` and the part numbers you
   want → returns a presigned **PUT** URL per part. You can request them in
   batches.
4. **PUT each chunk** to its URL and keep the **`ETag`** response header for that
   part number.
5. **`POST /files/{file_id}/finalize`** with `{ "upload_id": "…", "parts": [{
   "part_number": 1, "etag": "…" }, … ] }` — cloud storage assembles the object.

Either way, once finalized, attach the `file_id` to a Task with
`"file_ids": [...]` on `POST /messages`.


## OpenAPI

````yaml api-reference/openapi.json POST /files/uploads
openapi: 3.1.0
info:
  title: Biomni Public API — V0
  description: >-
    The public API for **Biomni** — the AI agent platform for clinical genomics
    (variant annotation, ClinVar lookups, PMID-cited literature, and project
    file drives). Create projects and Tasks, send messages to the agent, stream
    its replies, manage files, and check your usage — all from your own code.


    **Authentication**: send `Authorization: Bearer <your-api-key>`. The adapter
    forwards your key straight to Biomni; it never stores it.


    **Safe retries**: send `Idempotency-Key: <token>` on POST endpoints
    (`/projects`, `/tasks`, `/messages`, `/files/uploads`) so a retried request
    won't create a duplicate.
  version: 0.1.0
servers:
  - url: https://api.phylo.bio/api/v1
security: []
paths:
  /files/uploads:
    post:
      tags:
        - files
      summary: Upload a file
      description: Start uploading an input file so the agent can use it in a Task.
      operationId: request_upload_files_uploads_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateFileRequest'
            examples:
              minimal:
                summary: Minimal — VCF input file
                value:
                  project_id: proj_a4374b138a
                  filename: patient001_brca1.vcf
                  bytes: 4321
              with_mime:
                summary: With mime_type + explicit purpose
                value:
                  project_id: proj_a4374b138a
                  filename: Patient001_BRCA1_variant_report.json
                  bytes: 13913
                  purpose: output
                  mime_type: application/json
        required: true
      responses:
        '200':
          description: >-
            Upload started. `upload_type=single` → POST the bytes to
            `upload_url` with `fields`. `upload_type=multipart` → use
            `upload_id` + `part_size` + `part_count` with `POST
            /files/{file_id}/parts`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadIntent'
              examples:
                single:
                  summary: Small file — single POST
                  value:
                    object: upload_intent
                    file_id: 9c3d3be7-13d3-4deb-8e6a-aa3a9b51abd4
                    project_id: proj_a4374b138a
                    path: uploads/patient001_brca1.vcf
                    upload_type: single
                    upload_url: https://<bucket>.s3.us-east-1.amazonaws.com/
                    fields:
                      key: uploads/patient001_brca1.vcf
                      Content-Type: text/x-vcard
                      policy: eyJleHBpcmF0aW9uIjoiMjAyNi0w...
                      x-amz-signature: 5a8d...
                    expires_at: 1779135100
                    filename: patient001_brca1.vcf
                    bytes: 4321
                    mime_type: text/x-vcard
                multipart:
                  summary: Large file — multipart upload
                  value:
                    object: upload_intent
                    file_id: 1a2b3c4d-5e6f-7081-9aab-bccddeeff001
                    project_id: proj_a4374b138a
                    path: uploads/wgs_sample.cram
                    upload_type: multipart
                    upload_id: 2~aBcDeFgHiJkLmNoPqRsTuVwXyZ012345
                    part_size: 104857600
                    part_count: 21
                    expires_at: 1779135100
                    filename: wgs_sample.cram
                    bytes: 2147483648
                    mime_type: application/octet-stream
      security:
        - bearerAuth: []
components:
  schemas:
    CreateFileRequest:
      properties:
        project_id:
          type: string
          title: Project Id
        filename:
          type: string
          title: Filename
        bytes:
          type: integer
          title: Bytes
        purpose:
          type: string
          enum:
            - input
            - output
          title: Purpose
          default: input
        mime_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Mime Type
      type: object
      required:
        - project_id
        - filename
        - bytes
      title: CreateFileRequest
    UploadIntent:
      properties:
        object:
          type: string
          const: upload_intent
          title: Object
          default: upload_intent
        file_id:
          anyOf:
            - type: string
            - type: 'null'
          title: File Id
        project_id:
          type: string
          title: Project Id
        path:
          anyOf:
            - type: string
            - type: 'null'
          title: Path
        upload_type:
          type: string
          enum:
            - single
            - multipart
          title: Upload Type
          default: single
        upload_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Upload Url
        fields:
          additionalProperties: true
          type: object
          title: Fields
        upload_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Upload Id
        part_size:
          anyOf:
            - type: integer
            - type: 'null'
          title: Part Size
        part_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Part Count
        expires_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Expires At
        filename:
          type: string
          title: Filename
        bytes:
          type: integer
          title: Bytes
        mime_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Mime Type
      type: object
      required:
        - project_id
        - filename
        - bytes
      title: UploadIntent
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Requires an API key. See the Authentication guide.

````