---
title: "Register an Asset to an advertiser"
method: POST
path: "/assets/{id}/registrations"
tags: ["Assets"]
---

# Register an Asset to an advertiser

`POST /assets/{id}/registrations`

## Request

- Base URL: `https://api.adcrunch.dev`
- URL: `https://api.adcrunch.dev/assets/{id}/registrations`
- Auth: HTTP bearer

**Available on:** [![Meta](/providers/meta.svg)](https://docs.adcrunch.dev/connect/providers) [![TikTok](/providers/tiktok.svg)](https://docs.adcrunch.dev/connect/providers)

Places an Asset in one **advertiser's** provider-side library. Not a provider — an organization has several advertisers, and the bytes land in exactly one of them.

Returns immediately with a `running` Registration; poll `GET /assets/{id}` for its state. Video can take several minutes to process at the provider, which is normal rather than a failure.

A Registration that is `running` or `ready` refuses a second one for the same pair. A `failed` one starts again: send this request, and AdCrunch replaces it.

## Path parameters

- `id` string, required: The stored Asset to place.

## Request body

- object
  - `advertiserId` string, required: The advertiser whose library the bytes land in. Its provider decides how they get there.

## Response `200`

The Registration, at `running`. `providerIdentifier` is `null` until the provider has the bytes — read the Asset to see it settle.

- object
  - `advertiserId` string, required: The advertiser whose provider library gets the Asset.
  - `assetId` string, required: The Asset that the Registration places.
  - `createdAt` number, required: Milliseconds since the Unix epoch, UTC.
  - `deletedAt` number, nullable, required: Always `null` here. When a retry replaces a failed Registration, AdCrunch sets this time on the old one and answers it no more.
  - `failureCode` 'not_found' | 'provider_not_connected' | 'missing_write_access', nullable, required: Why AdCrunch refused the Registration before any provider call. Branch on this field, never on `failureReason`. `not_found`: your organization owns no advertiser of this provider with this id. `provider_not_connected`: the advertiser has no usable connection to the provider. Reconnect the provider, then register again. `missing_write_access`: the connection does not permit this kind of file. Reconnect the provider to grant it. `null` when the Registration did not fail, or when it failed at the provider.
  - `failureReason` string, nullable, required: Why the Registration failed, as a sentence: the words of the provider, or the words of AdCrunch. `null` unless `status` is `failed`.
  - `id` string, required: The id of the Registration, `reg_…`.
  - `organizationId` string, required: The organization that owns the Asset.
  - `provider` 'meta' | 'gads' | 'tiktok' | 'x' | 'openai' | 'snapchat' | 'dv360', required: The provider that owns the advertiser.
  - `providerIdentifier` string, nullable, required: The id that the provider gave the file: a Meta image hash, or the id of the image or the video at the provider. `null` until the provider gives it, and `null` on a `failed` Registration. An image gets its id when the Registration becomes `ready`. A video gets its id earlier, while the Registration is `running`, because the provider gives the id before it has processed the file. Build a creative from a `ready` Registration only.
  - `status` 'running' | 'ready' | 'failed', required: Video can stay `running` for several minutes while the provider processes it. That is normal, and not a failure.
  - `updatedAt` number, nullable, required: When the Registration last changed, in milliseconds since the Unix epoch, UTC. `null` until its first change.
  - `uploadSessionId` string, nullable, required: An in-flight provider upload session, where the protocol has one. `null` for every image.
  - `workflowId` string, required: The durable execution that runs the Registration.

## Other responses

- `400`: The request does not match the schema of this operation: a field is missing or has the wrong type, or the body is not valid JSON. `error` is `invalid_request`, and `issues` names each field. Nothing was changed.
- `401`: No API key, or one that does not resolve. See the security scheme. `error` is `unauthorized`.
- `402`: The organization has no active subscription. An owner subscribes at `paywallUrl`. `error` is `organization_unentitled`.
- `403`: The caller does not hold `asset:write`. `error` is `forbidden`.
- `404`: No stored Asset with that id, or no such advertiser in this organization. The two are one answer, so the surface cannot be used to discover that an id is real. `error` is `not_found`.
- `409`: This Asset is already in that advertiser’s library. `error` is `already_registered`.

---

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