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
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
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
const decision = await campaign.decide({
slots: ["homepage-hero"],
path: "/pricing?source=ignored"
});
// Only /pricing is sent.
console.log(decision.appliedTokens);slotscontains up to 20 unique safe slot names.pathis normalized to a pathname of at most 2,048 characters. Query parameters and fragments are not sent.assignmentTokenaccepts a signed tday bootstrap. Redirect handoffs normally supply and consume this automatically through the reservedtd_atquery parameter.
Decision result
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
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. eventIduses 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.
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.
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