---
title: asset_finalize
description: Complete an upload after the bytes have been PUT, validate the file, and add the Asset to your library — optionally registering it in the same call.
---

Completes an upload after the bytes have been `PUT` to the URL from [`asset_create_upload`](/mcp/tools/asset-create-upload), and adds the **Asset** to your library. The file is validated **here** — nothing about it is known until it lands — so a wrong type or an oversized file is rejected at this step.

## Input

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `asset_id` | `ast_*` | yes | The Asset id returned by `asset_create_upload`. |
| `advertiser_id` | `acc_*` | no | Register the Asset to this advertiser in the same call. |

## Output

`{ asset, registration? }`:

- `asset` — the finalized Asset (now `status: 'ready'`), shaped like an [`asset_list`](/mcp/tools/asset-list) row.
- `registration` — present only when `advertiser_id` was given: the outcome of the inline registration.

:::warning[A failed inline registration is not a failed finalize]

If `advertiser_id` is set and the placement fails, the Asset **is still stored** — only the registration needs retrying. Call [`asset_register`](/mcp/tools/asset-register) again; do **not** re-upload the file.

:::

## Example

> _"Finalize that upload and register it to the Acme account."_

Claude calls `asset_finalize({ asset_id: 'ast_…', advertiser_id: 'acc_…' })`, then polls [`asset_get`](/mcp/tools/asset-get) until the Registration is `ready`.

## Errors

Finalizing refuses a file it can't turn into a usable Asset:

- `not_uploaded` — the bytes haven't arrived. `PUT` them to the `uploadUrl` first, then call again.
- `too_large` — larger than the provider accepts. The file is discarded; upload a smaller version.
- `unsupported_type` — not usable in ads. Discarded; use JPEG, PNG, WebP, GIF, or MP4.
- `not_found` — no such Asset in this organization.
- `401` or `403` — see [Errors](/mcp/errors), which every tool shares. This one needs `asset:write`.
