# Server Ingest API

Server-side event and error ingest for BugWatch. Uses `x-api-key` with `ingest:write` scope. Also includes the browser-session mint endpoint (called server-side to produce a token for the browser).

**Scope required:** `ingest:write`

**Event severity scale**
`trace=10 · debug=20 · info=30 · warn=40 · error=50 · fatal=60`


**Event payload contract**

| Field | Type | Notes |
|-------|------|-------|
| `level` | number or string | `10/20/30/40/50/60` (trace/debug/info/warn/error/fatal) or a level name |
| `time` | number | Epoch **milliseconds**, optional; the server stamps now if omitted |
| `message` | string | Human-readable description |
| `release` | string ≤200 | Build/version label, informational in the body; the real environment binding comes from your API key |
| `environment` | string | Informational only; the actual environment is bound to the API key |
| `eventId` | string | Optional; enables deduplication within a 10-minute window |
| `traceId` | hex string ≤32 | Distributed trace id |
| `spanId` | hex string ≤16 | Span id |
| `tags` | flat object | Scalar string values only; max 50 keys |
| `user` | object | Accepted keys: **`id`, `email`, `username`, `ip`**; any other key is silently dropped |
| `exception` | object | `{type, value, stacktrace: {frames: [{filename, function, lineno, colno}]}}` |
| `causes` | array | Chained-exception causes, outermost first: `[{type, value, stacktrace?}]` (depth 3). Rendered as the Caused-by chain |
| `breadcrumbs` | array | Leading context events |
| `contexts` | object | Named groups of arbitrary structured data, passed through and redacted (legacy `context` is passed through too) |
| `fingerprint` | string or string[] | Optional grouping override (controls how events group into issues) |

> **Producing this from your app:** `user` (global vs concurrency-safe per-request vs per-capture), `tags`, `release`, `contexts`, breadcrumbs and trace IDs are set through the BugWatch SDKs (see [SDK Usage & Event Enrichment](/sdk-usage-event-enrichment)). On the wire each event carries a single merged `user` object; there is no separate per-request-user field.

**POST /api/v1/bugwatch/browser-session**: Mint browser session token (fetch id `endpoint:6ae152d083f212a997c813a1`)

**POST /api/v1/bugwatch/ingest**: Ingest – log event (JSON) (fetch id `endpoint:6ae152d083f212a997c813a2`)
