PQL queries API
PQL (Probara Query Language) reads the organization’s test data: cases, suites, runs, run cases, results, defects, milestones, plans and shared steps. A query names an entity, filters it, and can group and aggregate it. This page covers the endpoints, what they answer, and their limits.
Every entity, field, operator, function and error code of the language is in the PQL language reference.
Queries are available on the Pro and Enterprise plans, the same plans as dashboards. On any other plan every endpoint on this page returns 403 forbidden. dashboardsEnabled on GET /api/v1/orgs/current shows the plan’s setting.
| Method and path | What it does |
|---|---|
POST /api/v1/query | Runs one query and answers one page of rows or groups. |
GET /api/v1/query/schema | Answers the schema a query is checked against. |
Every member can run queries, viewers included. To keep a query and reuse it, see Saved queries.
Run a query
Section titled “Run a query”POST /api/v1/query takes a JSON body:
{ "query": "FROM results WHERE status = failed", "offset": 0 }queryis required: 1 to 4,000 characters.offsetis optional. It overrides the query’s own OFFSET for paging, from 0 to 10,000.
Results cover only the projects the caller can open, and archived projects are never included. scope.hiddenProjectCount counts the organization’s other projects that the caller cannot open, so a result is never shown as complete when projects are hidden.
Response modes
Section titled “Response modes”A query without an aggregate answers rows. Each row is one record, with a link to it and its values, one per column:
modeisrows, andcolumnsnames each column with itskey,labelandtype.totalcounts the matching rows exactly up to 10,000. Past that,totalis 10,000 andtotalCappedistrue.limitis the page size: the query’s LIMIT, 50 by default and 500 at most.offset,scopeandtimeZoneecho the page, the project counts and the zone the query read dates in.timeZoneFallbackistrueonly when the caller’s stored time zone could not be read, so the default zone answered.
A query with a SELECT of aggregates, or a GROUP BY, answers aggregate groups:
modeisaggregate. Each column has arole:groupfor a grouping key,measurefor a value computed per group.- Each row has
valuesand nolink. - Groups are capped at 1,000.
totalcounts them up to that cap, andtruncatedistruewhen there are more. passRate()is the percentage of executed rows that passed: a number from 0 to 100, rounded to one decimal, ornullwhen nothing executed. A result counts as executed unless its status isuntested. For runs, executed means passed, failed, blocked or skipped.passRate()applies to results and runs only.
Saved query references
Section titled “Saved query references”in query("name") and not in query("name") filter the entity’s display id by the rows of another saved query. Names are matched without regard to case.
- The name resolves among the saved queries the caller can see. A query the caller cannot see is unknown, and its name never appears in a hint.
- The referenced query must be a rows query over the same entity. Its WHERE applies under the caller’s own project access. Its
ORDER BY,LIMITandOFFSETare ignored. - A referenced query may reference another, up to three references deep from the query that runs. A cycle is refused.
- The referenced text is checked against the current fields each time the query runs, so a reference always reads the current text of the saved query. A reference that no longer validates answers
pql_invalidwithreferenced_query_invalid. - The refusals appear in
details.errors:unknown_value(no visible query has the name),query_entity_mismatch,query_not_rows,query_depth_exceeded,query_cycleandreferenced_query_invalid.
Schema
Section titled “Schema”GET /api/v1/query/schema answers what a query is checked against, for the caller:
customFields: the custom fields that apply to the caller’s projects, with their options.membersandgroups: the active members and the user groups.savedQueries: the names of the saved queries the caller can see, sorted by name. The schema answers at most 500 of them, andsavedQueriesTruncatedistruewhen there are more. A reference to any visible name still resolves.hints: the value lists for suites, milestones, plans, environments, projects and tags. Each is truncated at 500 names, withtruncatedset when there are more.
Errors
Section titled “Errors”Every error answers { "error": { "code", "message" } }, with a details object when there is more to say.
| Status | Code | When |
|---|---|---|
403 | forbidden | The organization’s plan does not include dashboards, so queries are off. |
422 | validation_failed | The body is not JSON, the query is empty or longer than 4,000 characters, or offset is outside 0 to 10,000. |
422 | pql_invalid | The query does not parse or does not validate. details.errors lists every error. |
422 | pql_unsupported | The query uses a construct a later release adds. details.construct names it. |
Each entry in details.errors has a stable code, a localized message, a span (offset, line, column and length) that points at the offending text, the expected tokens or fields, and an optional hint, such as a name the query may have meant.
Export as CSV
Section titled “Export as CSV”POST /api/v1/query/export takes the query text alone, and answers the rows of the query as CSV:
{ "query": "SELECT title, created FROM cases ORDER BY title" }- The export has the same checks, scope and access as a run, and refuses what a run refuses with the same codes and statuses.
- A rows query writes its rows in their order, up to 10,000. The
X-Pql-Export-Truncatedheader istruewhen more rows matched. - An aggregate query writes up to 1,000 groups, with its grouping keys and measures as columns.
- The query’s own
OFFSETandLIMITdo not apply to an export. - The body is UTF-8 with a byte order mark and CRLF record ends. The first record holds the column labels.
- Values are machine values: a time is its ISO-8601 UTC instant, a duration is milliseconds, a person, an option or a reference is its name, and the tags of a row are joined with
;. - A text a spreadsheet would read as a formula, one that starts with
=,+,-,@, a tab or a carriage return, is written with a leading quote. Content-Dispositionnames the filequery-YYYY-MM-DD.csv.X-Pql-Time-Zone-Fallbackistruewhen the stored time zone could not be read.
The saved query export is documented with the saved queries API.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Query text | 4,000 characters |
OFFSET | 10,000 at most |
LIMIT (page size) | 50 by default, 500 at most |
Rows total | Counted exactly up to 10,000, then totalCapped |
| Groups | 1,000 at most, then truncated |