On this page

Logs

Search the API requests, Auth, REST server, Postgres and Edge Function logs of a project, kept 7 days on Free up to 90 days on Enterprise.

LimitFreeProScaleEnterprise
Log retention7 days30 days60 days90 days

Open your project and choose Logs. Every project's logs are collected about once a minute and kept for your plan's log retention: 7 days on Free, 30 on Pro, 60 on Scale and 90 on Enterprise.

#Sources

SourceWhat it has
API requestsEvery request to your project URL: time, method, path with the query, status, response time, size, client IP and user agent. Query strings that carry an API key, a token, a password or a code are replaced by [redacted].
AuthThe Auth service: sign-ins, sign-ups, token refreshes, e-mails sent, errors.
REST serverThe server behind /rest/v1: start-up, schema reloads and errors.
PostgresYour database's errors and warnings, and schema changes (DDL).
Edge FunctionsWhat your functions write with console.log, console.warn and console.error, start-up errors and limit stops.
  • Search: every word must appear in the line (any field); put a phrase in quotes. Not case-sensitive.
  • Time: from the last 15 minutes up to your plan's retention. Lines are newest first; Load older continues below the last one.
  • Level: errors only, warnings and errors, or everything. Status (API requests): 2xx to 5xx.
  • Live refreshes every 5 seconds. Click a line for all its fields.

A search reads at most 72 hours or about 100 MB of logs at a time. When it stops before finding anything, Search older continues from there.

#From the API

Terminal
curl "https://stitchdb.com/platform/v1/projects/<ref>/logs?source=api&status=5xx&since=2026-10-25T00:00:00Z" \
  -H "Authorization: Bearer $STITCHDB_TOKEN"
ParameterMeaning
sourceapi, auth, rest, postgres or functions
since, untilISO date and time (default: your plan's retention, now)
q, level, statusThe filters above (level: error, warn, info; status: 404 or 4xx)
limitLines per page, up to 1,000 (default 100)
cursorThe next value of the previous page

The answer has lines (each with t time, l level, m message and the source's fields), next (null on the last page) and retention_days. Any team member can read logs; access tokens need the projects:read scope. AI tools read them with get_logs (MCP).

#Log queries

To count, group and measure log lines instead of reading them, send a log query. It looks like SQL but never runs on a database: StitchDB reads it with a strict grammar and evaluates it over the log store. Log queries are available from the API, and to AI tools as query_logs.

Terminal
curl -G "https://stitchdb.com/platform/v1/projects/<ref>/logs/query" \
  -H "Authorization: Bearer $STITCHDB_ACCESS_TOKEN" \
  --data-urlencode "query=SELECT status, count(*) AS n, p95(ms) FROM api WHERE status >= 500 GROUP BY status ORDER BY n DESC LIMIT 20" \
  --data-urlencode "since=6h"

You can also POST the same path with { "query": "SELECT …", "since": "…", "until": "…" }. More examples:

SQL
-- Slowest paths in the last hour
SELECT path, count(*), p95(ms), max(ms) FROM api GROUP BY path ORDER BY p95(ms) DESC LIMIT 10

-- 5xx per minute, for a chart
SELECT minute, count(*) FROM api WHERE status_class = '5xx' GROUP BY minute ORDER BY minute

-- Function errors by function
SELECT function, count(*) FROM functions WHERE l >= 'error' GROUP BY function

-- Distinct client IPs that failed to sign in
SELECT count(distinct ip) FROM api WHERE path LIKE '/auth/v1/token%' AND status >= 400
PartWhat you can use
SELECTFields, *, and the aggregates count(*), count(f), count(distinct f), sum, avg, min, max, p50, p90, p95, p99. Name a column with AS; otherwise it is called count, p95_ms and so on.
FROMapi, auth, rest, postgres or functions
WHERE= != < <= > >=, IN (…), NOT IN, LIKE and ILIKE (% any text, _ one character), IS [NOT] NULL, AND, OR, NOT and parentheses. Strings go in single quotes.
GROUP BY, ORDER BY, LIMITGroup by any field; order by a field, a column name or an aggregate, ASC or DESC; at most 1,000 rows (default 100).
SourceFields
Every sourcet (time), l (level: debug < info < warn < error, so l >= 'warn' works), m (message), minute and hour (the time cut to the minute or hour, for time buckets)
apimethod, path, status, status_class (for example '5xx'), ms, bytes, ip, ua, id
authmethod, path, status, status_class, component, action, request_id, error_code, event
postgresseverity, user, pid
functionsfunction, version, kind, execution_id
restOnly the common fields

since and until take an ISO time or a duration such as 15m or 6h. The default is the last hour. One query covers at most 24 hours, within your plan's retention; run several queries for longer periods. There are no joins, subqueries or other functions. A query is at most 4,000 characters.

The answer has columns, rows, the since and until it used, and scanned (hours, lines and bytes read). A query reads at most 256 MB or 2 million lines and runs at most 25 seconds. Past that, the answer has partial: true and counted_from, the time from which lines were counted; narrow the time range to get a full answer. When other log queries are running, you get 429 with Retry-After: 5. Access tokens need the projects:read scope and share the logs rate limit (a burst of 30, then 1 request a second).

To send these logs to Datadog, Loki or your own endpoint as well, add a log drain.

#How logs are stored

Lines are kept in EU object storage, encrypted (AES-256), in hourly files per project and source. The current hour is searchable within about a minute; a project that writes more than 50,000 lines of one source in a minute keeps the first 50,000 and a note of how many were left out.