Api

Intake Event

POST
/v1/track/events

Accepts one canonical Event of any type. A purchase sends type: "purchase" and its economic facts in purchase; the server derives its key and time. A tenant-defined type, which starts with custom_, sends its type, sourceEventId, and occurredAt. Names without the prefix are reserved. A participant has one signup, so a signup can leave out sourceEventId and occurredAt: its key is then derived from the participant, and its time is the receipt. A second signup with another key gets 409. Every Event gets an attribution decision. The first Event of a qualifying type of the Project (by default signup and purchase) with an eligible touch creates the referral; a later Event of any type uses the referral, and the referrer and referee rules of its type then evaluate it. The subject rules of the Programs in which the participant is enrolled evaluate every Event. A type that is not built in, not a qualifying type of the Project, and not named by a benefit rule of the Project is refused with 422. An Event carries no browser data. Only a signup can carry identify: { handle }, which identifies the handle of the browser where the account was created to the participant of the signup, as POST /v1/identify does, in the same transaction. The handle comes from a browser cookie, so any string of at most 4096 characters is accepted. A failed identification never fails the Event: the response then has identified: false. A retry of a stored signup identifies no handle. Every Event can carry refCode: the one referral code that the referee entered. It is part of the facts. The code counts when its owner was enrolled in the code's Program when the Event occurred (or when RefRef received it, for an Event dated after its receipt), the Program is active, and the owner is not the participant of the Event; otherwise RefRef ignores it. When the Event creates the referral, a code that counts wins over every click. A purchase under a policy that requires a new customer counts a code only on a first order, as it does a click.

Authorization

WorkspaceApiKey
X-Api-Key<token>

Workspace-owned Better Auth API key of one environment (Sandbox or Live); it authorizes the Projects of that environment in its Workspace. A Project of the other environment returns 403 ENVIRONMENT_MISMATCH. Never expose it in the browser.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/track/events" \  -H "Content-Type: application/json" \  -d '{    "projectId": "string",    "sourceNamespaceId": "string",    "participant": {      "kind": "individual",      "externalId": "string"    },    "type": "purchase",    "purchase": {      "resourceType": "invoice",      "externalResourceId": "string",      "paidAt": "string",      "currency": "string",      "currencyExponent": 0,      "paidAmountMinor": "string",      "taxMinor": "string",      "commissionableAmountMinor": "string"    }  }'
{  "success": true,  "eventId": "string",  "participantId": "string",  "processingState": "pending",  "processingReason": "awaiting_attribution",  "identified": true}