SDK integration flow

This is the advanced SDK lifecycle around job creation, decision delivery, generation reporting, and beacons. The default API lifecycle is shorter and lives under /api.

  1. 1

    Import and initialize CslClient

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

  2. 2

    Create a job

    Start with createJob({ job_type: "chat" }), then add optional context, privacy controls, brand safety, or slot hints only when you need them. 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. The filled creative may also include click_through_url and sponsor_name. 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(). Important: only the complete creative-specific sequence generates revenue.

What goes into `createJob()`

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

  • job_type is the only required field. slots_requested defaults to 1.
  • prompt is optional and accepts either a string or an object with text and an optional token_count_estimate.
  • context.topic is the lightest way to provide matching context without sharing prompt text.
  • consent, brand_safety, and slot_config are optional expansion surfaces for privacy, blocking, and placement control.
  • 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 also include publisher metadata, latency hints, client identifiers, routing hints, and callback settings for advanced delivery flows.

What comes back

  • From createJob() you get accepted job metadata, a typed rate_limit_exceeded result, 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",
});

API first, Script Tag second, SDK third

Back to API docsContact the team

These pages are the advanced package layer for teams that intentionally choose @csl/wrapper-sdk. Primary onboarding still lives in the API docs, and browser-first installs should start with the Script Tag. Use contact only when you want rollout review, enterprise coordination, or help with non-standard integration constraints. Beacon billing rules live in SDK Concepts.