Skip to content

Logs

Every environment keeps its app’s logs: what your code writes with console.log (and info, warn, error, debug), each request with its method, path, status and duration, uncaught exceptions with their stack, and cron and queue runs. Read them with the API, flatstack logs, or the get_logs MCP tool.

What is kept

Plan Logs are kept for
Hobby 3 days
Pro 7 days
Studio 30 days
Unclaimed sandbox 1 day

Lines appear within about 10 seconds. Older lines are deleted once a day; a read never returns lines older than your plan keeps, whatever since asks for.

Secrets are removed before anything is stored, so they can’t be read back later:

  • In objects you log, any field whose name contains token, secret, password, key, authorization or cookie, and fields named body, html, text, prompt, messages or content, become [redacted].
  • In text, name=value and name: value pairs with names like those, Bearer and Basic credentials, passwords in URLs (postgres://user:…@host), and well-known key formats (Stripe, AWS, GitHub, Slack, OpenAI and Anthropic keys, Flatstack tokens, JWTs, private keys) become [redacted].
  • Request query strings are never stored, only the path.
  • A line longer than 8,192 characters is cut.

GET /v1/projects/{projectId}/logs

Needs logs:read. Owners, admins, developers and viewers have it; deploy tokens can carry it.

Query Meaning
environment production (the default) or preview/<name>. A deploy token for one environment reads only that one.
since ISO 8601 (2026-10-29T12:00:00Z) or relative: 30s, 15m, 2h, 7d. Default 1h.
level The lowest level to return: debug, info, warn or error. warn returns warnings and errors.
search Only lines whose message or path contains this text, ignoring case.
limit Lines to return, 1 to 1000. Default 100.
{
  "environment": "production",
  "since": "2026-10-29T11:00:00.000Z",
  "until": "2026-10-29T12:00:00.000Z",
  "retentionDays": 7,
  "lines": [
    {
      "timestamp": "2026-10-29T11:58:02.114Z",
      "level": "error",
      "kind": "request",
      "message": "POST /api/checkout 500",
      "method": "POST",
      "path": "/api/checkout",
      "status": 500,
      "durationMs": 41,
      "deployId": "dep_…"
    }
  ],
  "hasMore": false,
  "warnings": []
}

Lines are newest first. kind is log, request, exception, cron or queue. A request is warn at 4xx and error at 5xx or when your code threw. deployId is the deploy (or rollback) that served the line, or null for the placeholder Worker and for lines logged before 30 October 2026, when deploys started being recorded on each line.

hasMore: true means more lines match than were returned: narrow since or raise limit. warnings says when since reached past your plan’s retention, or when a search had too many logs to read in one go.

Error When
400 validation_failed since, level or limit isn’t one of the forms above
403 forbidden The token has no logs:read
404 not_found No such project or environment in your account, or another environment than a deploy token’s

flatstack logs

flatstack logs                          # the last hour of production
flatstack logs --since 15m --level warn
flatstack logs --env preview/checkout --search "stripe" --limit 500
flatstack logs --json                   # the API's response, for scripts and agents

Live tail (--tail) and filtering by function and end user are coming.

MCP

get_logs takes the same filters as the API: projectId, environment, since, level, search, limit. See Connecting AI tools over MCP.

As Markdown: api/logs.md