Skip to main content
The POST /v2/analytics.getRuntimeLogs endpoint runs SQL queries on the logs that your deployments write to stdout and stderr. Use it from a trusted backend with a root key. Never put a root key in browser code. For the request and response schemas, see the API reference.

Authenticate the request

Use a root key with the project.*.read_runtime_logs permission. This permission gives access to the runtime logs of all projects in the workspace. The gateway requests need the project.*.read_gateway_requests permission. Unkey limits each query to the workspace of the root key. A query cannot read the data of a different workspace, and it cannot remove this filter.

Send a query

Send a JSON object with a query string. The response contains meta.requestId, which identifies the API request, and data, which contains an array of result objects.
Response
Queries follow the SQL limits and the resource limits in Query restrictions. Only SELECT queries are permitted. CTEs, subqueries, UNION, and EXCEPT are also permitted.

Select the logs of one project, app, environment, or deployment

Each row contains project_id, app_id, environment_id, and deployment_id. Add a filter on one of these columns to get the logs of one target. You can also combine them, for example app_id = 'app_1234' AND environment_id = 'env_1234'.
If you do not add one of these filters, the query reads all projects in the workspace.

Choose a time range

Your workspace retention setting controls the time range that a query can request. A query for a longer range gets a 400 response. If you do not add a time filter, Unkey limits the results to your workspace retention range. The time column holds Unix milliseconds, thus a time filter uses toUnixTimestamp64Milli.

Reference available columns

The table contains one row for each log line. Unkey filters workspace_id automatically, thus you do not need to add it to a query. Unkey reads severity from the content of the log line, not from the log level of your logger. A line that reports an error gets error.

Find text in a log

Use lower(message) LIKE '%text%' to find a substring. The lower() form ignores the case of the log line.
Use lower(attributes_text) LIKE '%text%' to search the attributes, and NOT LIKE to remove the lines that you do not want.

Read the structured attributes

The attributes_text column contains the log attributes as a JSON string. A log line with no attributes gives the string {}. This column is never null. Select the column to get the full JSON, then parse it in your own code.
To group or to sort by one attribute, use JSONExtractString to read that attribute as a column.

Count the errors of each deployment

Use countIf to count a subset of the rows in the same query. This example compares the failed lines with all lines of each deployment.

Get a breakdown of the severities

Page through a large result

Use LIMIT and OFFSET to read a large result in pages. Many log lines can have the same time. Thus ORDER BY time alone does not give a stable order, and one row can appear on two pages. Add more columns to make the order stable.

Errors

For the tables that each analytics endpoint accepts, see Invalid analytics table.
Last modified on August 19, 2026