Run SQL Statement
POST/api/v2/report-builder/sql/run
Run a SQL statement and return preview rows.
reports:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Every statement passes the same safeguards: it must be a single read-only SELECT (CTEs, UNIONs, subqueries and window functions are supported); every table it reads must be on the SQL-reports allowlist (see Get SQL Schema); schema-qualified references, variables, placeholders, locking clauses, SELECT ... INTO, stored routines and a small set of unsafe functions (SLEEP, BENCHMARK, LOAD_FILE, GET_LOCK, sequence functions, ...) and server-information functions (DATABASE(), USER(), CURRENT_USER, VERSION(), CONNECTION_ID(), ...) are rejected. A few columns that hold access tokens (purchase_orders.share_token, purchase_invoices.share_token) can never be read: naming them anywhere is rejected, and so is SELECT * / alias.* on a table that has one — list the columns you need instead. Statements run in a read-only transaction with a per-statement time limit and a row cap, and every execution is recorded in an audit log.
Columns are described from the result set, so they are returned even when there are no rows. Date-time values are returned as stored (UTC). truncated is true when more rows exist than the cap; export to get them all. sql_executed is the exact statement run, including the row-cap wrapper.
When the database estimates the statement will scan more than 500,000 rows it is queued as a background job instead: the response is 202 with a tracked_job_log_id, and the finished CSV is available from that background job's results.
Requires the reports.sql permission (administrators always have it). Personal access tokens need the reports:write scope (reports:read is enough for Get SQL Schema). Users without the permission receive 403.
Rate limited to 30 runs per minute per user.
Body:
sql(string, required, max 20000): the statementlimit(integer, optional, 1-5000, default 500): preview row cap
Request
Responses
- 200
- 202
- 401
- 403
- 422
- 429
OK
Response Headers
Accepted
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden
Response Headers
Unprocessable Entity
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.