conversions.track()
The core call. One canonical conversion event in; a result per configured destination out. Platforms without secrets are skipped. One platform failing never blocks the rest.
Signature
ts
import { createAdscapi } from 'adscapi';
const ads = createAdscapi(); // secrets default to process.env
const results: DestinationResult[] = await ads.conversions.track(
event: ConversionEvent,
opts?: TrackOptions,
);Create the client once at process start. Secrets default to process.env; pass an explicit bag for multi-tenant use.
ts
createAdscapi( secrets?: AdscapiSecrets, // default: process.env options?: AdscapiOptions, // getToken, dedupe, onResult hooks ): AdscapiClient
ConversionEvent
The event shape. Pass raw PII — adscapi normalizes and SHA-256 hashes per platform. Consent is required.
| Field | Type | Notes |
|---|---|---|
name | CanonicalEventName | string | page_view, lead, signup_start, signup, checkout_created, purchase, reply_generated, upgrade_clicked — or any custom string |
value | number? | Conversion value |
currency | string? | ISO 4217, e.g. USD |
user | ConversionUserData? | Match keys — see below |
clickIds | ConversionClickIds? | gclid, fbclid, msclkid, ttclid, twclid, epik, sccid, li_fat_id, rdt_uuid, … |
consent | ConversionConsent | Required. adUserData + adPersonalization booleans; optional gppString, gppSectionIds, tcfString, limitedDataUse |
eventId | string? | Stable id for pixel/CAPI dedup. Auto-filled as ${name}-${eventTime}-${transactionId|email} when absent |
eventTime | number? | Unix seconds |
transactionId | string? | Order / checkout id |
properties | Record<string, string | number | boolean | null | undefined>? | Extra custom data forwarded where supported |
testEventCode | string? | Prefer TrackOptions.testEventCodes — set per destination |
ConversionUserData
Every identity field you have raises match rate. All optional; all raw.
| Field | Type |
|---|---|
email | string? |
phone | string? |
firstName | string? |
lastName | string? |
city | string? |
state | string? (region is an alias) |
zip | string? |
country | string? |
dateOfBirth | string? |
gender | 'm' | 'f' |
externalId | string? |
ip | string? |
userAgent | string? |
fbc | string? |
fbp | string? |
TrackOptions
| Option | Type | Effect |
|---|---|---|
destinations | Record<string, boolean>? | Per-call allow/deny. { meta: false } skips Meta even when configured |
dryRun | boolean? | Log the fan-out without sending. Results come back with dryRun: true |
testEventCodes | Record<string, string>? | { meta: 'TESTxxxxx' } sends a real event to that platform’s Test Events view. Platforms without a documented test param ignore it |
Return — DestinationResult[]
One entry per active destination. Never throws for a single platform failure — check ok.
ts
type DestinationResult = {
platform: string;
ok: boolean;
error?: string; // set when ok === false
dryRun?: boolean; // set when opts.dryRun
deduped?: boolean; // set when a DedupeStore saw this eventId:platform
};Example
ts
import { createAdscapi } from 'adscapi';
const ads = createAdscapi();
const results = await ads.conversions.track(
{
name: 'purchase',
value: 49.0,
currency: 'USD',
transactionId: 'ord_123',
// eventId is auto-derived when absent — set it for cross-pixel/CAPI dedup
user: {
email: 'jane@example.com', // raw — never pre-hash
phone: '+1 415 555 0100',
firstName: 'Jane',
lastName: 'Doe',
city: 'San Francisco',
state: 'CA',
zip: '94107',
country: 'US',
ip: req.ip,
userAgent: req.headers['user-agent'],
fbc: cookies._fbc,
fbp: cookies._fbp,
},
clickIds: {
gclid: body.gclid,
fbclid: body.fbclid,
msclkid: body.msclkid,
ttclid: body.ttclid,
},
consent: {
adUserData: true,
adPersonalization: true,
// optional:
// gppString, gppSectionIds, tcfString, limitedDataUse
},
},
{
// dryRun: true, // log fan-out, send nothing
// testEventCodes: { meta: 'TESTxxxxx' }, // real event → Test Events view
// destinations: { tiktok: false }, // skip one platform this call
},
);
// One platform failing never throws — inspect per destination.
for (const r of results) {
if (!r.ok) console.error(r.platform, r.error);
}Also on the client
ts
// Which platforms are active right now?
ads.destinations.list();
// → [{ key: 'meta', support: 'real-capi', active: true }, …]
// Live credential check (hits each platform API)
await ads.destinations.verify();
await ads.destinations.verify(['meta', 'tiktok']); // optional filterRelated
- Errors — typed hierarchy behind failed destinations
- Pixel helpers — capture click ids client-side, pass them into
clickIds - Getting started
- Node.js guide