Skip to main content
Search log lines with the Public API (V2). This is the way to query logs programmatically, including structured (JSON) log data. The GraphQL API does not expose log lines.
If you’re building an AI agent or assistant, AppSignal MCP exposes log search and other monitoring data to agents directly, without calling this API yourself.

Finding your site and source IDs

A log search needs a site_id and one or more source_ids. Both appear in the URL of a log source in AppSignal. Open a log source and read them from the path:

Search log lines

Request body

Set use_expressions to true to use the expression-based query language documented on this page. pagination takes per_page (number), order (ASC or DESC), and a cursor with a time field (an ISO 8601 timestamp, or null for the first page). To fetch the next page, send the timestamp of the last line you received as the cursor.time of the next request.

Example request

Response

The endpoint returns an array of log lines. Each line includes these fields:
Structured fields such as status_code, path, or detail live in the json field, not in attributes. Query them by their exact key as it appears in your log’s JSON (for example, status_code=401 or detail.message:"required").

Query language

When use_expressions is true, the query string supports boolean logic over log line fields and the structured json body.

Operators

String operators (=, !=, :, !:) compare both sides as strings. Numeric operators (>, >=, <, <=) cast both sides to a number; if a value cannot be parsed as a number, that log line is skipped.

Combining expressions

  • AND / OR: severity=error AND hostname:web, or severity=info OR severity=warn.
  • Implicit AND: a space between expressions means AND. severity=error hostname:web is the same as severity=error AND hostname:web.
  • Nesting with parentheses: message:"API request" AND (severity=info OR severity=warn).
  • Precedence: AND binds tighter than OR.
Any operator can be used inside an OR group, not only equality — for example, message:"API request" AND (user.id>1000 OR user.email:"example.com").

Fields

Given a log line with this JSON body:
  • Base fields: message, severity, hostname, and group match the log line’s top-level fields.
  • Nested JSON: use dot notation to reach into the json body, such as status_code=200 or user.id=12345.
  • JSON arrays: index array elements, such as user.roles.0=admin.
  • Escaped dots: to match a literal dot in a key name, escape it. user.location\.country=US matches the key location.country inside user, rather than a nested country object.
  • Default field: a bare term with no field matches message with the contains operator. timeout is the same as message:timeout.
You do not need to prepend attributes. or append a type suffix to query a field — reference it directly by name. See legacy query syntax if you have older queries.

Quoting values

Wrap values that contain spaces or parentheses in double quotes. Otherwise the space splits the value into separate expressions joined by implicit AND.
Only double quotes are recognized. Inside a quoted value, escape a quote with \" and a backslash with \\. For example, message:"value with \"quotes\"" matches the text value with "quotes".

Legacy query syntax

Older queries stored attributes as typed fields, so they had to prepend attributes., append a type suffix (_string, _int), and use a [ ] list for multiple values. The current query language removes all three — reference fields directly and use OR instead of a list:
A query that still uses the legacy syntax returns a 422 with the legacy_log_query_syntax error slug.