- CLI Reference
- Commands
- ironflow sql
ironflow sql
Execute a read-only SQL query against the Ironflow database.
ironflow sql <query> [flags]Queries are automatically scoped to the current environment. Only SELECT and WITH queries are allowed. Mutation keywords (INSERT, UPDATE, DELETE, DROP, etc.) are rejected.
Arguments:
| Argument | Required | Description |
|---|---|---|
query | Yes | SQL SELECT query to execute |
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--format | string | table | Output format: table, json, csv, jsonl | |
--timeout | int32 | 5000 | Query timeout in milliseconds | |
--max-rows | int32 | 1000 | Maximum rows to return | |
--server | -s | string | $IRONFLOW_SERVER_URL or http://localhost:9123 | Server URL |
Available tables: events, runs, steps, functions, projection_registry, projection_state
Available functions: a query can call aggregates (count, sum, avg, min, max, string_agg, json_agg), window functions (row_number, rank, lag, lead), and string, number, date and JSON functions (lower, coalesce, round, date_trunc, strftime, json_extract, jsonb_extract_path_text). A call to any other function is rejected, and the error lists the permitted functions. A column list on a CTE or an alias (WITH t(n) AS ...) is also rejected; name the columns inside the query.
Environment scoping: Queries are automatically filtered to the current environment via temporary views. The environment is the ID in IRONFLOW_ENV (for example env_default). Without it the CLI sends current, the environment of your API key.
Examples:
# Count events by nameironflow sql "SELECT name, COUNT(*) AS total FROM events GROUP BY name"
# Find failed runsironflow sql "SELECT id, status FROM runs WHERE status = 'failed' LIMIT 10"
# Export events as JSONironflow sql "SELECT * FROM events WHERE entity_id = 'order-123'" --format json
# CSV output for spreadsheetsironflow sql "SELECT id, name FROM functions" --format csv
# JSONL for streaming processingironflow sql "SELECT * FROM events" --format jsonl | jq '.name'Output (table):
id name entity_idevt_001 order.placed order-123evt_002 order.paid order-123