JavaScript SDK
Install, client, methods, tag gate, double opt-in and receipt verification.
The SDK wraps the raw API with the plumbing you’d otherwise write yourself: response caching, ETag revalidation, offline receipt verification, and a tag gate that blocks trackers until consent actually allows them.
npm i @croombit/sdkClient
import { CroombitClient } from '@croombit/sdk';
const tc = new CroombitClient({
baseUrl: 'https://api.croombit.com',
apiKey: 'pk_live_…', // sk_live_… on a server
cacheTtlMs: 60_000, // optional
});Methods
recordConsent(params, { idempotencyKey })·recordConsentBatch(records)·recordPreferences(params)getConsentState(subject, { purpose?, fresh? })·getPreferences(subject)— ETag-cachedgetPurposes({ locale? })·getPurpose(key, { locale? })·getPreferenceTemplate()·getPolicy({ country? })getTcString(subject)·getConsentMode(subject)·applyConsentMode(subject, gtag)·getGppString(subject)getReceipt(id)·verifyReceipt(receipt)— Ed25519 offline via Web CryptocreatePortalToken(subject)·createSubject·addIdentifier·mergeSubjects·createDataRequest— requiresk_getConsentHistory(subject, { purpose? })·getPreferenceHistory(subject, { field? })— the append-only history, newest first; requiresk_(see Guide: showing a user their own history)getWebhookEvents()— the webhook event catalog and delivery contract (GET /v1/webhook-events)
recordConsent and recordConsentBatch accept source: 'API' | 'IMPORT' | 'MIGRATION' (default API). IMPORT and MIGRATION mean you assert the record, not the subject, and need an sk_ key — see Who acted: source.
Server helpers
The @croombit/sdk/server entry is for your backend only (Web Crypto, no dependencies; Node 18+, Deno, Bun, edge runtimes):
signIdentityToken(…)— vouch for a logged-in user so apk_key can reach them (guide)constructWebhookEvent({ header, rawBody, secret })— verify a webhook signature and return the typed event; throwsWebhookSignatureErrorverifyWebhookSignature({ header, rawBody, secret, toleranceSeconds? })— the same check as a booleanWEBHOOK_EVENTS·WebhookEventType·WebhookEvent— the event names and types
A complete receiver is in Webhooks: payloads & signature.
Tag gate
// load your scripts only once the subject has granted one of these purposes
await tc.gate('email:user@example.com', ['analytics'], () => loadAnalytics());
// after your banner writes new consent:
tc.notifyConsentChanged();Reading preferences
getPreferences returns the current preference-center state for a subject — channels, topics and typed fields — derived from POST /v1/preferences writes.
const prefs = await tc.getPreferences('email:user@example.com');
// prefs.channels['marketing'].topics['newsletter'].state === 'GRANTED'Double opt-in (email preferences)
For email marketing, many regulations require confirmed opt-in. Use createPreferenceConfirmationToken from your server (it needs an sk_ key — the token is the whole capability, so it must never reach a browser) to trigger the confirmation email; the recipient clicks a link that calls POST /v1/preferences/confirm.
// 1. Write a pending preference and request the confirmation email (server, sk_)
const { token, confirmUrl } = await tc.createPreferenceConfirmationToken({
subject: 'email:user@example.com',
values: [{ field: 'newsletter', value: true }],
channel: 'email',
redirectUrl: 'https://acme.com/subscription/confirmed', // must be on one of your site's domains
});
// Your email service sends confirmUrl — or pass `to: 'user@example.com'` (the subject's own
// address) and Croombit sends it for you.
// 2. No further action needed — the confirmation endpoint writes GRANTED
// and the webhook preference.confirmed fires.getPreferences returns PENDING until the link is clicked.