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

# Initiate Upload

> Start a single-part upload. Returns a presigned `upload_url` to `PUT` the bytes to, and the canonical `file_url` to pass as a model input. The file row is created now, so an upload you never complete leaves a row whose `file_url` 404s. Walkthrough: [File uploads](/guides/file-uploads).



## OpenAPI

````yaml /platform-openapi.json post /storage/upload/initiate
openapi: 3.1.0
info:
  title: ModelRunner Platform API
  version: 1.0.0
  description: >-
    Platform APIs: model catalog, search and collections; model pricing rate
    cards; the Serverless GPU catalog and deployment templates; file uploads and
    your asset library; account balance and usage; and webhook delivery
    management. Catalog reads are public; account-scoped routes authenticate
    with your API key (`Authorization: Key <MODELRUNNER_KEY>`). Request
    lifecycle endpoints (submit/status/result and the request list) live on the
    queue host — see the Queue API reference.
servers:
  - url: https://api.modelrunner.run
security: []
paths:
  /storage/upload/initiate:
    post:
      summary: Initiate Upload
      description: >-
        Start a single-part upload. Returns a presigned `upload_url` to `PUT`
        the bytes to, and the canonical `file_url` to pass as a model input. The
        file row is created now, so an upload you never complete leaves a row
        whose `file_url` 404s. Walkthrough: [File
        uploads](/guides/file-uploads).
      parameters:
        - name: X-Modelrunner-Object-Lifecycle-Preference
          in: header
          required: false
          schema:
            type: string
          description: >-
            JSON object setting an expiry for the stored object, e.g.
            `{"expiration_duration_seconds": 3600}`. The countdown starts at
            upload time. See the [data retention guide](/guides/data-retention).
          examples:
            oneHour:
              value: '{"expiration_duration_seconds": 3600}'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - file_name
                - content_type
              properties:
                file_name:
                  type: string
                  description: Original filename. Preserved, with a random prefix.
                content_type:
                  type: string
                  description: >-
                    MIME type. Send the same value as `Content-Type` on the
                    `PUT`.
                size:
                  type: integer
                  description: Byte size, for validation.
                relay:
                  type: boolean
                  description: >-
                    Also mint `relay_upload_url` — a first-party `PUT` URL on
                    this API host that streams to the same object server-side.
                    For clients whose egress allowlist rejects the raw AWS S3
                    host.
      responses:
        '200':
          description: Presigned upload.
          content:
            application/json:
              schema:
                type: object
                properties:
                  upload_url:
                    type: string
                    description: >-
                      Presigned S3 `PUT` URL. Valid 5 minutes. Send no
                      `Authorization` header — the URL carries its own
                      credentials.
                  file_url:
                    type: string
                    description: >-
                      Canonical public URL. Usable as model input once the bytes
                      land.
                  relay_upload_url:
                    type: string
                    description: >-
                      Present only when `relay: true`. Same 5-minute window;
                      `PUT` the raw bytes here instead if the S3 host is
                      blocked.
        '401':
          description: Missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKeyAuth: []
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message.
        request_id:
          type: string
          description: Correlation id for support.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use the format: Key modelrunner_key'

````