Skip to Content

Ads

An ad is the creative and its landing page. It takes its price, surfaces and geo targets from its ad set.

On the ai and ugc surfaces, Adzen uses your copy as written. On static, Adzen writes the call to action for each publisher page, using your cta as the starting point.

Which creative fields a placement shows depends on the placement’s ad format. body, price and the image appear only on formats that have a slot for them.

The ad object

{ "id": "ad_2864", "object": "ad", "ad_set_id": "adset_8271", "external_id": "cr-99812", "name": "Water heaters, same day", "status": "active", "review_status": "approved", "effective_status": "active", "serving_issues": [], "creative": { "brand_name": "Acme Home Services", "title": "Same-day water heater repair", "body": "Licensed Dallas plumbers. Upfront pricing.", "cta": "Book a plumber", "price": "From $89", "target_url": "https://acme.example/water-heaters", "file_id": "file_5120" }, "created_time": 1791590400, "updated_time": 1791590400 }
FieldTypeRules
ad_set_idstringRequired on create. adset_8271 or 8271. Cannot change.
namestringOptional. 1 to 256 characters with no control characters. For your reference; never shown to readers. null clears it.
external_idstringOptional. 1 to 256 characters with no control characters. Unique within the ad account. null clears it.
creativeobjectRequired on create.
creative.brand_namestringRequired. Up to 100 characters.
creative.titlestringRequired. The headline. Up to 120 characters. On the ugc surface, a title over 120 bytes in UTF-8 is shortened at a word and ends in …. Keep it to 120 bytes to show it in full everywhere.
creative.bodystringOptional. One or two sentences, up to 500 characters.
creative.ctastringOptional. The call to action, like "Book a plumber". Up to 50 bytes in UTF-8. Defaults to "Learn more".
creative.pricestringOptional. Like "From $89". Up to 40 characters. Shown as written on formats with a price slot.
creative.target_urlstringRequired. Starts with https:// and has a host. Up to 2,048 characters. Any domain, like a tracking redirect.
creative.file_idstringOptional. An image from POST /files in the same ad account as the ad, sent as a string like "file_5120".
statusstringRead-only: active, paused, archived. Change it with the status endpoints.
review_statusstringRead-only: in_review, approved, rejected.
rejection_reasonsstring[]Read-only. On an ad, this field is in the object only when review_status is rejected, and absent otherwise (the ad account always returns it). 1 to 10 reasons written by Adzen’s reviewers, each up to 200 characters.
effective_statusstringRead-only: active, inactive, archived. See Serving status.
serving_issuesobject[]Read-only. Why the ad is not serving: { code, message, source: { object, id } }. Empty when effective_status is active.
created_timeintegerRead-only. Unix seconds.
updated_timeintegerRead-only. Unix seconds. Moves on any change to the copy, name, external id, status or review, and when effective_status or serving_issues change. See Serving status.

Creative text

RuleDetail
TrimmingEvery text field is trimmed. Limits count characters after trimming.
ContentNot empty, and no control characters. A newline is a control character.
cta50 bytes in UTF-8, so 50 ASCII characters or fewer non-ASCII ones.
null on updateClears body, cta (back to “Learn more”), price and file_id. null on brand_name, title or target_url is a 400.
Unknown keysA key not in this table is a 400 invalid_value (unknown parameter creative.<key>).

A failed rule is a 400 invalid_value with param set to the field, like creative.title.

Create an ad

POST /ads

Ads are created paused and go to Adzen review. An ad serves when its effective_status is active. See Serving status.

HeaderRequiredValue
AuthorizationYesBearer YOUR_API_KEY
Content-TypeYesapplication/json
Idempotency-KeyNo1 to 255 visible characters. See Idempotency.
curl -X POST https://api.adzen.ai/v1/ad-manager/ads \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: 8d1c-cr-99812' \ -d '{ "ad_set_id": "adset_8271", "external_id": "cr-99812", "creative": { "brand_name": "Acme Home Services", "title": "Same-day water heater repair", "body": "Licensed Dallas plumbers. Upfront pricing.", "cta": "Book a plumber", "price": "From $89", "target_url": "https://acme.example/water-heaters", "file_id": "file_5120" } }'

The response is 200 with the new ad object, status paused and review_status in_review.

StatuscodeWhenRetry?
404not_foundNo such ad set in your organization (param is ad_set_id), or no such image in the ad’s ad account (param is creative.file_id)No
409archivedThe ad set or its campaign is archived and takes no new adsNo
409ad_account_archivedThe ad account is archivedNo
409external_id_conflictThe external_id is already used in this ad accountNo

Retrieve, list and update

MethodPathNotes
GET/adsList; filter with ad_set_id, campaign_id, external_id, status, review_status
GET/ads/{id}
POST/ads/{id}Update name, external_id and the creative. Send only the creative fields you are changing.

