Adsourcer Developer

Embed

Ship sponsored results without building ad UI from scratch. Prefetch on your server, render with a React component or iframe.

How it works

  1. Your server calls POST /v1/ads/recommend with your publisher API key
  2. Pass the response (no API key) to the embed as JSON
  3. The embed renders disclosure, pricing, and links through signed click_url
  4. Impression events post back to your page — proxy them server-side to Adsourcer

API keys stay server-side

Never pass your publisher API key to the browser. Prefetch recommend results on your backend and forward only the ad payload to the embed.

Live preview

Same card rendered by the embed route. On your site, load it via iframe or import the React component directly.

adsourcer.io/embed/adsLive preview
via Adsourcer

Marathon Elite 2

Lightweight daily trainer with responsive foam and a nylon plate built for weekly marathon mileage.

Iframe embed

Host an iframe pointed at /embed/ads on adsourcer.io or mirror the route in your app. Pass a base64url-encoded payload via the d query parameter.

embed.html
html
<iframe  src="https://adsourcer.io/embed/ads?d=eyJyZXF1ZXN0X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwic2Vzc2lvbl9pZCI6ImRlbW8tc2Vzc2lvbiIsImFkcyI6W3siYWRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0aXRsZSI6Ik1hcmF0aG9uIEVsaXRlIDIiLCJkZXNjcmlwdGlvbiI6IkxpZ2h0d2VpZ2h0IGRhaWx5IHRyYWluZXIgd2l0aCByZXNwb25zaXZlIGZvYW0gYW5kIGEgbnlsb24gcGxhdGUgYnVpbHQgZm9yIHdlZWtseSBtYXJhdGhvbiBtaWxlYWdlLiIsImNsaWNrX3VybCI6Imh0dHBzOi8vYWRzb3VyY2VyLmlvL2RvY3MvY2xpY2stdHJhY2tpbmciLCJpbWFnZV91cmwiOiIiLCJwcmljZSI6MTM5LCJjdXJyZW5jeSI6IkVVUiIsInNwb25zb3JlZCI6dHJ1ZSwiZGlzY2xvc3VyZSI6IlNwb25zb3JlZCJ9XX0"  title="Sponsored recommendations"  style="width:100%;min-height:220px;border:0"  sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"></iframe>

Or send payloads after load with postMessage:

typescript
const iframe = document.querySelector("iframe"); window.addEventListener("message", (event) => {  if (event.data?.type === "adsourcer:ready") {    iframe.contentWindow.postMessage(      { type: "adsourcer:render", payload: recommendResponse },      "*",    );  }   if (event.data?.type === "adsourcer:impression") {    // POST to your server → Adsourcer /v1/events/impression    fetch("/api/ads/impression", {      method: "POST",      body: JSON.stringify(event.data),    });  }});

React component

Import the embed components directly when you control the React tree. Same payload shape as the iframe — copy from publisher integration.

AdSlot.tsx
tsx
import { AdsourcerAdList } from "@/components/embed"; export function AdSlot({ payload }: { payload: EmbedPayload }) {  return (    <AdsourcerAdList      payload={payload}      onImpression={({ requestId, adId, sessionId }) => {        fetch("/api/ads/impression", {          method: "POST",          body: JSON.stringify({ request_id: requestId, ad_id: adId, session_id: sessionId }),        });      }}    />  );}

Server prefetch

app/api/ads/recommend/route.ts
typescript
import { Adsourcer } from "@adsourcer/sdk"; export async function POST(req: Request) {  const { query, sessionId } = await req.json();  const client = new Adsourcer({ apiKey: process.env.ADSOURCER_API_KEY! });  const result = await client.ads.recommend({ query, sessionId, maxResults: 1 });   if (result.decision !== "SHOW") {    return Response.json({ request_id: result.request_id, ads: [] });  }   return Response.json({    request_id: result.request_id,    session_id: sessionId,    ads: result.ads,  });}

Impressions

The embed fires an impression when an ad is at least 50% visible. Wire onImpression or listen for adsourcer:impression postMessage events, then proxy to POST /v1/events/impression from your server.

If you skip impressions, clicks still attribute via the signed click_url redirect — but view metrics will be undercounted.

Next steps