Server-side (SSAI)
This guide covers calling the Ezoic VAST tag from a server-side ad insertion (SSAI) service, a stitcher, or any other server-side fetcher. Server-side integrations have two failure modes that do not exist on the device. Read the first two sections before anything else.
Rule 1: Forward the viewer's IP and user agent
The tag uses the IP and user agent it receives. Your stitcher's requests carry your data centre's values, which destroy geo targeting and most demand. Send the viewer's values on every request:
&ua=<viewer's user agent, URL-encoded>&ip=<viewer's IP>
Most SSAI platforms expose these as session values or macros. For example, AWS MediaTailor uses [session.client_ip] and [session.user_agent]. Check your vendor's macro table. For IPv6 sessions, send ipv6=.
Rule 2: Check that your macros expand
The tag drops any parameter whose whole value is an unexpanded macro, such as [IFA], {{BUNDLE}} or %%US_PRIVACY%%. The request still succeeds, but you lose that signal and the revenue attached to it. You get no error.
So do not judge the integration by whether it returns VAST. Capture a real session request and check that each parameter carries a concrete value. See Testing and troubleshooting.
Tag template
Replace the {{MACRO}} names with your vendor's macro syntax.
https://g.ezoic.net/ezoic/videoad/vast?bundle={{APP_BUNDLE}}&app_name={{APP_NAME}}&storeurl={{APP_STOREURL}}&app_domain=<YOUR_EZOIC_DOMAIN>&adunit=<YOUR_VIDEO_AD_UNIT>&ifa={{DEVICE_IFA}}&ifa_type={{IFA_TYPE}}&ua={{USER_AGENT}}&ip={{DEVICE_IP}}&lmt={{LMT}}&us_privacy={{US_PRIVACY}}&gdpr={{GDPR}}&consent={{GDPR_CONSENT}}&content_id={{CONTENT_ID}}&content_title={{CONTENT_TITLE}}&content_genre={{GENRE}}&content_cat={{IAB_CATEGORY}}&content_len={{CONTENT_DURATION}}&livestream={{IS_LIVE}}&pod={{POD_ID}}&slot={{POD_SLOT}}&minduration={{MIN_DURATION}}&maxduration={{MAX_DURATION}}&devicetype=3&plcmt=1&v=3&w=1920&h=1080&cb={{CACHEBUSTER}}
Set these once: app_domain (your Ezoic domain), adunit (your normal video ad unit name), devicetype=3, plcmt=1, ssai if you declare it, and v. Use v=3 unless your pipeline needs more.
Declare your SSAI level
Some buyers require this declaration before they buy SSAI inventory. Send ssai only when you know the value.
ssai |
Meaning |
|---|---|
1 |
All client-side. Not server-side at all. |
2 |
Assets stitched server-side, tracking pixels fired client-side. |
3 |
All server-side, stitching and tracking. |
A full server-side stitcher usually sends 3. A stitcher that stitches assets while the player fires tracking usually sends 2. If you are not stitched, omit the parameter.
Ad pods: sequential single-slot requests
The tag returns one ad per request, with no VMAP. To fill a break with several ads:
- Request each slot separately.
- Send the same
podfor the whole break and an incrementingslot, starting at 1. Buyers use these to avoid showing the same creative twice in one break. - Use a fresh
cbfor each call. - Set
mindurationandmaxdurationper slot if the break has a fixed total length. For a 90-second break, for example, request slots withmaxduration=30.
Timeout
The auction budget defaults to 3500 ms. If your stitcher has a tighter per-tag timeout, send tmax with your real budget in milliseconds so the auction finishes inside your window. The tag keeps a 50 ms network buffer, so a request that ends early can still get a fill if the auction is quick. Set tmax to what your stitcher really allows, and test that value end to end.
Response handling
All three response shapes return HTTP 200, after following any 302:
- VAST with an
<Ad>element: stitch it. - Empty VAST document: no fill. Skip the slot, or move down your waterfall.
A response can contain more than one <Ad>. If your stitcher takes only one, use the first. The others are same-request fallbacks, not a pod.
Identity notes
ifaandifa_typecome from the device session, passed through your stitcher's session macros. If they are missing, buyers discount the request, as they would on the device.- If you send universal IDs such as UID2 or RampID, pass them in
eids. Keep to the size and shape limits in Parameters. - Send
schainonly when there are intermediaries between the content owner and Ezoic. Serialize it per the IAB spec exactly, because a malformed chain is dropped.
Go-live checklist
- Viewer
ipanduaare forwarded from session values. Check they are not your server's values. - Every macro expands with a real session. No literal
[...]or{{...}}reaches the tag. -
adunit,app_domain,devicetype=3andplcmt=1are set. -
ssaiis declared, or omitted when you are not stitched. -
podandslotare sent on multi-ad breaks, with a freshcbper call. -
tmaxfits inside your stitcher's per-tag timeout. -
vmatches what your transcoding pipeline accepts.