---
title: "Complete a chunked upload"
description: "POST https://api.markitdown.ai/v1/uploads/{id}/complete — Complete a chunked upload. Authenticate with x-api-key."
url: https://markitdown.ai/docs/api/complete-upload
updated: 2026-09-26
source: markitdown.ai
---

# Complete a chunked upload

> POST https://api.markitdown.ai/v1/uploads/{id}/complete — Complete a chunked upload. Authenticate with x-api-key.

## Endpoint

**POST** `/v1/uploads/{id}/complete` — Complete a chunked upload

Assembles the uploaded parts, HEADs the object, and verifies its actual size matches the declared size and the caller's plan file-size limit.

## Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | path · string | yes |  |

## Request body

`application/json` — object (required).

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `parts` | object[] | yes |  |
| `parts[].etag` | string | yes |  |
| `parts[].number` | integer | yes |  |

## Example request

**curl**

```bash
curl -X POST https://api.markitdown.ai/v1/uploads/cnv_00000000000040008000000000000001/complete \
  -H "x-api-key: $MARKITDOWN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "parts": [ { "etag": "string", "number": 1 } ] }'
```

## Responses

- `200` Completed.
- `404` Not found (`application/problem+json`) — `Problem`
- `409` Upload not completed (`application/problem+json`) — `Problem`
- `410` File expired (`application/problem+json`) — `Problem`
- `413` Upload too large (`application/problem+json`) — `Problem`
- `503` Conversion unavailable (`application/problem+json`) — `Problem`

## Errors

- [Error codes](/docs/errors) — every `error` code with its status, meaning and whether to retry

## Related

- [API reference](https://markitdown.ai/docs/api)
- [Error codes](https://markitdown.ai/docs/errors)
- [Introduction](https://markitdown.ai/docs)
- [Document Conversion APIs](https://markitdown.ai/developers)
