No credit cardStart free

Execute API

Run SQL queries programmatically. One endpoint, one API key, instant results.

Quick Start

bash
curl -X POST https://api.rawquery.dev/api/v1/execute \
-H "X-API-Key: rq_your_api_key" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT 1 AS num"}'

Authentication

The Execute API uses API keys via the X-API-Key header. This is separate from JWT Bearer tokens used by the dashboard.

Getting an API Key

bash
rq api-keys create --name my-key

Or go to Settings > API Keys in the dashboard. The key starts with rq_.

Using the API Key

text
X-API-Key: rq_your_api_key_here

Or via the Authorization: Bearer header if you prefer (both work with rq_ keys).

POST /api/v1/execute

Execute a SQL query and return results. Supports Postgres-compatible SQL syntax.

Request Body

json
{
"sql": "SELECT * FROM my_stripe.customers LIMIT 10",
"format": "json",
"workspace_id": "optional-uuid"
}
FieldTypeRequiredDescription
sqlstringYesSQL query (DuckDB syntax)
formatstringNojson (default), csv, or objects
workspace_iduuidNoTarget workspace. Defaults to your first workspace.

Response (JSON)

json
{
"columns": [
{ "name": "id", "type": "VARCHAR" },
{ "name": "email", "type": "VARCHAR" }
],
"rows": [
["cus_abc123", "alice@example.com"],
["cus_def456", "bob@example.com"]
],
"row_count": 2,
"execution_time_ms": 45.12,
"metadata": {
"bytes_scanned": 1024,
"cost_eur": 0.00001
}
}

Response (Objects)

When format: "objects", returns an array of objects - the developer-friendly format:

json
{
"data": [
{ "id": "cus_abc123", "email": "alice@example.com" },
{ "id": "cus_def456", "email": "bob@example.com" }
],
"row_count": 2,
"execution_time_ms": 45.12,
"metadata": {
"bytes_scanned": 1024,
"cost_eur": 0.00001
}
}

Use format=objects when you want to consume results directly without mapping columns to rows.

Response (CSV)

When format: "csv", returns text/csv with a Content-Disposition header:

csv
id,email
cus_abc123,alice@example.com
cus_def456,bob@example.com

GET /api/v1/execute/tables

List all tables available for querying.

Response

json
{
"tables": [
{
"name": "customers",
"schema_name": "my_stripe",
"row_count": 1234,
"size_bytes": 524288,
"column_count": 12
}
]
}

Error Handling

Every error includes a code, message, and optional hint to help you fix it.

json
{
"detail": {
"error": {
"code": "SYNTAX_ERROR",
"message": "Syntax error at line 1: unexpected token 'FORM'",
"hint": "Check your SQL syntax. rawquery uses Postgres-compatible SQL."
}
}
}
HTTP StatusError CodeMeaning
401MISSING_API_KEYNo X-API-Key header provided
401INVALID_API_KEYAPI key not found or invalid format
401EXPIRED_API_KEYAPI key has expired
400SYNTAX_ERRORInvalid SQL syntax
400UNDEFINED_TABLETable doesn't exist
400UNDEFINED_COLUMNColumn doesn't exist
400QUERY_TOO_LARGEQuery scan exceeds plan limit
408QUERY_TIMEOUTQuery exceeded 30s timeout
400SNAPSHOT_NOT_FOUNDNo data snapshot exists at the requested time (time travel)
400NO_WORKSPACENo workspace found for your account
403WORKSPACE_ACCESS_DENIEDNot a member of the specified workspace
500INTERNAL_ERRORUnexpected server error

Rate Limits

Rate limits are applied per workspace based on your plan. Limits are counted over a 60-second sliding window.

PlanQueries / minute
Free10
Team60
Business100

Examples

curl

bash
# JSON result (columns + rows)
curl -X POST https://api.rawquery.dev/api/v1/execute \
-H "X-API-Key: rq_your_api_key" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT * FROM my_stripe.customers LIMIT 5"}'
# Objects format (array of dicts - easiest to consume)
curl -X POST https://api.rawquery.dev/api/v1/execute \
-H "X-API-Key: rq_your_api_key" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT * FROM my_stripe.customers LIMIT 5", "format": "objects"}'
# CSV download
curl -X POST https://api.rawquery.dev/api/v1/execute \
-H "X-API-Key: rq_your_api_key" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT * FROM my_stripe.customers", "format": "csv"}' \
-o customers.csv
# List tables
curl https://api.rawquery.dev/api/v1/execute/tables \
-H "X-API-Key: rq_your_api_key"

Python

python
import requests
API_KEY = "rq_your_api_key"
BASE_URL = "https://api.rawquery.dev/api/v1"
response = requests.post(
f"{BASE_URL}/execute",
headers={"X-API-Key": API_KEY},
json={"sql": "SELECT * FROM my_stripe.customers LIMIT 5"},
)
data = response.json()
for row in data["rows"]:
print(row)
# With pandas
import pandas as pd
df = pd.DataFrame(
data["rows"],
columns=[c["name"] for c in data["columns"]],
)
print(df)

Time Travel

Query historical data using FOR SYSTEM_TIME AS OF:

bash
# Query data as it was on January 15, 2024
curl -X POST https://api.rawquery.dev/api/v1/execute \
-H "X-API-Key: rq_your_api_key" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT * FROM my_stripe.charges FOR SYSTEM_TIME AS OF '\''2024-01-15'\'' LIMIT 10"}'

JavaScript / TypeScript

js
const API_KEY = "rq_your_api_key";
const BASE_URL = "https://api.rawquery.dev/api/v1";
const response = await fetch(`${BASE_URL}/execute`, {
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
sql: "SELECT * FROM my_stripe.customers LIMIT 5",
}),
});
const data = await response.json();
console.log(data.columns.map(c => c.name));
console.log(data.rows);

See also: All API Endpoints