API Endpoints
Complete reference for all API endpoints. All endpoints require authentication.
All endpoints are under https://api.rawquery.dev/api/v1. Authenticate with a Bearer token (JWT) or X-API-Key header depending on the endpoint.
POST /api/v1/execute
Execute a SQL query and return results. Auth: X-API-Key header. See the full Execute API docs for details.
Request Body
{ "sql": "SELECT * FROM my_stripe.customers LIMIT 10", "format": "json"}{ "sql": "SELECT * FROM my_stripe.customers LIMIT 10", "format": "json"}Format options: json (columns + rows), objects (array of dicts), csv (file download).
Response
{ "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 }}{ "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 }}Example
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 COUNT(*) FROM my_stripe.charges"}'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 COUNT(*) FROM my_stripe.charges"}'GET /api/v1/execute/tables
List all available tables. Auth: X-API-Key header.
Example
curl https://api.rawquery.dev/api/v1/execute/tables \ -H "X-API-Key: rq_your_api_key"curl https://api.rawquery.dev/api/v1/execute/tables \ -H "X-API-Key: rq_your_api_key"POST /api/v1/workspaces/{workspace_id}/query
Execute a workspace-scoped query with usage tracking. Auth: Bearer token. Used internally by the dashboard query editor.
Connections
GET /api/v1/workspaces/{workspace_id}/connections
List all connections in a workspace. Auth: Bearer token.
POST /api/v1/workspaces/{workspace_id}/connections # Create connectionGET /api/v1/workspaces/{workspace_id}/connections # List connectionsGET /api/v1/workspaces/{workspace_id}/connections/{connection_id} # Get connectionDELETE /api/v1/workspaces/{workspace_id}/connections/{connection_id} # Delete connectionPOST /api/v1/workspaces/{workspace_id}/connections/{connection_id}/test # Test connectionGET /api/v1/workspaces/{workspace_id}/connections/{connection_id}/streams # Discover streamsPOST /api/v1/workspaces/{workspace_id}/connections/{connection_id}/sync # Trigger syncGET /api/v1/workspaces/{workspace_id}/connections/{connection_id}/sync-status # Sync statusPOST /api/v1/workspaces/{workspace_id}/connections # Create connectionGET /api/v1/workspaces/{workspace_id}/connections # List connectionsGET /api/v1/workspaces/{workspace_id}/connections/{connection_id} # Get connectionDELETE /api/v1/workspaces/{workspace_id}/connections/{connection_id} # Delete connectionPOST /api/v1/workspaces/{workspace_id}/connections/{connection_id}/test # Test connectionGET /api/v1/workspaces/{workspace_id}/connections/{connection_id}/streams # Discover streamsPOST /api/v1/workspaces/{workspace_id}/connections/{connection_id}/sync # Trigger syncGET /api/v1/workspaces/{workspace_id}/connections/{connection_id}/sync-status # Sync statusTables (Lakehouse)
GET /api/v1/query/tables
List all available Iceberg tables with metadata. Auth: Bearer token (JWT). For API key access, use /api/v1/execute/tables.
GET /api/v1/query/tables # List all tablesGET /api/v1/query/tables/{schema.table}/metadata # Table detail + columnsGET /api/v1/query/tables # List all tablesGET /api/v1/query/tables/{schema.table}/metadata # Table detail + columnsTransforms
SQL transforms with DAG execution. Auth: Bearer token. See the Transforms docs for details.
GET /api/v1/workspaces/{workspace_id}/transforms # List transformsPOST /api/v1/workspaces/{workspace_id}/transforms # Create transformGET /api/v1/workspaces/{workspace_id}/transforms/dag # Get DAGPOST /api/v1/workspaces/{workspace_id}/transforms/run # Run all/selectedGET /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Get transformPATCH /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Update transformDELETE /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Delete transformPOST /api/v1/workspaces/{workspace_id}/transforms/{transform_id}/run # Run singleGET /api/v1/workspaces/{workspace_id}/transforms/{transform_id}/runs # Run historyGET /api/v1/workspaces/{workspace_id}/transforms # List transformsPOST /api/v1/workspaces/{workspace_id}/transforms # Create transformGET /api/v1/workspaces/{workspace_id}/transforms/dag # Get DAGPOST /api/v1/workspaces/{workspace_id}/transforms/run # Run all/selectedGET /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Get transformPATCH /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Update transformDELETE /api/v1/workspaces/{workspace_id}/transforms/{transform_id} # Delete transformPOST /api/v1/workspaces/{workspace_id}/transforms/{transform_id}/run # Run singleGET /api/v1/workspaces/{workspace_id}/transforms/{transform_id}/runs # Run historyAPI Keys
Manage API keys programmatically. Auth: Bearer token.
POST /api/v1/auth/api-keys # Create API keyGET /api/v1/auth/api-keys # List API keysDELETE /api/v1/auth/api-keys/{key_id} # Revoke API keyPOST /api/v1/auth/api-keys # Create API keyGET /api/v1/auth/api-keys # List API keysDELETE /api/v1/auth/api-keys/{key_id} # Revoke API keyCharts
Chart CRUD and publishing. Auth: Bearer token. See the Charts docs for details.
GET /api/v1/workspaces/{workspace_id}/charts # List chartsPOST /api/v1/workspaces/{workspace_id}/charts # Create chartGET /api/v1/workspaces/{workspace_id}/charts/{name} # Get chartPATCH /api/v1/workspaces/{workspace_id}/charts/{name} # Update chartDELETE /api/v1/workspaces/{workspace_id}/charts/{name} # Delete chartPOST /api/v1/workspaces/{workspace_id}/charts/{name}/publish # Publish chartDELETE /api/v1/workspaces/{workspace_id}/charts/{name}/publish # Unpublish chartGET /c/{token} # Public chart pageGET /c/{token}/data # Public chart data (JSON)GET /api/v1/workspaces/{workspace_id}/charts # List chartsPOST /api/v1/workspaces/{workspace_id}/charts # Create chartGET /api/v1/workspaces/{workspace_id}/charts/{name} # Get chartPATCH /api/v1/workspaces/{workspace_id}/charts/{name} # Update chartDELETE /api/v1/workspaces/{workspace_id}/charts/{name} # Delete chartPOST /api/v1/workspaces/{workspace_id}/charts/{name}/publish # Publish chartDELETE /api/v1/workspaces/{workspace_id}/charts/{name}/publish # Unpublish chartGET /c/{token} # Public chart pageGET /c/{token}/data # Public chart data (JSON)Pages
Page (dashboard) CRUD and publishing. Auth: Bearer token. See the Pages docs for details.
GET /api/v1/workspaces/{workspace_id}/pages # List pagesPOST /api/v1/workspaces/{workspace_id}/pages # Create pageGET /api/v1/workspaces/{workspace_id}/pages/{name} # Get pagePATCH /api/v1/workspaces/{workspace_id}/pages/{name} # Update pageDELETE /api/v1/workspaces/{workspace_id}/pages/{name} # Delete pagePOST /api/v1/workspaces/{workspace_id}/pages/{name}/publish # Publish pageDELETE /api/v1/workspaces/{workspace_id}/pages/{name}/publish # Unpublish pageGET /p/{token} # Public pageGET /api/v1/workspaces/{workspace_id}/pages # List pagesPOST /api/v1/workspaces/{workspace_id}/pages # Create pageGET /api/v1/workspaces/{workspace_id}/pages/{name} # Get pagePATCH /api/v1/workspaces/{workspace_id}/pages/{name} # Update pageDELETE /api/v1/workspaces/{workspace_id}/pages/{name} # Delete pagePOST /api/v1/workspaces/{workspace_id}/pages/{name}/publish # Publish pageDELETE /api/v1/workspaces/{workspace_id}/pages/{name}/publish # Unpublish pageGET /p/{token} # Public pageSaved Queries
Parameterized saved queries. Auth: Bearer token. See the Saved Queries docs for details.
GET /api/v1/workspaces/{workspace_id}/saved-queries # List saved queriesPOST /api/v1/workspaces/{workspace_id}/saved-queries # Create saved queryGET /api/v1/workspaces/{workspace_id}/saved-queries/{name} # Get saved queryDELETE /api/v1/workspaces/{workspace_id}/saved-queries/{name} # Delete saved queryPOST /api/v1/workspaces/{workspace_id}/saved-queries/{name}/run # Run saved queryGET /api/v1/workspaces/{workspace_id}/saved-queries # List saved queriesPOST /api/v1/workspaces/{workspace_id}/saved-queries # Create saved queryGET /api/v1/workspaces/{workspace_id}/saved-queries/{name} # Get saved queryDELETE /api/v1/workspaces/{workspace_id}/saved-queries/{name} # Delete saved queryPOST /api/v1/workspaces/{workspace_id}/saved-queries/{name}/run # Run saved queryWorkspaces
Workspace CRUD. Auth: Bearer token.
POST /api/v1/workspaces # Create workspaceGET /api/v1/workspaces # List your workspacesGET /api/v1/workspaces/{workspace_id} # Get workspace by IDPOST /api/v1/workspaces # Create workspaceGET /api/v1/workspaces # List your workspacesGET /api/v1/workspaces/{workspace_id} # Get workspace by IDCreate Workspace
{ "name": "My Company", "slug": "my-company", "region": "eu-west-gra"}{ "name": "My Company", "slug": "my-company", "region": "eu-west-gra"}Slug must be 3-63 characters, lowercase alphanumeric with hyphens. Region defaults to eu-west-gra.
Workspace Members
Manage workspace members and roles. Auth: Bearer token. Adding, updating, and removing members requires OWNER or ADMIN role.
GET /api/v1/workspaces/{workspace_id}/members # List membersPOST /api/v1/workspaces/{workspace_id}/members # Add member by emailPATCH /api/v1/workspaces/{workspace_id}/members/{member_id} # Update member roleDELETE /api/v1/workspaces/{workspace_id}/members/{member_id} # Remove memberGET /api/v1/workspaces/{workspace_id}/members # List membersPOST /api/v1/workspaces/{workspace_id}/members # Add member by emailPATCH /api/v1/workspaces/{workspace_id}/members/{member_id} # Update member roleDELETE /api/v1/workspaces/{workspace_id}/members/{member_id} # Remove memberAdd Member
{ "email": "alice@example.com", "role": "MEMBER"}{ "email": "alice@example.com", "role": "MEMBER"}Roles: OWNER, ADMIN, MEMBER, VIEWER. OWNER cannot be assigned via invite.
Push Data
POST /api/v1/workspaces/{workspace_id}/push
Push JSON records into an Iceberg table. Creates the table if it does not exist. Schema is inferred from the records. Auth: Bearer token. See the Push Data docs for details and CLI usage.
Request Body
{ "table": "crm.contacts", "records": [ { "id": 1, "name": "Alice", "email": "alice@example.com" }, { "id": 2, "name": "Bob", "email": "bob@example.com" } ], "primary_key": ["id"], "mode": "append"}{ "table": "crm.contacts", "records": [ { "id": 1, "name": "Alice", "email": "alice@example.com" }, { "id": 2, "name": "Bob", "email": "bob@example.com" } ], "primary_key": ["id"], "mode": "append"}Mode: append (default) or overwrite. Table format: namespace.table (e.g. crm.contacts).
Response
{ "records_written": 2, "table": "crm.contacts"}{ "records_written": 2, "table": "crm.contacts"}Usage & Billing
Query usage tracking and billing information. Auth: Bearer token.
GET /api/v1/workspaces/{workspace_id}/usage # Usage summary (default: current month)GET /api/v1/workspaces/{workspace_id}/usage/daily # Daily usage breakdownGET /api/v1/workspaces/{workspace_id}/usage/current # Current billing period usageGET /api/v1/workspaces/{workspace_id}/usage/dashboard # Usage dashboard with plan limits and costGET /api/v1/workspaces/{workspace_id}/usage/export # Export usage records (CSV or JSON)GET /api/v1/workspaces/{workspace_id}/usage # Usage summary (default: current month)GET /api/v1/workspaces/{workspace_id}/usage/daily # Daily usage breakdownGET /api/v1/workspaces/{workspace_id}/usage/current # Current billing period usageGET /api/v1/workspaces/{workspace_id}/usage/dashboard # Usage dashboard with plan limits and costGET /api/v1/workspaces/{workspace_id}/usage/export # Export usage records (CSV or JSON)Usage Summary
Query params: start_date, end_date (YYYY-MM-DD). Defaults to current month.
{ "query_count": 142, "total_bytes_scanned": 1073741824, "total_bytes_scanned_gb": 1.0, "total_cpu_ms": 28400, "total_rows_returned": 5280, "period_start": "2026-02-01", "period_end": "2026-02-18"}{ "query_count": 142, "total_bytes_scanned": 1073741824, "total_bytes_scanned_gb": 1.0, "total_cpu_ms": 28400, "total_rows_returned": 5280, "period_start": "2026-02-01", "period_end": "2026-02-18"}Usage Dashboard
{ "plan_tier": "team", "plan_price": 29.0, "queries_used": 142, "queries_included": 50000, "queries_remaining": 49858, "overage_queries": 0, "storage_used_gb": 1.2, "storage_limit_gb": 10.0, "storage_remaining_gb": 8.8, "connectors_used": 3, "connectors_limit": null, "estimated_cost_mtd": 29.0, "period_start": "2026-02-01", "period_end": "2026-02-28"}{ "plan_tier": "team", "plan_price": 29.0, "queries_used": 142, "queries_included": 50000, "queries_remaining": 49858, "overage_queries": 0, "storage_used_gb": 1.2, "storage_limit_gb": 10.0, "storage_remaining_gb": 8.8, "connectors_used": 3, "connectors_limit": null, "estimated_cost_mtd": 29.0, "period_start": "2026-02-01", "period_end": "2026-02-28"}Export
Query params: start_date, end_date, format (csv or json).
SDK Examples
Python
import requests
API_KEY = "rq_your_api_key"BASE_URL = "https://api.rawquery.dev/api/v1"
def query(sql): response = requests.post( f"{BASE_URL}/execute", headers={"X-API-Key": API_KEY}, json={"sql": sql}, ) return response.json()
result = query("SELECT * FROM my_stripe.customers LIMIT 5")for row in result["rows"]: print(row)import requests
API_KEY = "rq_your_api_key"BASE_URL = "https://api.rawquery.dev/api/v1"
def query(sql): response = requests.post( f"{BASE_URL}/execute", headers={"X-API-Key": API_KEY}, json={"sql": sql}, ) return response.json()
result = query("SELECT * FROM my_stripe.customers LIMIT 5")for row in result["rows"]: print(row)JavaScript
const API_KEY = "rq_your_api_key";const BASE_URL = "https://api.rawquery.dev/api/v1";
async function query(sql) { const response = await fetch(`${BASE_URL}/execute`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ sql }), }); return response.json();}
const result = await query("SELECT * FROM my_stripe.customers LIMIT 5");console.log(result.columns.map(c => c.name));console.log(result.rows);const API_KEY = "rq_your_api_key";const BASE_URL = "https://api.rawquery.dev/api/v1";
async function query(sql) { const response = await fetch(`${BASE_URL}/execute`, { method: "POST", headers: { "X-API-Key": API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ sql }), }); return response.json();}
const result = await query("SELECT * FROM my_stripe.customers LIMIT 5");console.log(result.columns.map(c => c.name));console.log(result.rows);