Skip to content
AdCrunch
Esc
↑↓navigate↵open⌘Jpreview
On this page

asset_create_upload

Create an Asset from bytes that the client holds. The client sends the file to a short-lived upload URL.

Ask to add a file to AdCrunch when the agent holds the bytes and the file has no public URL. AdCrunch creates an Asset at pending and gives a short-lived upload URL.

“Add the image in this folder to AdCrunch.”

The agent sends an HTTP PUT with the bytes to the upload URL, with the header If-None-Match: *. A PUT without that header answers 403. The PUT needs no Content-Type, because AdCrunch reads the type from the bytes. The upload URL can create the file once, and it can never replace it. A PUT that answers 412 found the file already stored, so the agent continues. The agent then calls asset_get until the Asset is ready or failed. A read of the Asset checks the file and finalizes it. A ready Asset shows in the Assets of your organization. The agent then calls asset_register.

The upload URL is on *.r2.cloudflarestorage.com. An agent that cannot reach that host uses asset_create with the public URL of the file.

This tool is part of the job Bring your own creative.

Reference

Create an Asset from bytes that you hold, and get a short-lived URL to send them to.

You upload the bytes yourself: send an HTTP PUT to upload_url with the file as the body and the header If-None-Match: *. A PUT without that header answers 403. No Content-Type is needed: AdCrunch reads the type from the bytes. The bytes must never pass through this conversation. Read the file and send the PUT from your own runtime.

The URL can create the object once, and never replace it. A PUT that answers 412 found the bytes already stored, for example after a retry: continue as after a 200. To use a different file, create a new Asset.

Then poll asset_get until status is ready or failed. A read of the Asset checks the file and finalizes it. When status is failed, failureCode and failureReason say why. When status is ready, call asset_register to place the Asset in an advertiser library.

The upload URL is on *.r2.cloudflarestorage.com. A client that cannot reach that host cannot use this tool. It uses asset_create with the public URL of the file instead.

Input

Argument Type Required Description
filename string yes The original filename, including its extension.

Output

A successful call returns this object in structuredContent.

Field Type Always present Description
asset_id string yes The Asset that the call created, at pending. Poll asset_get with this id.
expires_at number yes When the upload URL stops being accepted, in milliseconds since the Unix epoch, UTC.
upload_url string yes Send the bytes here with an HTTP PUT and the header If-None-Match: *. The URL is the credential: anybody who holds it can create that one object until it expires. It can never replace the object.

Failure codes

A failed call has isError set, and structuredContent.error holds one of these codes. Errors describes the shape of a failed call.

  • reservation_failed
  • organization_unentitled
  • forbidden
  • invalid_request
  • internal_error

Scope

The token must hold asset:write. Auth & scopes lists each scope.

Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

  • Writes. The tool can change data.
  • Not destructive. The tool makes only additive changes.
  • Not idempotent. A second call with the same arguments can change more.
  • Closed world. The tool reads and writes the data of AdCrunch only.

Example

The arguments:

{
  "filename": "spring-sale.mp4"
}

The result, in structuredContent:

{
  "asset_id": "ast_7c1e9a",
  "expires_at": 1790003600000,
  "upload_url": "https://b7f3c81a29d64e0fa5c3d1e8b0947265.r2.cloudflarestorage.com/assets/org_3a7f10/ast_7c1e9a?X-Amz-Expires=3600&X-Amz-Date=20260921T141320Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=4f8e2a6c1b9d7e3f5a0c2b4d6e8f1a3c%2F20260921%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=7d1c4a9f2e8b0536c1a7e94d2b6f038a5c1e9b7d3f6a2c805d4e1b93a7f0c625"
}

Was this page helpful?