Skip to main content

Events API rules

Scope

This page defines runtime rules for:

  • POST /events
  • POST /events/batch

It focuses on behavior rules and processing semantics. Endpoint fields are covered by API reference docs.

Ingestion identity and dedupe

An event is deduplicated by (billing_account_id, request_hash).

request_hash is computed from canonicalized event facts:

  • billing_account_id
  • semantic_kind
  • event_type
  • occurred_at (ISO timestamp)
  • subject_ref
  • payload

Labels are not part of dedupe identity.

Account and realm scoping

  • Billing account is taken from request context, not caller-provided body identity.
  • Writes are account-scoped and realm-scoped.
  • Missing account context rejects the request.

Validation rules

  • billing_account_id must be present in context.
  • semantic_kind must be activity or outcome.
  • occurred_at must be a valid timestamp.
  • event_type is required and max length is 128.
  • subject_ref is optional; max length is 256.
  • payload must be an object; non-object payload is normalized to {}.

occurred_at semantics

occurred_at is the business event time, not request arrival time.

How it is used:

  • Policy version resolution uses occurred_at to choose the effective active version.
  • Contract term resolution uses occurred_at to select effective term values.
  • Event-to-rating conversion evaluates rules against the event's occurred_at.

Impact on downstream ratings and reports:

  • Late-arriving events are rated under the policy/contract context that was effective at their occurred_at.
  • Time-window reports and traceability views should treat event-time and rating-time as different dimensions.
  • Correct occurred_at is required for accurate backfill, reconciliation, and period analysis.

Recommended usage:

  • Send UTC timestamps from your source system's event clock.
  • Preserve original event time on retries and replays.
  • Do not overwrite occurred_at with API call time.

Payload design for E2R rules

payload is a freeform object, but E2R rules rely on stable field paths and stable value types.

Design rules:

  • Keep field paths stable over time (for example usage.input_tokens).
  • Keep type stable per field (do not alternate between number/string/object).
  • Store billable quantities as numeric values in minor units.
  • Use explicit schema versioning (for example schema_version) when payload shape evolves.
  • Keep high-cardinality diagnostics out of billable rule paths.

How E2R reads payload:

  • Single-event rules read payload by dot-path (for example payload_int: usage.input_tokens).
  • Predicate comparisons and numeric expressions coerce numeric-like values.
  • Aggregate numeric ops (sum/avg/min/max) only work reliably on numeric sources.

Recommended split:

  • payload: business facts and quantities used by pricing/rating logic.
  • labels: low-cardinality dimensions for filtering and reporting dimensions.

Example payload:

{
"schema_version": "v1",
"usage": {
"input_tokens": 1200,
"output_tokens": 340
},
"model": {
"name": "gpt-5",
"tier": "pro"
},
"request": {
"region": "us-east-1"
}
}

/events response semantics

  • First accepted write returns 201.
  • Idempotent replay returns 200.
  • Response returns the canonical event identity, including event_id and request_hash.

/events/batch response semantics

Batch always returns 207 with per-item status.

Per-item status values:

  • accepted: inserted as new event
  • duplicate: deduped against existing event
  • invalid: payload-level validation failed
  • failed: processing failed

Batch summary includes:

  • accepted_count
  • failed_count

Label persistence rules

  • Labels are stored only when an event is newly accepted.
  • Duplicate replays do not rewrite stored labels.
  • Label keys are normalized to lowercase and typed into one value slot (text/uuid/bool/number).

Hand-off to events -> ratings pipeline

  • POST /events:
    • accepted event is enqueued
    • event processing is also attempted inline
  • POST /events/batch:
    • accepted events are enqueued
    • processing is deferred to worker/sweep flow

Verify checklist

  • Same event fact replay returns duplicate behavior (200 or duplicate item status).
  • Changed event fact produces a new event identity.
  • Batch result preserves input order by index.
  • Accepted events appear in processing queue for downstream rating.