§ 02 · Getting started
Data model
How events, users, and deliveries relate — and what TrackLayer persists vs forwards.
Data model
TrackLayer is a pipeline with 3 core entities: Event, Delivery, and Alert. Understanding how they relate makes debugging much faster, especially when an event exists in TrackLayer but does not appear in Meta, or appears late, duplicated, or not at all.
At a high level:
business action
-> Event
-> one or more Deliveries
-> zero or more Alerts if the pipeline degradesAn order, a lead form submission, or an add-to-cart action becomes one Event. That Event can fan out to multiple platforms, which creates one Delivery per destination. If the pipeline starts failing, backing up, or dropping below expected throughput, TrackLayer creates Alerts so the problem is visible before attribution data quietly degrades.
Event
An Event is the canonical record of a business-meaningful action. TrackLayer expects one Event per action you care about: Purchase, AddToCart, Lead, CompleteRegistration, and similar conversion events.
The Event is the source of truth inside TrackLayer. It is the durable record you inspect first when you want to answer questions like:
- Did we receive this action at all?
- Did we receive it once or multiple times?
- Which identifiers were attached?
- Which downstream platforms should have received it?
Typical Event fields include:
event_nameevent_idoccurred_atuser_datacustom_data
user_data contains identifiers associated with the actor, such as email, phone, IP, user agent, fbp, fbc, external IDs, or platform-specific cookie values. custom_data contains event-specific business context such as revenue, currency, content IDs, order references, or product metadata.
event_id is your ID, not TrackLayer's. Use a durable identifier from your system whenever possible:
- order ID for purchases
- checkout ID for checkout completion
- CRM lead ID for lead capture
- subscription ID for trial start or conversion
This matters because TrackLayer uses event_id for idempotency. If the same event is sent twice with the same event_id, TrackLayer coalesces it instead of treating it as two independent conversions. That protects you against duplicate webhook deliveries, queue retries upstream, and accidental replay from your application code.
This is what a complete Event payload can look like at ingestion time:
{
"event_name": "Purchase",
"event_id": "order_12345",
"occurred_at": "2026-04-23T14:12:33.000Z",
"user_data": {
"email": "973dfe463ec85785f5f95af5ba3906e64c23a8bce2d4b2b88f8ef90d2640d1b0",
"phone": "a0e4aeb280283d343698dcbf9213bdb2e8e8e7abceb5f106874900ad3a7e1b41",
"client_ip": "203.0.113.42",
"client_user_agent": "Mozilla/5.0",
"fbp": "fb.1.1713877200.1234567890",
"fbc": "fb.1.1713877200.AQzXy1abcDEFghiJKlMNopQR"
},
"custom_data": {
"value": 129.99,
"currency": "USD",
"order_id": "order_12345",
"product_ids": ["sku_123", "sku_456"],
"num_items": 2
}
}Think of the Event as normalized input. It should describe the business action once, with enough identity and value context for downstream transformations to work.
Delivery
A Delivery is the platform-specific attempt to forward an Event to a destination.
There is one Delivery per (event, platform) pair. If a purchase event is routed to Meta and TikTok, that produces:
- one Event
- two Deliveries
This separation is important because a single Event can be healthy while one Delivery fails. That lets you answer the right question. "Did the order exist?" is different from "Did Meta acknowledge the order?"
Each Delivery has its own lifecycle. The status is one of:
queueddeliveredfaileddropped
queued means TrackLayer accepted the Event and scheduled the outbound work. delivered means the destination acknowledged the request. failed means an attempt failed but can still be retried. dropped means TrackLayer gave up after exhausting the retry policy or deciding the Delivery should not continue.
Latency is tracked per Delivery as the time between Event arrival and platform acknowledgment. This is useful because a healthy pipeline is not just one that eventually succeeds. It also needs to succeed within a reasonable time window for attribution and optimization systems to stay useful.
TrackLayer retries failed deliveries with exponential backoff, up to 5 attempts over 24 hours. If the platform still does not accept the request after that window, the Delivery status becomes dropped.
A Delivery row might look like this:
{
"event_id": "order_12345",
"platform": "meta",
"status": "failed",
"attempts": 3,
"last_error": "400 Invalid fbc format",
"queued_at": "2026-04-23T14:12:34.102Z",
"last_attempt_at": "2026-04-23T14:25:10.917Z",
"latency_ms": null,
"next_retry_at": "2026-04-23T15:05:10.917Z"
}When debugging a platform issue, this is usually the entity you inspect second, right after confirming the Event exists. If the Event is present and the Delivery is failed or dropped, the problem is almost always in credentials, routing, platform schema transformation, or destination-side validation.
Alert
An Alert is an operational signal created by TrackLayer's cron workers when pipeline conditions degrade.
Alerts are not business events and they are not delivery attempts. They exist to answer a different question: is the system behaving abnormally enough that a human should look at it?
TrackLayer can create alerts such as:
platform_downqueue_backlogtracking_stoppeddelivery_rate_drop
These appear in the dashboard at /notifications and can also be sent by email when that channel is enabled.
Examples:
platform_down: Meta or another destination is consistently rejecting or timing out requests.queue_backlog: events are arriving faster than workers can process them.tracking_stopped: a merchant that usually sends events has gone quiet.delivery_rate_drop: the success rate fell below the normal baseline.
Alerts do not replace logs or Delivery history. They are early warning signals that reduce the chance of silent failure.
What we persist
TrackLayer persists enough information to audit the pipeline, replay debugging context, and support retention requirements without storing unnecessary sensitive data.
By merchant setting, Events are retained for 30, 90, 180, or 365 days. Deliveries follow the same retention window so you can inspect the Event and its downstream outcome over the same period.
For user_data, email and phone hashing use SHA-256 per merchant setting, with hashing enabled by default. That means TrackLayer can receive normalized identifiers and persist them in a form suitable for platform matching without keeping plaintext values where they are not needed.
TrackLayer does not persist raw credit card data. Payment card numbers, CVCs, and similar cardholder data are out of scope for the Event model and should never be sent in custom_data or user_data.
In practice, a persisted Event should contain:
- enough identity for attribution and matching
- enough business context for reporting and transformation
- enough metadata for retry, deduplication, and troubleshooting
It should not become a general-purpose dump of every payload your application knows about.
What we forward
TrackLayer forwards Event data to platform conversion APIs after transforming it into each platform's required schema.
Conceptually, this is:
Event.user_data + Event.custom_data
-> platform mapper
-> destination-specific payload
-> platform CAPIThe forwarded shape is not identical across platforms. Meta, TikTok, Google Ads, Pinterest, and others all have different naming rules, required fields, normalization requirements, and acceptance criteria. TrackLayer handles that transformation layer so you do not maintain a separate payload contract for every destination.
That said, your source Event still needs to be correct. Platform mappers can translate field names and formats, but they cannot invent missing business identifiers or recover user context you never captured.
See the relevant platform guide under the flat docs slugs, such as /docs/platforms-meta or /docs/platforms-google-ads, for platform-specific rules and caveats.
Identity stitching
Identity stitching is how TrackLayer connects multiple requests or visits back to the same person or session strongly enough for downstream matching to work.
TrackLayer uses two main sources:
- a first-party cookie for cross-visit continuity
- merchant-hashed email as a secondary identifier
The cookie acts like a stable browser-scoped key, similar in spirit to fbp, but owned on the TrackLayer side. It helps bridge page views, checkout steps, and server-side events that happen within the same browsing lifecycle. Merchant-hashed email provides a stronger identifier when the user authenticates, checks out, or submits a form.
The retention window for stitched identity data follows merchant settings. That gives you control over how long TrackLayer can connect historical activity across visits.
Identity stitching improves match quality, but it does not change the Event model itself. It enriches the context around the Event so Deliveries have better odds of being accepted and matched downstream.
See /docs/dedup for how event_id deduplication actually works, or /docs/platforms-meta for a Meta-specific walkthrough.