Skip to content

Ingest one or a batch of tracking events

Primary event-collection endpoint. Accepts a single event object, a bare array of events, or a { "events": [...] } wrapper. Batch size is capped at 100 events (over → 400).

Auth (X-API-Key header, or ?_ak=<key> / ?key=<key> query params — the query forms exist only for navigator.sendBeacon() where headers cannot be set). No explicit scope gate on this route beyond a valid project key.

Validation modes (resolved: key-level validationMode > project settings.ingestValidation.mode > warn): off = no validation; warn = validate but accept; enforce = reject schema-violating events. Only property-schema errors (not envelope warnings like a missing visitorId) cause enforce rejection.

Response mode:

  • default → 202 { accepted, failed, queued, processed:false, invalid? } — events validated and dispatched into ctx.waitUntil; persistence is async and NOT proven. Do not treat 202 as durable persistence.
  • ?sync=1 or X-Trackly-Sync: 1200 { accepted, failed, queued, processed:true, errors?, enforceRejected? } — non-metering events reached D1 + Analytics Engine before the response. For debugging/health checks only.
  • enforce mode + all events rejected (sync path) → 422.

Metering (conversion) events are enqueued synchronously to the metering ingest queue before any response; a missing queue binding or a send failure yields 503. ?debug=1 (or a per-event _debug flag) captures samples into DebugView.

sync
string
Allowed values: 1

1 forces synchronous processing (200 with processed:true). Equivalent to the X-Trackly-Sync: 1 header.

debug
string

When truthy, invalid/accepted event samples are captured into DebugView for the project (best-effort; never affects ingest outcome).

_ak
string

API key fallback (sendBeacon). Prefer the X-API-Key header.

key
string

API key fallback (lowest precedence). Prefer the X-API-Key header.

X-Trackly-Sync
string
Allowed values: 1

1 forces synchronous processing (same effect as ?sync=1).

A single event object, a bare array of events, or a { "events": [...] } wrapper. Max 100 events per request.

Media typeapplication/json
One of:

A single tracking event. eventName is required; everything else is optional. Every field accepts both camelCase and snake_case aliases (e.g. visitorId/visitor_id). Unknown top-level keys are preserved as part of the raw envelope, except the internal derived-event provenance fields (source, derivedRuleId, derivationDepth) which are hard-stripped from external payloads.

object
eventName
required

Event name (aliases event / event_name). Envelope validation expects ^[a-z0-9_]{1,100}$; a non-matching name is a warn-level error (still processed). A missing eventName marks the event invalid.

string
visitorId

Device/browser-level ID (alias visitor_id). Defaults to "anon" if omitted (warn-level).

string
userId

Logged-in user ID (alias user_id).

string
sessionId

Session ID (alias session_id). Tier-1 attribution key.

string
properties

Custom key-value payload. Monetary amounts go in amount (or value) in minor units (cents). currency defaults to CNY. Max ~32 KB serialized (warn-level properties_too_large over the limit).

object
key
additional properties
any
clientTimestamp

Event time, ISO 8601 (aliases client_timestamp / timestamp). Unparseable values are a warn-level error.

string
eventId

Optional client-supplied idempotency/dedup key (alias event_id). Must match ^[A-Za-z0-9_.-]{8,64}$; otherwise it is ignored (with a warning) and the server generates one. REQUIRED for metering events on the backfill endpoint.

string
shortLinkId

Short-link ID for explicit attribution (alias short_link_id).

string
shortLinkCode

Short code for direct-landing attribution (aliases _tk / short_link_code).

string
clickIds

Recommended unified Click ID map covering all 29 ad platforms, e.g. { "bd_vid": "...", "gclid": "..." }. Alternatives: a top-level click_id, or legacy strongly-typed top-level fields (bdVid, gclid, fbclid, … — cover only the earlier ~15 platforms).

object
key
additional properties
string
url

Full page URL; Click IDs are auto-extracted from its query string.

string
landingUrl
string
referrer
string
utmSource

Alias utm_source

string
utmMedium

Alias utm_medium

string
utmCampaign

Alias utm_campaign

string
utmTerm

Alias utm_term

string
utmContent

Alias utm_content

string
Examples

Single purchase event

json
{
"eventName": "user_paid",
"visitorId": "vid_abc123",
"userId": "uid_456",
"sessionId": "sess_789",
"properties": {
"amount": 9900,
"currency": "CNY"
},
"clickIds": {
"bd_vid": "abc",
"gclid": "xyz"
}
}