On GET /ads, status must be active, paused or archived, and review_status must be in_review, approved or rejected. A malformed ad_set_id or campaign_id, like abc, returns an empty list. GET /ads/{id} and POST /ads/{id} return 200 with the ad object.

An update with an empty body, {}, changes nothing and returns the ad as it is. Changes to name and external_id apply right away, with no review.

Editing a live ad

Any update that includes creative sends the ad to in_review, even when the values are the same as before. The creative fields you send are merged over the current ones.

The ad before the editWhile the edit is in reviewIf the edit is approvedIf the edit is rejected
ApprovedThe approved creative keeps serving. GET returns the edited creative with review_status in_review.The edited creative serves.The approved creative keeps serving. GET returns it with review_status rejected and rejection_reasons.
Never approvedThe ad is not serving. GET returns the edited creative.The ad can serve.The ad stays off.

If Adzen rejects an ad that has no edit in review, the ad stops serving until you send an edit and Adzen approves it.

Status changes, and changes to the ad set’s price or the campaign’s flight dates and budgets, apply right away with no review.

Concurrent changes

One change to an ad runs at a time. An edit or status change that arrives while another is running on the same ad is a 409 ad_busy. Retry with backoff for up to 30 seconds.

Change status

MethodPath
POST/ads/{id}/activate
POST/ads/{id}/pause
POST/ads/{id}/archive

Each returns 200 with the ad object.

  • Archive is final. activate or pause on an archived ad is a 409 archived. archive on an archived ad returns 200.
  • activate on an ad in an archived ad account is a 409 ad_account_archived.

Images

POST /files

Upload an image and use it on any ad in the same ad account.

HeaderRequiredValue
AuthorizationYesBearer YOUR_API_KEY
Content-TypeYesmultipart/form-data (cURL’s -F sets it)
Idempotency-KeyNo1 to 255 visible characters. See Idempotency.

The body is multipart/form-data with exactly these fields:

FieldRequiredValue
ad_account_idYesAn ad account in your organization, like acct_61
purposeYesad_image
fileYesThe image: PNG or JPEG, up to 25 MB
curl -X POST https://api.adzen.ai/v1/ad-manager/files \ -H 'Authorization: Bearer YOUR_API_KEY' \ -F ad_account_id=acct_61 \ -F purpose=ad_image \ -F file=@water-heater.jpg

The response is 200 with the file object. Use its id as creative.file_id; ads reference images only by id.

{ "id": "file_5120", "object": "file", "ad_account_id": "acct_61", "purpose": "ad_image", "content_type": "image/jpeg", "width": 1200, "height": 1200, "bytes": 482113, "created_time": 1791590400 }
RuleValue
FormatsPNG or JPEG
SizeUp to 25 MB (26,214,400 bytes)
DimensionsAny. The file object returns width and height in pixels. Square 1200 x 1200 px images display best. Review rejects an image that won’t render well on Adzen’s surfaces.
StatuscodeWhenRetry?
400invalid_imageThe file is empty or over 25 MB; it is not a PNG or JPEG; or its part’s Content-Type names another format or is not a valid type. param is file.No
400invalid_valuead_account_id or file is missing, purpose is not ad_image, or the form has another field; param names itNo
404not_foundNo such ad account in your organization; param is ad_account_idNo

A file part with no Content-Type, or application/octet-stream, is accepted when its bytes are a PNG or JPEG.

GET /files and GET /files/{id}

List the images in your ad accounts, or retrieve one, for example to recover an id after a timed-out upload. GET /files is a list, newest first by default; filter with ad_account_id. Its updated_after filter compares against created_time. Each item, and the response of GET /files/{id}, is a file object.

Error responses

Errors use the Ads API error body. Authentication errors, the non-US 403, 429 rate_limit_exceeded and 503 temporarily_unavailable apply to every endpoint and are listed in Errors.

StatuscodeWhenRetry?
400invalid_valueA field failed validation, is unknown or is read-only; param names itNo
400invalid_jsonThe body is not JSONNo
400invalid_imageThe upload is not a PNG or JPEG of 25 MB or lessNo
404not_foundNo such ad, ad set, ad account or file in your organization. For a file the creative names, param is creative.file_id.No
409ad_busyAnother change to this ad is runningYes, with backoff, for up to 30 seconds
409external_id_conflictThe external_id is already used in this ad accountNo
409archivedThe ad, or on create its ad set or campaign, is archived and cannot changeNo
409ad_account_archivedThe ad account is archived; nothing in it can changeNo
409managed_by_adzenAdzen manages this object; it can be read but not changed.No
503upstream_unavailableThe request did not completeYes, with backoff. On a create, resend with the same Idempotency-Key.
Last updated on