CslClient

RELEASED

CslClient is the wrapper-facing entry point for the SDK server and browser package paths. It carries the core paths for jobs, decisions, generation events, and beacons.

Public request methods are fail-silent by design. Use options.onError to observe structured CslSdkError values and machine-readable CslSdkErrorCode values.

Methods

createJob(request: JobRequest): Promise<JobResponse | null>

Creates a wrapper job and returns accepted job metadata, a typed rate-limit result, or null on fail-silent transport or contract failure.

ParameterTypeRequiredDescription
requestJobRequestyesCreate-job payload. job_type is the only required field; everything else is optional.

Returns

Resolves to accepted JobResponse metadata with job_id and slot_ids, { error: "rate_limit_exceeded", retry_after_ms }, or null when the SDK falls back silently.

Notes

  • Use callback_url inside request when the job should switch to callback delivery.
  • Transport or contract failures are observed through options.onError, not thrown as hard failures.
getDecision(slotId: string, options?: { wait_ms?: number }): Promise<DecisionResponse>

Returns a normalized DecisionResponse union. Ready decisions preserve constraints and cs_declaration.

ParameterTypeRequiredDescription
slotIdstringyesOne slot id from createJob(). The SDK resolves it through polling, WebSocket, auto, or callback-aware delivery rules.
options{ wait_ms?: number }noOptional polling wait budget for direct decision reads when the integration wants to tune the long-poll request.

Returns

Resolves to DecisionResponse, which can represent pending, no-fill, or fill outcomes.

Notes

  • When decisionDelivery is "auto", the SDK prefers WebSocket where available and falls back to polling.
reportGeneration(jobId: string, event: GenerationEvent, request?: GenerationRequest): Promise<void>

Reports started, finished, or failed generation events to the public wrapper API.

ParameterTypeRequiredDescription
jobIdstringyesAccepted wrapper job id returned by createJob().
eventGenerationEventyesLifecycle stage: "started", "finished", or "failed".
requestGenerationRequestnoOptional lifecycle payload such as generation_id, model_id, usage_json, or error.

Returns

Resolves when the lifecycle event has been handed off through the public wrapper API.

Notes

  • Use the same jobId for every lifecycle update tied to one wrapper job.
sendBeacon(request: BeaconRequest): Promise<BeaconResponse>

Sends wrapper beacons such as rendered, visible_started, visible_ended, clicked, and related public beacon types.

ParameterTypeRequiredDescription
requestBeaconRequestyesPublic beacon payload with beacon id, asset_token, beacon type, client timestamp, and optional measurements.

Returns

Resolves to BeaconResponse, which acknowledges whether the beacon was accepted and may include reason_code.

Notes

  • Send beacons only after a fill decision because asset_token comes from the filled response.
  • Revenue requires the full beacon sequence, not just rendered: banner and native use rendered -> visible_started -> visible_ended, while clip uses rendered -> play_started -> play_completed.

Important `createJob()` fields

The table below highlights the minimum request fields most integrators need first when wiring `createJob()`.

createJob() request

Released public JobRequest shape

FieldTypeRequiredDefaultDescription
job_typestringyesnoneType of job, for example "chat".
slots_requestednumberno1Number of sponsoring slots.
model_idstringno"unknown"Optional model identifier.
localestringno"en"Optional locale code, for example "en-US".
context.topicstringnononeOptional context hint for matching without sharing prompt text.
prompt{ text?: string; token_count_estimate?: number } | stringnononeOptional prompt context when your integration chooses to send it.
consentConsentFlagsnoserver defaultsOptional privacy and consent configuration.
slot_config{ allowed_formats?: ("banner" | "clip" | "native")[]; max_width?: number; max_height?: number; position_hint?: "above" | "below" | "sidebar" | "between"; bidfloor?: number; bidfloorcur?: string }nononeOptional slot and bidfloor hints.
brand_safety{ blocked_categories?: string[]; blocked_domains?: string[] }nononeOptional category and advertiser blocking controls.

Error handling

Public methods stay fail-silent. Observe SDK failures through options.onError, then handle null or incomplete results in your integration code.

  • CslSdkError is the structured error object surfaced through options.onError.
  • CslSdkErrorCode is the machine-readable companion for transport, timeout, parse, WebSocket, HTTP, and internal failure categories.
  • Treat null from createJob() as a failed handoff and keep your app path moving without assuming a sponsored slot exists.

Documented `CslSdkErrorCode` values

  • sdk_http
  • sdk_network
  • sdk_timeout
  • sdk_websocket
  • sdk_parse
  • sdk_internal

error-handling.ts

typescript

ONERROR
const client = new CslClient({
  baseUrl: "https://api.wavebird.ai",
  getApiKey: () => process.env.WAVEBIRD_SECRET_KEY ?? "",
  options: {
    onError: (error) => {
      console.error(error.code, error.message, error.cause);
    },
  },
});

const job = await client.createJob(request);

if (!job) {
  // Fail-silent path: inspect telemetry or your onError hook.
}

The cause field may contain the originating Error when the SDK can preserve that underlying failure context.

Package and client types

Jobs and decisions

Lifecycle and contracts

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.