Skip to Content

Sandbox

The sandbox answers UGC API requests with ads from a fixed set of fictional advertisers, in the same response format as production.

Base URL

https://sandbox.adzen.ai

Paths

PathMethodKeyWhat it does
/ugc/v1/processPOSTYesMatches a post and returns one ad, or the no-match body.
/ugc/swagger-ui/GETNoInteractive API docs.
/ugc/api-docs/openapi.jsonGETNoOpenAPI document.

Send sandbox requests to /ugc/v1/process. Production uses /v1/ugc/process.

Getting a sandbox key

Ask your Adzen account representative for a sandbox key. Use the sandbox key on the sandbox and your production key in production. Send it in the X-API-Key header.

Example

curl -X POST https://sandbox.adzen.ai/ugc/v1/process \ -H 'Content-Type: application/json' \ -H 'X-API-Key: YOUR_SANDBOX_KEY' \ -d '{ "post_id": "thread-12345", "message": "Looking for a good plumber in Seattle, our kitchen sink keeps backing up", "geo_target": { "zipcode": "98103" } }'

The request body is the same as production. See UGC API.

How the sandbox responds

  • About 4 in 5 requests return one ad: the closest match from the fictional catalog.
  • About 1 in 5 requests, chosen at random, return the no-match body { "no_ad_retry_after_seconds": 86400 }. Use these to test your no-match handling. The same post_id can return an ad on the next request.
  • The sandbox applies no length rule to message. Production returns empty ads for a message under 10 characters or over 10,000 bytes.
  • The sandbox does not return { "post_id": "...", "ads": [] }.

Responses use the same format as production. Some values differ from production:

FieldSandbox value
advertiser_nameA fictional brand.
pricing_modelAlways { "type": "CPC", "bid_amount": 0.5 }.
sponsor_logo_urlAlways "".
ttl_secondsAlways 28800.
eligibility_ttlAlways 259200.

Tracking URLs

Sandbox click_through_url and pixel_trackers[].url point at sandbox.adzen.ai and carry {SESSION_ID} only. Use them to test that your code replaces the tracking macros. They are not live URLs: do not request them. Nothing is counted or billed in the sandbox.

Production URLs carry {SESSION_ID}, {EXPERIMENT} and {TREATMENT}. Code that replaces all three works in both environments.

Errors

StatusBodyWhenRetry?
400text/plainThe body is not valid JSON.No. Fix the request.
401{"error":"Missing X-API-Key header"}No key.No. Add the key.
401{"error":"Invalid X-API-Key"}The key is not a sandbox key.No. Check the key.
401{"error":"Profile disabled"}The key is turned off.No. Ask your account representative.
413text/plainThe body is larger than 2 MB.No. Shorten the body.
415text/plainContent-Type is missing or is not application/json.No. Set the header.
422text/plainpost_id or message is missing, empty or the wrong type, or a geo_target field has the wrong type.No. Fix the field.
5xxVariesA temporary error.Yes, with exponential backoff.

A request without a valid key gets 401 whatever its body. Branch on the status code, not the body.

Moving to production

  • Change the host to https://api.adzen.ai.
  • Change the path from /ugc/v1/process to /v1/ugc/process.
  • Use your production key.
  • Call production from a US IP address. Production returns 403 to requests from outside the US, including the click and pixel URLs. The sandbox does not apply this rule.
  • Handle an empty ads array, which the sandbox never returns.
Last updated on