---
title: "Assemble a chunked upload. Body: { upload_id, parts: [{ part_number, etag }] }. Only after every part has been PUT; then call /submit."
method: POST
path: "/jobs/{id}/upload-complete"
---

# Assemble a chunked upload. Body: { upload_id, parts: \[{ part_number, etag }\] }. Only after every part has been PUT; then call /submit.

`POST /jobs/{id}/upload-complete`

## Request

- Base URL: `https://widget.reelquoteai.com/api/v1`
- URL: `https://widget.reelquoteai.com/api/v1/jobs/{id}/upload-complete`
- Auth: HTTP bearer

## Request body

- object
  - `upload_id` string, required: From the multipart ticket
  - `parts` object[], required: Every part, in any order
    - `part_number` integer: 1-based
    - `etag` string: The ETag response header of that part's PUT

## Response `200`

Assembled

- object
  - `job_id` string
  - `status` 'uploaded'

## Other responses

- `400`: `invalid_request` — A field is missing, malformed or not allowed in this state. `message` says which. `secret_key_in_url` — A secret key was sent as `?k=`. Secret keys go in the Authorization header only.
- `401`: `unauthorized` — No key, an unknown key, or a revoked key.
- `404`: `not_found` — No such job for this key, or no such endpoint.
- `429`: `rate_limited` — Per-key limit (60/min publishable, 300/min secret), the mover's daily ballpark or video-analysis cap, or a visitor's daily catalog-search cap. Obey `Retry-After`. Carries `Retry-After` in seconds.

---

[API](https://skmtc.dev/reelquoteai/apis/reelquoteai-us-api.md) · [All operations](https://skmtc.dev/reelquoteai/apis/reelquoteai-us-api/llms.txt) · [OpenAPI document](https://skmtc.dev/reelquoteai/apis/reelquoteai-us-api/revisions/56c304752192?raw)
