Overview — the ad lifecycle
Adzen matches a contextual ad to each piece of user-generated content — a post, comment, or thread — and returns a ready-to-render ad payload.
What “understanding the content” means here
Your users write in their own words, not in keywords. The value Adzen adds is reading those words the way a person would.
| A user writes | What Adzen reads |
|---|---|
| “Our water heater finally died. Anyone know a plumber in Brooklyn who can come out this week?” | Urgent home-services need, plumbing, Brooklyn, this week. Strong commercial intent. |
| “Three weeks into marathon training and my knees are wrecked — do I need better shoes or a physio?” | Running footwear and sports-medicine intent, mid-consideration, unresolved question. |
| “Finally closed on the house! Keys Friday 🎉” | Life event, not a request. Adjacent categories — moving, insurance, furnishing — without a stated need. |
| “Can’t believe that plane crash. Horrifying.” | News, tragedy. No ad. Suppressed regardless of available demand. |
That last row matters as much as the first three. The comprehension that finds the plumber is the same comprehension that refuses the plane crash.
The core endpoint
| Endpoint | When to call |
|---|---|
POST /v1/ugc/process | When a user creates a post or views a thread. Returns the matched ad. |
That is the only call an API integration makes. Prefer a script on the page to backend work? See Ways to integrate.
Why there is only one endpoint. Relevance scoring, brand-safety checks, suppression rules, and advertiser eligibility are handled by Adzen, not in your code. You send content and render a result; we own everything in between, and keep owning it as the rules change.
End-to-end flow
- A user creates a post, or opens a thread, in your product.
- You call
POST /v1/ugc/processwith the content. - Adzen matches against live advertiser demand and applies relevance, safety, and suppression rules.
- You receive either a matched ad or a no-match response (see No match).
- You render the ad, and fire its
pixel_trackersURLs once it is actually visible on screen.
Suppression is ours, not yours
Suppression is handled by Adzen rather than by the caller, and a no-match response is the normal signal that nothing suitable was found for that post.
A no-match is a feature. It means we found nothing worth showing your
users on that post and declined to fill the slot. Treat it as an expected
response and render your default state — not as an error to retry. When the
body is { "no_ad_retry_after_seconds": N }, wait N seconds before asking
about that post again.
Impression tracking
Impression tracking is handled via the pixel_trackers URLs returned on each
matched ad — fire those URLs when the ad becomes visible on screen.
Why viewability matters to you. Firing on actual visibility rather than on render means your impressions reflect ads people actually saw.
See the delivery endpoints.
Two environments
| Sandbox | Production | |
|---|---|---|
| Base URL | https://sandbox.adzen.ai | https://api.adzen.ai |
| UGC path | /ugc/v1/process | /v1/ugc/process |
| Responses | Sample ads (not matched) | Real matched ads |
| Billing | Never charged | Live, per your agreement |
| Key prefix | sandbox- | prod- |
The response schema is identical between environments — if your client works in sandbox, it will work in production. You can build, demo, and QA the entire experience, including the no-match path, with zero budget at risk. Production only accepts requests from the US; see Sandbox.
Ways to integrate
| Method | Status on UGC |
|---|---|
| Direct API | Available — the standard path, described on this page |
| Tag | On request |
Not sure which fits? See Choose your integration.
Next
- Sandbox — build and test without touching billing
POST /v1/ugc/processreference — request, response and headers