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

# Start or finish a multipart upload

> Without `upload_id`, starts an upload of a file larger than 64 MiB.

Send its SHA-256 in `X-Content-SHA256` and its total byte length in `X-Content-Length`;
the answer is the `upload_id`. Older clients may omit the total length; their parts
reserve quota cumulatively. With `upload_id`, finishes it: the body lists the parts and
the file's size, and the assembled file must match that size and SHA-256. Repeating the
same start or completion is safe after a lost response. Keep the upload ID and query its
status to resume. At most 16 unfinished uploads belong to one run; uploads idle for 24
hours are aborted and their quota released. Publication temporarily keeps both the
staging object and the replacement: leave room for one additional file copy. A quota
refusal preserves the upload so you can free room and retry, or DELETE the upload to
release its reservation.


## OpenAPI

````yaml /api-reference/openapi.yaml post /v1/robot/runs/{robot}/{run}/uploads/{path}
openapi: 3.1.0
info:
  title: Abstract API
  version: 1.0.0
  summary: Robot action models and LLMs behind one API key.
  description: >
    `POST /v1/chat/completions` serves the robot action models. `POST
    /v1/responses` and

    `GET /v1/responses/{response_id}` serve the LLM models through the OpenAI
    Responses API.

    `GET /v1/models` lists the LLM model ids.


    The robot models also run over a WebSocket at
    `wss://api.abstract.inc/v1/responses`.

    OpenAPI does not describe it. See [Sessions over
    WebSocket](/robots/sessions).


    `/v1/robot/runs` stores your robot runs (episode logs, the Rerun recording
    with the

    camera video) under your account, and lists, downloads and deletes them.
    Only the key's

    account reaches its runs. An account stores up to 100 GiB of runs;

    `GET /v1/robot/runs/usage` shows what it holds.
  contact:
    name: Abstract
    url: https://abstract.inc
servers:
  - url: https://api.abstract.inc
security:
  - bearerAuth: []
tags:
  - name: Robot models
  - name: Robot runs
  - name: LLM models
paths:
  /v1/robot/runs/{robot}/{run}/uploads/{path}:
    post:
      tags:
        - Robot runs
      summary: Start or finish a multipart upload
      description: >
        Without `upload_id`, starts an upload of a file larger than 64 MiB. Send
        its SHA-256

        in `X-Content-SHA256` and its total byte length in `X-Content-Length`;
        the answer is

        the `upload_id`. Older clients may omit the total length; their parts
        reserve

        quota cumulatively. With `upload_id`, finishes it: the body lists the
        parts and

        the file's size, and the assembled file must match that size and
        SHA-256.

        Repeating the same start or completion is safe after a lost response.
        Keep the

        upload ID and query its status to resume. At most 16 unfinished uploads
        belong

        to one run; uploads idle for 24 hours are aborted and their quota
        released.

        Publication temporarily keeps both the staging object and the
        replacement:

        leave room for one additional file copy. A quota refusal preserves the
        upload

        so you can free room and retry, or DELETE the upload to release its
        reservation.
      operationId: startOrFinishRobotRunUpload
      parameters:
        - $ref: '#/components/parameters/Robot'
        - $ref: '#/components/parameters/Run'
        - $ref: '#/components/parameters/FilePath'
        - name: upload_id
          in: query
          required: false
          schema:
            type: string
        - name: X-Content-SHA256
          in: header
          required: false
          description: Required to start. The whole file's SHA-256, 64 hex digits.
          schema:
            type: string
            pattern: ^[0-9a-f]{64}$
        - name: X-Content-Length
          in: header
          required: false
          description: >-
            Recommended at start. Reserves the whole file's byte length before
            accepting parts.
          schema:
            type: integer
            minimum: 0
            maximum: 2147483648
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              required:
                - parts
                - size
              properties:
                parts:
                  type: array
                  items:
                    type: object
                    required:
                      - part
                      - etag
                    properties:
                      part:
                        type: integer
                      etag:
                        type: string
                size:
                  type: integer
      responses:
        '201':
          description: Started (`upload_id`), or finished (`path`, `size`, `sha256`).
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - upload_id
                    properties:
                      upload_id:
                        type: string
                  - $ref: '#/components/schemas/RobotRunFile'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: '`upload_not_found`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: >-
            `run_too_large`, `request_too_large` or `storage_quota_exceeded`. A
            quota refusal keeps the staged upload for retry or explicit abort.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            `checksum_mismatch`: the assembled file is not the size and SHA-256
            it started with, and is discarded; or `invalid_request`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: '`storage_unavailable` or `auth_unavailable`. Retry with backoff.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    Robot:
      name: robot
      in: path
      required: true
      description: Your robot's name, for example `t800`.
      schema:
        type: string
        pattern: ^[a-z0-9][a-z0-9._-]{0,63}$
    Run:
      name: run
      in: path
      required: true
      description: The run's name, its start time as `YYYYMMDD-HHMMSS`.
      schema:
        type: string
        pattern: ^\d{8}-\d{6}$
    FilePath:
      name: path
      in: path
      required: true
      description: >-
        The file's path in the run. It may hold `/`; up to 8 segments of
        letters, digits, `.`, `_` and `-`, each starting with a letter or digit,
        512 bytes in all. `manifest.json` at the top is the server's.
      schema:
        type: string
  schemas:
    RobotRunFile:
      type: object
      required:
        - path
        - size
        - sha256
      properties:
        path:
          type: string
        size:
          type: integer
        sha256:
          type: string
          pattern: ^[0-9a-f]{64}$
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
              description: For people. It can change.
            type:
              type: string
            param:
              type:
                - string
                - 'null'
              description: The request field at fault, when one is.
            code:
              type: string
              description: Branch on this. See [Errors and limits](/errors).
  responses:
    Unauthorized:
      description: '`missing_api_key` or `invalid_api_key`.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              message: Invalid API key.
              type: invalid_request_error
              code: invalid_api_key
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your Abstract API key. Get it with `abstract login`, pass it as
        `$(abstract token)`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.