Skip to main content

Uploading a file

Two calls: reserve a slot, then send the bytes.
1

Reserve the slot

Answers with an uploadId, the slot’s state and an expiresAt.
2

Send the bytes

Answers with the finished Asset, including its assetId and publicUrl.
The server verifies the actual file bytes against the contentType and sizeBytes you declared. Declaring one thing and sending another fails.

Limits

A slot moves through INITIATEDUPLOADINGCLEANINGCOMPLETED, or ends in FAILED / EXPIRED.

Generating creative

Image generation is asynchronous: submit, poll, attach.
status moves PENDINGGENERATINGSUCCEEDED or FAILED. On success the response carries a contentUrl; on failure, an error. Not happy with it? POST /api/v1/image-generations/{requestId}/regenerate runs it again from the same request. aspectRatio is SQUARE or PORTRAIT.
destinationUrl here is a hint about who you are and nothing more: only the scheme, host and path reach the image model, never the query string. A URL still carrying a placeholder after the query string is cut is left out of the prompt altogether — the image is generated before the campaign exists, so there is no campaign to name.

Attaching creative to a campaign

Pass asset ids in mediaAssetIds when you create the campaign. Assets carry a source of USER_UPLOAD or AI_GENERATED, so you can tell later which is which. DELETE /api/v1/assets/{assetId} removes one.