Skip to Content

Configuration

Sensible defaults, three places to tune.

The SDK has three configurable surfaces: the server-side fetchAdzenAd call, the <AdzenCard> component, and the useAdImpressions hook. There is no automatic environment-variable binding — your application reads environment variables and passes them in.

Environment variables

These are recommended names. Your server code reads them and passes them to fetchAdzenAd.

Required

VariablePurpose
ADZEN_API_KEYAdzen API key for your publisher account. Read server-side only.

Optional

VariableDefaultPurpose
ADZEN_API_URLhttps://api.adzen.ai/v1/aiAdzen API base URL. The SDK appends /process. The default targets the hosted API (AI endpoints under the /ai prefix, so /process resolves to https://api.adzen.ai/v1/ai/process). Override only if Adzen gives you a different base URL.
ADZEN_LOCATION—DMA location code (e.g. "US-CA-803") sent for geo-targeting.
ADZEN_PROFILE_ID—Publisher profile ID, sent as the X-Profile-Id header. Only needed if Adzen support asks you to set it.

Example .env

ADZEN_API_KEY=your_api_key ADZEN_LOCATION=US-CA-803

fetchAdzenAd options

fetchAdzenAd(options: FetchAdzenAdOptions): Promise<AdzenPlacement | null> — from @adzenai/ai. Server-side (it sends the API key).

OptionTypeRequiredDefaultDescription
contentstringYes—The text to match an ad against, sent as content.
messageIdstringYes—Identifier for this placement, sent as message_id. Any stable value (e.g. a message id or a UUID).
apiKeystringYes—Adzen API key. Sent as the X-API-Key header.
endpointUrlstringNo"https://api.adzen.ai/v1/ai"Adzen API base URL. The helper appends /process. Override only if Adzen gives you a different base URL.
timeoutMsnumberNo3000Max time (ms) before the fetch is aborted. Ignored when signal is provided.
locationstringNo—DMA location code sent as a top-level location field for geo-targeting.
conversationIdstringNo—Sent as conversation_id; links impressions to a conversation.
profileIdstringNo—Sent as the X-Profile-Id header.
adUnitPositionstringNo"chin"Used as the placement’s adUnitPosition when the ad carries no placement.
signalAbortSignalNo—Caller-supplied abort signal. When set, timeoutMs is not applied.
const placement = await fetchAdzenAd({ apiKey: process.env.ADZEN_API_KEY!, content: assistantMessage, messageId: msg.id, location: process.env.ADZEN_LOCATION, });

AdzenCardProps

<AdzenCard> from @adzenai/ai/react. Props are dual-mode — supply either a resolved ad (generic usage) or a messageId (CopilotKit event-driven usage), not both.

PropTypeRequiredDefaultDescription
adAdzenPlacementone of ad / messageId—A resolved placement (e.g. the result of fetchAdzenAd). The type doesn’t accept null, and fetchAdzenAd returns null on no match, so render the card only when you have a placement.
messageIdstringone of ad / messageId—Look the ad up from placement events instead (CopilotKit). See the CopilotKit configuration.
adUnitPositionstringNo"chin"Ad unit position label reported for this placement.
viewabilityThresholdMsnumberNo1000Milliseconds the ad must be continuously visible before the view impression fires.
classNamestringNo—CSS class applied to the card’s root element.
{placement && ( <AdzenCard ad={placement} viewabilityThresholdMs={2000} className="my-ad-card" /> )}

The built-in card shows the advertiser avatar (from advertiser_image_url, falling back to the advertiser’s initial), the advertiser name, a “Relevant Ad” disclosure, the headline, and the CTA link (target="_blank", rel="noopener sponsored"). It does not render description — that field is available on the placement for custom rendering.

useAdImpressions

useAdImpressions(ad, options?) => { ref } from @adzenai/ai/react. For rendering your own markup while keeping Adzen impression tracking.

const { ref } = useAdImpressions(placement, { adUnitPosition: "chin", viewabilityThresholdMs: 1000, }); // attach ref to the element that represents the ad
OptionTypeDefaultDescription
adUnitPositionstring"chin"Ad unit position label reported for this placement.
viewabilityThresholdMsnumber1000Continuous-visibility time before the view beacon fires.

Returns { ref } — attach it to your ad element. The render beacon fires once when the ad becomes available; the view beacon fires once the element has been continuously visible for the threshold. Both beacons are skipped when their impression URL is null. AdzenCard uses this hook internally.

Adzen API response format

The Adzen /process API returns:

{ "message_id": "msg_abc123", "ads": [ { "ad_id": 1071, "title": "Local Coffee Co", "cta": "Learn More", "click_through_url": "https://api.adzen.ai/…/redirect/abc1234", "advertiser_name": "Acme Corp", "sponsor_logo_url": "https://example.com/logo.png", "creative_url": "https://example.com/banner.jpg", "description": "A great product", "placement": "chin", "render_impression_url": "https://api.adzen.ai/…/impressions/render", "view_impression_url": "https://api.adzen.ai/…/impressions/view" } ] }

fetchAdzenAd returns the first ad mapped to AdzenPlacement:

API fieldAdzenPlacement field
ads[0].ad_idad_id (coerced to string)
ads[0].titleheadline
ads[0].ctacta_text
ads[0].click_through_urldestination_url
ads[0].advertiser_nameadvertiser_name
ads[0].sponsor_logo_urladvertiser_image_url
ads[0].creative_urlcreative_url
ads[0].descriptiondescription
ads[0].placementadUnitPosition (falls back to the adUnitPosition option)
ads[0].render_impression_urlrender_impression_url
ads[0].view_impression_urlview_impression_url
ads.length === 0returns null

Impression beacons

Both the built-in card and useAdImpressions fire impression beacons as client-side GET requests directly to the delivery API — no server proxy or auth headers required. The impression URLs are pre-built by the API and fired as-is.

  • Render impression — fired on mount, as a GET to render_impression_url.
  • View impression — fired after the viewability threshold is met, as a GET to view_impression_url.

If render_impression_url or view_impression_url is null, that beacon is skipped. A beacon that fails is retried once after 1 second, then dropped silently.

Viewability

Viewability uses IntersectionObserver via @adzenai/core’s observeViewability():

SettingDefaultDescription
Intersection threshold1.0The ad must be 100% visible. Not configurable via AdzenCard / useAdImpressions.
Time threshold1000msContinuous-visibility time. Configurable via viewabilityThresholdMs.
Firing behaviorOnceThe view impression fires once per ad instance.

Error handling and silent degradation

Adzen never throws into your render tree. All failures are silent:

ScenarioBehavior
/process returns non-200fetchAdzenAd returns null
/process times outAborted via AbortController → null
Network errornull
/process returns empty adsnull
ad is nullAdzenCard renders nothing; useAdImpressions is a no-op
Impression beacon failsSingle retry after 1 second, then swallowed

Next

Last updated on