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

# Complete a Multipart Upload

> Finalize a direct upload started via `POST /v1/files/init-upload`. The file then goes through FFprobe for media metadata; `status` changes as `UPLOADED` and becomes `STORED` when analysis completes. See the [direct upload guide](https://docs.rendi.dev/direct-upload) for the full flow.

<Note>
  Step 3 of 3 in the direct-upload flow. See the [direct upload guide](/direct-upload) for the full flow.

  After this call succeeds, Rendi analyzes the file with FFprobe to extract media metadata. The response returns `status: UPLOADED` immediately; poll [`GET /v1/files/{file_id}`](/api-reference/endpoint/get-file) — `status` becomes `STORED` when analysis completes and metadata (duration, dimensions, codec, mime type, bitrate, etc.) is populated.
</Note>


## OpenAPI

````yaml POST /v1/files/{file_id}/complete-upload
openapi: 3.1.0
info:
  title: FFmpeg Command API
  description: API for running FFmpeg in a cloud environment
  version: 1.0.0
servers:
  - url: https://api.rendi.dev
    description: Rendi - FFmpeg API
security: []
paths:
  /v1/files/{file_id}/complete-upload:
    post:
      tags:
        - API
        - File Management
      summary: Complete a multipart upload
      description: >-
        Finalize a direct upload started via `POST /v1/files/init-upload`. The
        file then goes through FFprobe for media metadata; `status` changes as
        `UPLOADED` and becomes `STORED` when analysis completes. See the [direct
        upload guide](https://docs.rendi.dev/direct-upload) for the full flow.
      operationId: complete_upload_v1_files__file_id__complete_upload_post
      parameters:
        - name: file_id
          in: path
          required: true
          schema:
            type: string
            title: File Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompleteUploadRequest'
      responses:
        '200':
          description: Upload completed; file is being ffrpobed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RendiStoredFile'
        '400':
          description: >-
            File is not in an upload-in-progress state, or the upload session
            has expired
        '401':
          description: Invalid API key
          content:
            application/json:
              example:
                detail: Invalid authorization key
        '404':
          description: File not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - APIKeyHeader: []
components:
  schemas:
    CompleteUploadRequest:
      properties:
        parts:
          items:
            $ref: '#/components/schemas/UploadPart'
          type: array
          minItems: 1
          title: Parts
          description: >-
            One entry per uploaded part, in order. Every part_number from 1 to N
            must be present.
      type: object
      required:
        - parts
      title: CompleteUploadRequest
    RendiStoredFile:
      properties:
        file_id:
          type: string
          title: File Id
          description: Unique identifier for the stored file
          examples:
            - 987fcdeb-a89b-43d3-b456-789012345678
        environment_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Environment Name
          description: >-
            The environment this file was stored in (e.g., 'main', 'test',
            'dev').
          examples:
            - main
        storage_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Storage Url
          description: URL where the file is stored
          examples:
            - >-
              https://storage.rendi.dev/123e4567-e89b-12d3-a456-426614174000/output.avi
        status:
          anyOf:
            - $ref: '#/components/schemas/FileStatus'
            - type: 'null'
          description: Status of the file
          examples:
            - STORED
        rendi_store_type:
          anyOf:
            - $ref: '#/components/schemas/RendiFileStoreType'
            - type: 'null'
          description: Type of storage of the file in rendi
          examples:
            - STORED_FILE
        error_status:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Status
          description: Status of any error that occurred during file processing
          examples:
            - UNREACHABLE_INPUT_FILE
        external_error_message:
          anyOf:
            - type: string
            - type: 'null'
          title: External Error Message
          description: Error details if the file failed to be processed
          examples:
            - Input file url https://rendi.dev/example is not reachable.
        is_deleted:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Deleted
          description: Whether the file has been deleted
          examples:
            - false
        size_mbytes:
          anyOf:
            - type: number
            - type: 'null'
          title: Size Mbytes
          description: Size of the output file or folder in megabytes
          examples:
            - 15.2
        file_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: File Count
          description: Number of files in the output folder/playlist
          examples:
            - 5
        size_compressed_mbytes:
          anyOf:
            - type: number
            - type: 'null'
          title: Size Compressed Mbytes
          description: Size of the output compressed folder in megabytes
          examples:
            - 15.2
        is_private:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Private
          description: >-
            Whether the file is stored privately. Private files are accessible
            via their `storage_url` only if you request a presigned URL by
            passing `presigned_ttl_seconds` on `GET /v1/files/{file_id}` (for a
            single file) or `GET /v1/commands/{command_id}` (for a command's
            output files) to receive a time-limited downloadable URL. Not
            available on free plans.
          examples:
            - false
        original_file_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Original File Url
          description: URL of the original file (or just name in case of uploaded file)
          examples:
            - https://somehwereonline.stored.com/file_to_store.mp4
        duration:
          anyOf:
            - type: number
            - type: 'null'
          title: Duration
          description: Duration of the media file in seconds
          examples:
            - 30.5
        file_type:
          anyOf:
            - type: string
            - type: 'null'
          title: File Type
          description: Type of the media file (video, audio, image, subtitles, etc.)
          examples:
            - video
        file_format:
          anyOf:
            - type: string
            - type: 'null'
          title: File Format
          description: Format/container of the media file
          examples:
            - avi
        width:
          anyOf:
            - type: integer
            - type: 'null'
          title: Width
          description: Width of the video in pixels
          examples:
            - 1920
        height:
          anyOf:
            - type: integer
            - type: 'null'
          title: Height
          description: Height of the video in pixels
          examples:
            - 1080
        codec:
          anyOf:
            - type: string
            - type: 'null'
          title: Codec
          description: Codec used for the media file
          examples:
            - msmpeg4v2
        timebase:
          anyOf:
            - type: string
            - type: 'null'
          title: Timebase
          description: How time is represented in the media file
          examples:
            - 1/25
        pixel_format:
          anyOf:
            - type: string
            - type: 'null'
          title: Pixel Format
          description: How the pixel data is stored in the media file
          examples:
            - yuv420p
        mime_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Mime Type
          description: MIME type of the media file
          examples:
            - video/mp4
        frame_rate:
          anyOf:
            - type: number
            - type: 'null'
          title: Frame Rate
          description: Frame rate of the video in frames per second
          examples:
            - 30
        bitrate_video_kb:
          anyOf:
            - type: number
            - type: 'null'
          title: Bitrate Video Kb
          description: Video bitrate in kilobits per second
          examples:
            - 4000
        bitrate_audio_kb:
          anyOf:
            - type: number
            - type: 'null'
          title: Bitrate Audio Kb
          description: Audio bitrate in kilobits per second
          examples:
            - 128
        video_profile_level:
          anyOf:
            - type: string
            - type: 'null'
          title: Video Profile Level
          description: Video profile level
          examples:
            - main
        is_varying_frame_rate:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Varying Frame Rate
          description: Whether the video has a variable frame rate
          examples:
            - false
      type: object
      required:
        - file_id
      title: RendiStoredFile
      description: >-
        Represents a file stored by rendi. Could either be an uploaded file or a
        file generated by running a command.


        This model contains metadata about files stored in rendi storage,
        including file details,

        media information, and storage location.
      example:
        bitrate_audio_kb: 128
        bitrate_video_kb: 4000
        codec: h264
        duration: 30
        environment_name: main
        file_format: mp4
        file_id: 987fcdeb-a89b-43d3-b456-789012345678
        file_type: video
        frame_rate: 30
        height: 1080
        is_deleted: false
        is_varying_frame_rate: false
        mime_type: video/mp4
        original_file_url: https://storage.rendi.dev/sample/big_buck_bunny_720p_5sec_intro.mp4
        pixel_format: yuv420p
        rendi_store_type: STORED_FILE
        size_mbytes: 2.27
        status: STORED
        storage_url: >-
          https://storage.rendi.dev/files/224ea098-5c10-419b-8a77-707d89443c56/987fcdeb-a89b-43d3-b456-789012345678/output.mp4
        timebase: 1/25
        video_profile_level: main
        width: 1920
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    UploadPart:
      properties:
        part_number:
          type: integer
          minimum: 1
          title: Part Number
          description: 1-based part number, matching the index in `upload_urls`.
          examples:
            - 1
        etag:
          type: string
          title: Etag
          description: ETag returned by R2 in the response of the part's PUT request.
          examples:
            - '"7d865e959b2466918c9863afca942d0f"'
      type: object
      required:
        - part_number
        - etag
      title: UploadPart
    FileStatus:
      type: string
      enum:
        - QUEUED
        - DOWNLOADING
        - DOWNLOADED
        - UPLOADED
        - FAILED
        - STORED
      title: FileStatus
    RendiFileStoreType:
      type: string
      enum:
        - INPUT
        - OUTPUT
        - STORED_FILE
      title: RendiFileStoreType
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-KEY

````