Integrate with the API (browser)
Fetch the ad as JSON from the user's browser, render it however you want, and fire the impression pixel when it's visible.
1. Get your placement ID
Create a placement in the publisher dashboard and copy the ID. Register the domain you'll show ads on.
2. Fetch the ad
Call the serve endpoint from your client JavaScript. Add ?test=1 while developing to receive ads without recording impressions. Full parameter reference: Serve endpoint parameters.
const res = await fetch(
`https://adventory.to/api/ad/serve?p=${PLACEMENT_ID}`
);
const { ad } = await res.json();
if (!ad) {
// No-fill: hide the slot or show fallback content.
return;
}3. Render the ad
The response gives you everything you need to build the UI. Full shape and types: Serve response reference.
product_name: bold title, e.g. "Acme Analytics"headline: tagline / supporting copylogo: image URL (may be null)cta_text: button labelcolors.background,colors.text,colors.cta_background,colors.cta_text: brand hex colors for the container, text, and CTA buttonplacement_type:bannerorcard, in case you render both
<div style={{
background: ad.colors.background,
color: ad.colors.text,
}}>
{ad.logo && <img src={ad.logo} alt="" />}
<strong>{ad.product_name}</strong>
<p>{ad.headline}</p>
<a
href={ad.click_url}
target="_blank"
rel="noopener sponsored"
style={{
background: ad.colors.cta_background,
color: ad.colors.cta_text,
}}
>
{ad.cta_text}
</a>
</div>The sponsored rel value marks the CTA as a paid placement, per the Google guidance for paid links. The attribution link in the next step uses rel="noopener" only because it's a disclosure, not a paid link.
4. Show attribution
Every paid impression must show one of ad.attribution.texts (e.g. "Ad", "Sponsored") linked to ad.attribution.url, visibly near the ad. This is a publisher requirement, not a suggestion.
<a
href={ad.attribution.url}
target="_blank"
rel="noopener"
style={{ fontSize: 10 }}
>
{ad.attribution.texts[0]}
</a>Full attribution rules: Attribution guidelines.
5. Fire the impression pixel
Fire ad.impression_url once the ad has been visible for at least 1 second. Use IntersectionObserver to watch the ad container, then trigger the pixel with an Image object (the universal tracking-pixel idiom: no CORS concern, fire-and-forget):
const adEl = document.querySelector("#my-ad");
let timer = null;
let fired = false;
const io = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting && !fired && timer === null) {
timer = window.setTimeout(() => {
new Image().src = ad.impression_url;
fired = true;
io.disconnect();
}, 1000);
} else if (!entry.isIntersecting && timer !== null) {
clearTimeout(timer);
timer = null;
}
}, { threshold: 0.5 });
io.observe(adEl);The browser sets the Referer header for you; as long as the page is on your registered domain, the impression is recorded. Pixel mechanics (1-hour dedup window, caching rules): Impression pixel reference.
6. Confirm it's working
The first real impression flips your placement to active in the dashboard. See Verification for the lifecycle, or Troubleshooting if nothing records.
Reference
- Serve endpoint: full parameter and response reference.
- Impression pixel: dedup window, caching rules.
- Click tracking.
- Domain validation: what the Referer check does and which origins are blocked.