---
title: "Complete a multipart upload"
method: POST
path: "/v1/media/upload/multipart/{id}/complete"
tags: ["media"]
---

# Complete a multipart upload

`POST /v1/media/upload/multipart/{id}/complete`

## Request

- Base URL: `https://api.brixsignage.com`
- URL: `https://api.brixsignage.com/v1/media/upload/multipart/{id}/complete`
- Auth: HTTP bearer

Finalize a multipart upload by sending the list of uploaded parts, each with partNumber and etag. If the list is left empty, the server completes the upload using the parts it already has on record, so a client resuming an interrupted upload does not need to know every part's ETag. This creates the media asset record; video files are automatically queued for processing.

**Notes.**
- For a master upload (`masterOf`) the body is `{ id, masterKey, masterBytes }`; otherwise it is the new media row.

## Path parameters

- `id` string, required

## Request body

- object
  - `parts` object[], required
    - `partNumber` integer, required
    - `etag` string, required

## Response `201`

Success.

- object
  - `data` union, required
    - object
      - `id` string, required: Media asset id.
      - `spaceId` string, required: Workspace id.
      - `nodeId` string, nullable, required: Home location; null = workspace library root.
      - `folderId` string, nullable, required
      - `name` string, required
      - `kind` string, required: Media kind: image, video, audio, pdf, powerpoint, web, dashboard, weather, rss, clock, qr, menu, directory, donor-wall, hall-of-fame, birthday-board, recognition, wayfinding, check-in, emergency, touch-kiosk, package, font. Free text in storage, so a very old row may carry another value.
      - `url` string, required: Where the bytes live: a `/v1/media/<id>/file` path, an `https` URL, `r2://…`, or (for a web link) the page address.
      - `bytes` integer, required: Stored size in bytes (0 for links and apps).
      - `active` boolean, required: False when archived.
      - `altText` string, nullable, required
      - `width` integer, nullable, required
      - `height` integer, nullable, required
      - `durationSec` number, nullable, required: Video/audio length in seconds.
      - `loopDurationMs` integer, nullable, required: Animated image loop length.
      - `state` 'ready' | 'failed' | 'processing' | 'ready_with_warnings' | 'needs_action', required
      - `stateReason` string, nullable, required
      - `stateCode` string, nullable, required
      - `stateFault` 'user' | 'platform', nullable, required
      - `codec` string, nullable, required
      - `autoCaption` boolean, required
      - `captionState` unknown, required
      - `autoSmartFit` boolean, required
      - `importSourceId` string, nullable, required
      - `createdAt` string, required: ISO-8601 timestamp (UTC).
      - `updatedAt` string, required: ISO-8601 timestamp (UTC).
      - `deletedAt` unknown, required
    - object
      - `id` string, required: The asset the master was attached to (`masterOf`).
      - `masterKey` string, required
      - `masterBytes` integer, required

## Other responses

- `401`: Missing, expired or revoked bearer token.
- `403`: The token lacks the permission this operation needs (see `x-brix-permission`).
- `404`: No such upload.
- `409`: A part is missing or does not match.
- `422`: No parts.
- `5XX`: Server error. The body carries a `requestId` to quote to support.

---

[API](https://skmtc.dev/brixsignage/apis/brix-api.md) · [All operations](https://skmtc.dev/brixsignage/apis/brix-api/llms.txt) · [OpenAPI document](https://skmtc.dev/brixsignage/apis/brix-api/revisions/02fd3665dc7d?raw)
