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). On the wire each event carries a single mergeduserobject; there is no separate per-request-user field.
Mint browser session token
Mints a short-lived browser session token. Call this from your backend with the secret key, then pass the token to your frontend. The secret never reaches the client.
Scope: ingest:write
Send the request with an empty body.
Authorization
x-api-keyAPI key · headerrequiredResponses
200Token minted401Invalid or missing API key403Missing permission scopecurl -X POST 'https://api.newinstance.cloud/api/v1/bugwatch/browser-session' \
-H 'x-api-key: YOUR_API_KEY'{
"token": "eyJhbGciOiJIUzI1NiJ9.example",
"expiresAt": "2026-06-26T12:15:00.000Z"
}Ingest – log event (JSON)
Ingests logs and error events from server-side or CI environments.
Scope: ingest:write
Send Content-Type: application/json with a single event or an array of events, or application/x-ndjson with one event per line. The body can be up to 2 MB.
Event fieldslink
| Field | Type | Notes |
|---|---|---|
level | number | 10/20/30/40/50/60 |
time | number | Unix ms timestamp |
message | string | Human-readable text |
release | string | App build version |
environment | string | production / staging / development |
eventId | string | Optional; enables deduplication within 10-min window |
tags | object | Flat key-value labels (≤50 keys) |
user | object | {id, email, username, ip}. Only these four keys are kept; others are silently dropped |
traceId | string | Hex distributed trace id (≤32 chars) |
spanId | string | Span id |
exception | object | {type, value, stacktrace: {frames}} |
breadcrumbs | array | Leading events |
Send an error eventlink
Set level to 50 and add exception, breadcrumbs and trace ids. The eventId enables deduplication: re-sending the same event within 10 minutes increments deduped instead of ingested, as the duplicate example response shows.
{
"level": 50,
"time": {{nowMs}},
"message": "Uncaught TypeError: Cannot read properties of undefined",
"release": "{{release}}",
"environment": "{{environment}}",
"eventId": "evt_unique_abc123",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"spanId": "00f067aa0ba902b7",
"contexts": { "cart": { "id": "cart_42", "items": 3 } },
"tags": { "component": "checkout" },
"user": { "id": "usr_456", "username": "alice" },
"exception": {
"type": "TypeError",
"value": "Cannot read properties of undefined (reading 'price')",
"stacktrace": {
"frames": [
{ "filename": "checkout.js", "function": "calculateTotal", "lineno": 42, "colno": 15 },
{ "filename": "cart.js", "function": "applyDiscount", "lineno": 88, "colno": 7 }
]
}
},
"breadcrumbs": [
{ "timestamp": {{nowMs}}, "category": "navigation", "message": "Navigated to /checkout", "level": "info" },
{ "timestamp": {{nowMs}}, "category": "ui.click", "message": "Clicked \"Apply coupon\"", "level": "info" }
]
}Send a batch as NDJSONlink
Set Content-Type: application/x-ndjson and put one event on each line. Each line is an independent event. This is the preferred format for batching from server SDKs.
{"level":50,"time":{{nowMs}},"message":"Payment processing failed","release":"{{release}}","environment":"{{environment}}","tags":{"orderId":"ord_789"},"user":{"id":"usr_789"}}
{"level":30,"time":{{nowMs}},"message":"Retry attempt 1 of 3","release":"{{release}}","environment":"{{environment}}","tags":{"orderId":"ord_789"}}Authorization
x-api-keyAPI key · headerrequiredRequest body
application/json{
"level": 30,
"time": {{nowMs}},
"message": "User signed in",
"release": "1.0.0",
"environment": "production",
"tags": { "region": "eu-west-1" },
"user": { "id": "usr_123", "email": "alice@example.com" }
}Responses
202Event ingested401Invalid or missing API key403Missing permission scope429Rate limitedcurl -X POST 'https://api.newinstance.cloud/api/v1/bugwatch/ingest' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data-raw '{
"level": 30,
"time": {{nowMs}},
"message": "User signed in",
"release": "1.0.0",
"environment": "production",
"tags": { "region": "eu-west-1" },
"user": { "id": "usr_123", "email": "alice@example.com" }
}'{
"ingested": 1,
"skipped": 0,
"deduped": 0
}