Ingest
Send events to ScryWatch over HTTP.
POST /api/ingest
Ingest a batch of events (up to 50 per request). Each event is canonicalized (message template, event ID, fingerprint) and enqueued to Cloudflare Queues; the response returns immediately and is decoupled from storage.
Auth: API key (Bearer) · Content-Type: application/json
Request body
| field | type | required | description |
|---|---|---|---|
| events | array | yes | 1–50 event objects |
| events[].timestamp | number | yes | Epoch ms |
| events[].level | string | yes | error | warn | info | debug |
| events[].type | string | yes | crash | session | navigation | api_call | custom | cron | log |
| events[].message | string | yes | Event message |
| events[].user_id | string | no | User identifier |
| events[].session_id | string | no | Session identifier |
| events[].environment | string | no | e.g. production |
| events[].service | string | no | Service name |
| events[].device_type | string | no | Device type |
| events[].metadata | object | no | Arbitrary JSON |
| events[].trace_id | string | no | Trace correlation ID |
| events[].span_id | string | no | Span correlation ID |
The log type is normally produced by the Supabase log drain (below), but is also accepted directly on this endpoint like any other type.
Response 202
{ "status": 202, "inserted": 3 }
inserted is the number of events accepted for processing.
Errors: 400 validation errors, shape { "status": 400, "error": "<message>" }:
"events array is required and must not be empty""batch size must not exceed 50 events""invalid level: <x>""invalid type: <x>""message is required""timestamp is required"
Common auth/limit responses (401, 402, 429) apply — see Authentication.
POST /api/ingest/supabase
Accepts a Supabase Generic HTTP log drain payload: a JSON array of Logflare events, optionally gzip-compressed (send Content-Encoding: gzip and the worker decompresses before parsing). Auth via Authorization: Bearer <project API key> set as a custom header on the drain (same key type as /api/ingest). Each event is mapped to a log-type event, with its source auto-detected (postgres | auth | api | storage | realtime | edge_functions | unknown) from the Logflare metadata shape, then filtered per the project’s Supabase drain config before being handed to the same ingest pipeline as /api/ingest.
Auth: API key (Bearer, set as a custom header on the drain) · Content-Type: application/json
Response 200
{ "received": 120, "kept": 43, "dropped": 77, "inserted": 43 }
If the project’s drain config is disabled, the endpoint still returns 200 with all events dropped (kept: 0, inserted: 0, dropped equal to received).
Errors:
400—"failed to read body (bad gzip?)"/"invalid JSON body"/"expected a JSON array of Supabase log events"413— body too large:{ "error": "body too large", "max_bytes": 8388608 }(decompressed body exceeds 8 MB)413— batch too large:{ "error": "batch too large", "max": 500 }(more than 500 events)
Common auth/limit responses (401, 402, 429) apply — see Authentication.