Authenticate requests
Both endpoints read the ingest key from one of these places:- The
x-squasher-key: <key>header. - The
Authorization: Bearer <key>header. - The
keyquery parameter (?key=<key>), for tools that cannot set headers.
403. To get
both values, see Create an ingest key.
Send an event
200 response means that Squasher accepted the event. An event at error or fatal level
becomes an issue.
To send more than one event, use one of these bodies:
- A JSON array of event objects.
- An object with an
eventsarray. - One event object on each line, with
Content-Type: application/x-ndjson.
message. If an event or line is not valid, Squasher rejects the full
request with 400 and names the event or line.
Event fields
Automatic AI triage runs only on issues in the
production environment by default. Set
environment on events that must be triaged.
Send log lines to the drain endpoint
The drain endpoint takes JSON log records in any shape and keeps a few known fields. The platform guides, such as Vercel and Fly.io, use it.<source>is a name that you choose, with lowercase letters, digits,_, and-. Squasher stores it on each record and uses it as the service name when a record has none.- Send a JSON array of objects, or one JSON object on each line. Squasher skips lines that are not JSON objects. A JSON array must contain only objects.
- Syslog bodies also work: Heroku
application/logplex-1octet-counted frames, or one RFC 5424 message on each line. See Heroku. - The body can be gzip or
deflatecompressed. Squasher also detects gzip without aContent-Encodingheader. Other encodings return415. A body can be at most 16 MiB, before and after decompression. A larger body returns413. - Add
?environment=<name>to the URL to set the environment of records that have none. The name can contain letters, digits,.,_, and-, up to 64 characters. - Squasher skips a record that has
"squasher.skip_ingest": true.
What Squasher keeps from each record
Squasher drops all other fields, including nested objects such as
proxy or metadata. It reads
only top-level keys, except the Fly.io log.level and fly.app.name fields.
Squasher reads a numeric timestamp below 1010 as seconds, below 1016 as
milliseconds, and above that as nanoseconds. A timestamp in microseconds is read as milliseconds,
so convert it before you send it.
How levels become issues
A top-level
level or severity is used as sent. A record without one gets its level from, in
order:
- A platform level that is not
info: the Fly.iolog.level, or the syslog severity. - The message: a JSON
"level"field (pino numbers too),level=errororat=error, the first uppercase level word such asERROR,[WARN], orFATAL:, or a stack trace such asTraceback (most recent call last):,TypeError: ..., orpanic:. info, when nothing matches.
?environment= when your records have no environment field. Otherwise, select Run triage
in the Squasher triage card on the issue to start it by hand.
Squasher groups error records into issues by service, error type, and the first line of the
message. Before it compares messages, it replaces numbers, hexadecimal strings, and UUIDs.
Limits
- Each project can send 10,000 records per minute by default. Squasher counts each log record,
span, and metric point. Above the limit, it returns
429withRetry-AfterandX-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Resetheaders. - A
503response withRetry-After: 1means that ingest is not available for a moment. Retry with backoff. - The events endpoint reads the body as uncompressed text. The drain endpoint also reads gzip and
deflatebodies.
POST /v1/ai/ingest/<project-id>.
Next steps
OpenTelemetry
Send traces, logs, and metrics from any language over OTLP.
Vector
Forward logs from files and containers through a Vector sink.
Node.js SDK
Capture errors with stack traces from Node.js services.
Issues
See how Squasher groups errors into issues.