Campaign SDK

Campaign SDK reference

Configuration, client methods, response shapes, endpoint contracts, and operating limits for the current 0.1.0 preview build.

Initialize a client

TypeScript
import { init } from "@designtday/campaign-sdk";

const campaign = init({
  siteKey: "td_pub_your_public_installation_key",
  campaign: "homepage-launch",
  consent: "unknown",
  autoDecide: true,
  autoApply: true,
  flushIntervalMs: 5000
});

const firstDecision = await campaign.ready;

Calling init() again destroys the previous singleton. The IIFE build exposes the same functions on window.tday.

Configuration

OptionTypeDefaultDescription
siteKeystringRequiredPublic td_pub_ installation key.
campaignstringRoute dependentPublished campaign slug. Omit only when the installation has one exact host and path route.
endpointstringhttps://tday.com/api/sdk/v1HTTP(S) runtime base URL without credentials, query, or fragment.
visitorIdstringGeneratedOptional customer-managed pseudonymous ID. Never pass PII.
consentunknown | granted | denied | booleanunknownCurrent analytics consent state.
autoDecidebooleantrueDecide after DOM readiness and on same-document navigation.
autoApplybooleantrueApply valid manifests to matching declared slots.
flushIntervalMsnumber5000Event flush interval from 250 through 60000 milliseconds.
fetchtypeof fetchglobalThis.fetchOptional fetch implementation for controlled browser environments.

Client state and methods

A client exposes a ready promise, current pseudonymous visitorId, normalized consent, and these methods. Automatic initialization resolves ready to null when the initial decision is unavailable.

decide(options?)Request a decision for optional slots, pathname, or signed assignment bootstrap.
track(name, options?)Queue an unverified browser event and return its stable event ID.
expose(token)Queue one explicit exposure for a token in the current decision. Returns null after the first.
setConsent(state)Update consent. A changed state requests a new consent-bound decision token.
setVisitorId(id)Switch the pseudonymous visitor and decide again when enabled.
flush()Attempt to deliver the current event queue.
destroy()Restore the baseline, stop observers and timers, and start a tracked keepalive flush.

The module also exports singleton decide, track, expose, setConsent, setVisitorId, flush, and destroy functions, plus CampaignClient, SDK_VERSION, and fingerprintSlot.

Decision options

TypeScript
const decision = await campaign.decide({
  slots: ["homepage-hero"],
  path: "/pricing?source=ignored"
});

// Only /pricing is sent.
console.log(decision.appliedTokens);
  • slots contains up to 20 unique safe slot names.
  • path is normalized to a pathname of at most 2,048 characters. Query parameters and fragments are not sent.
  • assignmentToken accepts a signed tday bootstrap. Redirect handoffs normally supply and consume this automatically through the reserved td_at query parameter.

Decision result

TypeScript shape
interface DecisionResult {
  decisionId: string;
  releaseId: string;
  assignments: Array<{
    armKey: string;
    token: string;
    manifest: CampaignManifest;
    campaignId?: string;
    releaseId?: string;
    armId?: string;
    page?: Record<string, unknown>;
    destinationUrl?: string | null;
    channel?: { key: string; kind: string };
  }>;
  expiresAt: string;
  appliedTokens: string[];
}

appliedTokens lists assignments whose safe manifest was applied to an unambiguous matching DOM. Headless consumers use the sanitized assignment and call expose(token) when their rendered experience is visible.

Track options

TypeScript shape
interface TrackOptions {
  eventId?: string;
  valueMinor?: number;
  currency?: string;
  properties?: Record<string, unknown>;
  assignmentToken?: string;
}
  • Event names match ^[a-z][a-z0-9_.:-]{0,63}$. The primary conversion name uses exact string equality.
  • eventId uses 1 to 128 safe identifier characters and deduplicates within one SDK installation.
  • Properties are plain JSON, bounded before and after filtering, and sanitized for PII, secrets, unsafe keys, and unsafe URL data.

Runtime endpoints

The default base URL is https://tday.com/api/sdk/v1. Browser endpoints use credential-free CORS and echo only an exact registered origin.

EndpointAuthenticationPurpose
POST /decidePublic key and exact registered OriginReturn a stable, sanitized published assignment.
POST /eventsPublic key or signed tokens and exact registered OriginAccept browser events as unverified evidence.
POST /conversionsSecret key in a header or Bearer tokenAccept trusted server events without requiring an Origin header.

Content Security Policy

The SDK does not use eval, new Function, injected scripts, generated code, arbitrary HTML, or dynamic JavaScript loading. A self-hosted artifact can use a narrow policy.

CSP directives
script-src 'self' 'nonce-YOUR_PER_RESPONSE_NONCE'
connect-src 'self' https://tday.com
img-src 'self' https:
media-src 'self' https:

No unsafe-eval is required. Optional manifest CSS variables use validated element.style.setProperty. Omit CSS variables if your policy forbids inline style attributes. Use a unique nonce for every response, or move initialization into an external script and remove the nonce source.

Continue reading