Skip to main content

Event Shape

Each event in a flush batch conforms to SunglassesEvent:

interface SunglassesEvent {
type: 'capture' | 'screen' | 'identify' | 'alias' | 'group';
event: string; // e.g. 'button_clicked', '$screen', '$error'
properties: Record<string, unknown>;
anonymousId: string; // UUID v4 — device identity
distinctId?: string; // Set after identify()
timestamp: string; // ISO-8601 UTC
messageId: string; // UUID v4 — deduplication
context?: {
library?: { name: string; version: string };
app?: { name?: string; version?: string; build?: string; variant?: string; update?: AppUpdateInfo };
environment?: string;
features?: string[];
entitlements?: string[];
traits?: Record<string, unknown>;
sessionId?: string;
screen?: string;
platform?: string;
};
}

HTTP batch payload​

HttpStorageAdapter POSTs:

{
"batch": [ /* SunglassesEvent[] */ ],
"sentAt": "2026-06-26T12:00:00.000Z"
}

Ingest server Parquet columns​

When using the ingest server, events are flattened to:

ColumnTypeNotes
event_typeVARCHARcapture, screen, identify, …
eventVARCHAREvent name
distinct_idVARCHARUser ID (may be hashed)
anonymous_idVARCHARDevice UUID
tsVARCHARISO-8601 event timestamp
message_idVARCHARDeduplication UUID
propertiesVARCHARJSON — PII-sanitized
contextVARCHARJSON — library/platform metadata
received_atVARCHARServer receive time
dtVARCHARYYYY-MM-DD partition key

Synthetic events​

EventWhen emitted
$screenScreen tracking
$session_startNew session (if enabled)
$errorError capture
$identifyInternal identify representation

$error event properties​

$error events are built by captureException and always carry:

PropertyTypeNotes
$error_messagestringError message (truncated to maxMessageLength, default 200)
$error_typestringerror.name — e.g. "TypeError"
$error_handledbooleantrue = caught boundary / try-catch; false = unhandled global
$error_levelstringSentry-compatible severity — usually "error"
$error_stack?stringParsed stack frames (on by default, capped to maxStackFrames)
$error_component_stack?stringReact errorInfo.componentStack — set by error boundaries
$error_cause?stringerror.cause chain — "Name: msg\ncaused by: …", depth-capped at 3
$error_extra?objectCustom enumerable Error props (code, statusCode, …) — scalar values only
$error_fatal?booleanReact Native ErrorUtils isFatal — absent on web
$error_source?stringOrigin: "boundary", "global", "rejection", or "console"
$error_filename?stringWeb ErrorEvent.filename — source file URL
$error_line?numberWeb ErrorEvent.lineno
$error_column?numberWeb ErrorEvent.colno

All properties pass through PiiSanitizer before being queued.