Synchronous result (?sync=1). processed:true proves non-metering events reached D1 + Analytics Engine.

Media typeapplication/json

Synchronous (?sync=1) ingest response — also the 422 body in enforce mode.

object
accepted
required

Events written to D1 + Analytics Engine (= total minus enforce-rejected).

integer
failed
required

Invalid events plus enforce-rejected events.

integer
queued
required

Metering events enqueued.

integer
processed
required

Always true on the sync path.

boolean
errors

Per-event validation errors (present only when non-empty).

Array<object>

Validation errors for a single event (sync=1 / 422 response).

object
index

0-based batch index.

integer
eventName
string
errors
Array<object>

Structured validation error (envelope or property-schema).

object
field
required
string
rule
required

Rule identifier, e.g. type, required, enum, pattern, minimum, maximum, maxLength, or envelope rules like envelope/event_name_format, envelope/visitor_id_missing.

string
expected

Expected value/constraint (any type).

actual

Actual value/type observed (any type).

message
required
string
enforceRejected

Number of events rejected by enforce-mode schema validation (present only when > 0).

integer

Accepted (default async). Events dispatched to background processing; persistence completes after the response and is not guaranteed.

Media typeapplication/json

Default 202 async ingest response.

object
accepted
required

Events validated and dispatched to background processing (NOT proof of persistence).

integer
failed
required

Count of invalid (unparseable / missing eventName) events.

integer
queued
required

Metering events enqueued to the metering ingest queue.

integer
processed
required

Always false on the async path.

boolean
invalid

Present only when there are invalid events.

Array<object>

An event rejected at the envelope/parse layer.

object
index
required

0-based position in the incoming batch.

integer
rawSample
required

Raw event sample truncated to ≤1KB.

string
reason
required

Human-readable rejection reason (e.g. “缺少 eventName 字段”).

string
Example
json
{
"accepted": 2,
"failed": 0,
"queued": 2,
"processed": false
}

Invalid JSON body, or batch exceeds 100 events.

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Examples
json
{
"error": "无效的 JSON 格式"
}

Missing or invalid API key.

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Examples
json
{
"error": "缺少 X-API-Key 请求头"
}

Enforce mode and every event was rejected (sync path only).

Media typeapplication/json

Synchronous (?sync=1) ingest response — also the 422 body in enforce mode.

object
accepted
required

Events written to D1 + Analytics Engine (= total minus enforce-rejected).

integer
failed
required

Invalid events plus enforce-rejected events.

integer
queued
required

Metering events enqueued.

integer
processed
required

Always true on the sync path.

boolean
errors

Per-event validation errors (present only when non-empty).

Array<object>

Validation errors for a single event (sync=1 / 422 response).

object
index

0-based batch index.

integer
eventName
string
errors
Array<object>

Structured validation error (envelope or property-schema).

object
field
required
string
rule
required

Rule identifier, e.g. type, required, enum, pattern, minimum, maximum, maxLength, or envelope rules like envelope/event_name_format, envelope/visitor_id_missing.

string
expected

Expected value/constraint (any type).

actual

Actual value/type observed (any type).

message
required
string
enforceRejected

Number of events rejected by enforce-mode schema validation (present only when > 0).

integer
Example
json
{
"accepted": 0,
"failed": 1,
"queued": 0,
"processed": true,
"enforceRejected": 1,
"errors": [
{
"index": 0,
"eventName": "user_paid",
"errors": [
{
"field": "amount",
"rule": "type",
"expected": "number",
"actual": "string",
"message": "Field amount: expected number, got string"
}
]
}
]
}

Transient infra failure. SELECTOR_LOOKUP_FAILED (retryAfter 30) when the metering-selector lookup fails; QUEUE_UNAVAILABLE (retryAfter 60) when metering events are present but the queue binding is absent or the enqueue send failed.

Media typeapplication/json

503 transient error with a suggested retry delay.

object
error
required
string
Allowed values: SELECTOR_LOOKUP_FAILED QUEUE_UNAVAILABLE
retryAfter
required

Suggested seconds to wait before retrying (30 or 60).

integer
Examples
json
{
"error": "SELECTOR_LOOKUP_FAILED",
"retryAfter": 30
}