Integration flow

The main integration flow is the direct wrapper path around job creation, decision delivery, generation reporting, and beacons.

  1. 1

    Import and initialize CslClient

    Initialize the client with baseUrl, getApiKey, and optionally decisionDelivery plus timing, wrapper_version, and error observation options.

  2. 2

    Create a job

    Send app context and prompt information through createJob(). The response returns job_id and slot_ids.

  3. 3

    Report generation started

    Report model generation start through reportGeneration(jobId, "started", request).

  4. 4

    Retrieve the decision

    Retrieve the sponsor decision for the first slot through getDecision(slotId) using auto, websocket, polling, or callback-driven delivery.

  5. 5

    Continue and finish generation

    Continue model generation and then report finished or, if needed, failed.

  6. 6

    Render fill or handle no-fill

    On fill, render creative, respect constraints, and use asset_token. On no-fill, react to reason and cs_declaration.

  7. 7

    Send beacons after fill

    Send wrapper beacon events such as rendered, visible_started, visible_ended, or clicked through sendBeacon().

What goes into `createJob()` today

Data flow: The job payload, including the prompt, is sent to the CSL, wavebird's middleware layer. It is not sent to the ad market. The CSL data firewall extracts only an abstract topic category and the language before any signal reaches external SSPs. Raw prompt text never leaves the CSL.

  • job_type, model_id, locale, consent, and slots_requested form the minimum request shape.
  • prompt accepts either a string or an object with text and an optional token_count_estimate.
  • decisionDelivery can be auto, websocket, polling, or callback at the client level.
  • callback_url opts a job into callback delivery even when the client-level mode is not "callback".
  • Optional fields include latency hints, client identifiers, routing hints, and callback settings for advanced delivery flows.

What comes back

  • From createJob() you get accepted job metadata or null when the SDK falls back silently.
  • From getDecision() you get pending or ready decisions, preserving constraints and cs_declaration.
  • From sendBeacon() you get { accepted, reason_code }. reportGeneration() always resolves.

node-server.ts

typescript

WRAPPER FLOW
await client.reportGeneration(job.job_id, "started", {
  generation_id: `gen_${job.job_id}`,
  model_id: "gpt-4o-mini",
});

const slotId = job?.slot_ids[0];
const decision = slotId ? await client.getDecision(slotId) : null;

if (decision?.fill === true) {
  await client.sendBeacon({
    beacon_id: `rendered-${Date.now()}`,
    asset_token: decision.asset_token,
    beacon_type: "rendered",
    occurred_at_ms_client: Date.now(),
  });
}

await client.reportGeneration(job.job_id, "finished", {
  generation_id: `gen_${job.job_id}`,
  model_id: "gpt-4o-mini",
});

Ask about integration

Ask about integration

Start with Node direct for the recommended production-ready integration path.