Skip to content

Events API

Ingest event batches with sdk.events.v1.EventsService/BatchCreate — full request schema, property wrapping and validation rules.

Updated View as Markdown

Ingest events from SDKs and server-side integrations using sdk.events.v1.EventsService/BatchCreate.

Auth: x-api-key header (public key pub_… or private key prv_…). No Authorization header or x-project-id is required — the project is resolved from the key. See Authentication.

BatchCreate

POST /sdk.events.v1.EventsService/BatchCreate

Validates and enqueues up to 1 000 events in a single request. Returns the count of accepted events. There is no single-event endpoint — all ingestion goes through this method.

All google.protobuf.Timestamp fields (here, occurTime, and timestampValue inside a PropertyValue) serialize as RFC 3339 strings — e.g. "2026-06-05T10:00:00Z".

Event fields

Proto field JSON name Type Required Notes
event_id eventId string Yes UUID (any version; UUIDv7 recommended for time-sortability)
auto_properties autoProperties map<string, PropertyValue> No Context set by the SDK or server. Keys must start with $. $bot_score and $verified_bot are server-only — any client-supplied value is stripped and replaced from CDN headers
custom_properties customProperties map<string, PropertyValue> No Your event properties. Keys must not start with $
distinct_id distinctId string Yes Anonymous or identified user ID
kind kind string Yes Event name. Must not start with pug. (reserved prefix)
occur_time occurTime google.protobuf.Timestamp → RFC 3339 Yes When the event occurred
session_id sessionId string Yes UUID grouping events in a visit

Proto field names (snake_case) and lowerCamelCase are both accepted by the Connect JSON codec. The lowerCamelCase forms shown above are canonical.

PropertyValue — typed property wrapper

Every value in customProperties and autoProperties is a wrapped object that names its type explicitly. This is the Connect JSON encoding of the protobuf oneof.

Variant JSON shape Notes
String { "stringValue": "hello" } Max 1 024 Unicode code points. Values exceeding the limit are rejected with invalid_argument (not truncated)
Integer { "intValue": "42" } int64 — the value is a JSON string, not a number
Double { "doubleValue": 3.14 } Must be finite (NaN and ±Infinity are rejected)
Boolean { "boolValue": true }
Timestamp { "timestampValue": "2026-06-05T10:00:00Z" } RFC 3339; stored at millisecond precision

Exactly one variant must be set per PropertyValue object. Proto snake_case aliases (e.g. string_value) are accepted as well.

Validation summary

All rules above enforced together; any violation fails the request with invalid_argument:

  • Batch size — at most 1 000 events per BatchCreate call.
  • eventId, sessionId — must be valid UUIDs.
  • $bot_score, $verified_bot — server-only; any client-supplied value is dropped and re-set from the CDN-injected CF-Bot-Score/CF-Verified-Bot headers.

(Property-key prefix rules, stringValue length, and doubleValue finiteness are covered in the Event fields and PropertyValue tables above.)

Request / response shape

Property values are typed PropertyValue wrappers. Every value in customProperties and autoProperties names its type explicitly — intValue (int64) must be a JSON string, doubles are bare numbers, etc. (see the table above). This is not how profile traits work: Identify’s traits are plain JSON, not PropertyValue-wrapped — see Profiles.

BatchCreateRequest

{
  "events": [
    {
      "eventId":   "<uuid>",
      "distinctId": "anon-abc123",
      "kind":       "page_view",
      "sessionId":  "<uuid>",
      "occurTime":  "2026-06-05T10:00:00Z",
      "customProperties": {
        "plan":  { "stringValue": "pro" },
        "seats": { "intValue": "5" },
        "mrr":   { "doubleValue": 299.0 },
        "trial": { "boolValue": false }
      },
      "autoProperties": {}
    }
  ]
}

BatchCreateResponse

{ "accepted": 1 }

accepted (uint32) is the number of events that passed validation and were enqueued. It equals the number of events in the request when all events are valid.

Errors

These are the codes BatchCreate returns in practice — a subset of the full error model:

Connect code HTTP status Cause
unauthenticated 401 Missing or invalid x-api-key
invalid_argument 400 Validation failed — see the message field for which rule
resource_exhausted 429 Rate limit exceeded
internal 500 Server error — retry with exponential backoff

Error responses follow the Connect envelope:

{
  "code": "invalid_argument",
  "message": "event kind must not use reserved prefix 'pug.'"
}

Further reading

Navigation

Type to search…

↑↓ navigate↵ selectEsc close