Ingest API event schema
Events sent to the Ingest API follow a fixed schema. Only the fields listed below are read and stored; extra fields are ignored (no error).
Example payload (minimal)
{
"event": "page_view",
"user_hash": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234abcd",
"customer_org_id": "org_123",
"path": "/dashboard/"
}
Example payload (all optional fields)
{
"event": "feature_used",
"user_hash": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234abcd",
"customer_org_id": "org_xyz",
"path": "/settings/",
"plan": "premium",
"environment": "production",
"ts_epoch": 1738000000,
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
(user_hash must be exactly 64 characters; the examples above use a 64-character hex string.)
Field reference
-
event(string, required)
Event name (e.g.page_view,feature_used). 1–255 characters. The field isevent, notevent_name. -
user_hash(string, required)
Pseudonymized user identifier. Exactly 64 characters (e.g. SHA-256 hex). -
customer_org_id(string, required)
B2B tenant/organization identifier. Non-empty. Numbers are coerced to string. -
path(string, required for page-level analytics)
Page or resource path (e.g./,/dashboard). Required for page views and for Pages / Top pages analytics; if omitted, those reports have no data. Must start with/. Max 2048 characters. -
session_id(UUID string, optional)
Client session id. If omitted, the server infers a session (30‑minute bucket + context). -
plan(string, optional)
e.g. plan tier. -
environment(string, optional)
Environment label (e.g.production,staging). Max 32 characters. Field name isenvironment, notenv. -
ts_epoch(integer, optional)
Unix timestamp in seconds. You don’t need to send it—if omitted, the server uses receive time. Only send when you need a different event time (e.g. backfill). Non‑negative, not more than ~1 year in the future. Field name ists_epoch, nottimestamports. -
properties(object, optional)
Free-form metadata for analytics. Used by AI usage events (ai_call_completed,ai_call_failed,ai_output_accepted,ai_output_rejected,ai_output_edited) to carry feature, provider, model, token counts, cost, latency, success flag, workflow id and value signals. You may nest AI fields underproperties.ai(they are flattened at ingest). Ingest runs managed cost resolution when provider/model are present (catalog + aliases + optional explicit cost). Only metadata is stored — do not send prompts or generated content. See Tracking AI usage for the full field list and examples.
Validation and errors
- Validation errors (invalid payload, e.g. wrong
user_hashlength orpathnot starting with/) return HTTP 400 with a descriptive message. - Invalid signature returns 401 Unauthorized.
- Unknown app UUID returns 404 Not Found.
path
path is required for page views and for page-level analytics (Pages, Top pages, Page details). Many reports depend on it. If you send events without path, those reports will have no or incomplete data. When provided, path must start with / (e.g. /, /dashboard, /settings).
Paths are treated as case-sensitive. If your application uses dynamic IDs (e.g. /tasks/123/edit), consider normalizing paths client-side for meaningful page aggregation.
Extra fields
Extra fields are ignored and not stored. They are not available in analytics queries. Only the whitelisted fields above are persisted; the request still succeeds.
customer_org_id and B2B
- customer_org_id identifies the B2B tenant. For example, send
"customer_org_id": "acme_corp"for all events belonging to that customer. - The current version uses a single level of organization; sub-org hierarchies are not in the schema.
ts_epoch
Optional. If you omit ts_epoch, the server records the event with the time at which it received the request. You only need to send ts_epoch when the event time should differ from receive time (e.g. batched or backfilled events). The field name is ts_epoch (Unix seconds), not ts or timestamp.
session_id
- Optional. If you send session_id, it must be a valid UUID string. The server uses it as-is.
- If you omit session_id, the server infers a stable session from (company, app, environment, customer_org_id, user_hash) and a 30‑minute time bucket, so events in the same bucket for the same user/org get the same inferred session. For true browser sessions, sending a client-generated session_id is recommended.
Batch requests
The API accepts a single event per request (one JSON object per POST). An array of events is not supported; use one request per event. For high-volume systems, send events asynchronously and in parallel rather than batching them in a single request.
Next: Data model – Entities or Overview.