Scopes & costs
Scopes
Tokens carry scopes, and they are the real boundary — not the assistant's willingness to comply.
| Scope | Grants |
|---|---|
query:read | Calling any tool at all |
query:write | INSERT, UPDATE, DELETE, CREATE, DROP, ALTER |
export | export_query_results |
A read-only token cannot write, whatever the SQL says or the assistant intends.
Cost limits
Every query is priced from its plan before it runs:
| Limit | Default |
|---|---|
| Per query | $5 |
| Per day, per company | $50 |
Reserved budget is refunded if a query fails or is cancelled — cancel work you no longer need rather than leaving it running.
Separately, scanning a large external table with no selective filter is refused regardless of price. That refusal is about the shape of the query, so a cheaper rewrite will not pass; add the filter.
Row limits and timeouts
| Rows per call | 1,000 default, 10,000 maximum |
| Default timeout | 60 seconds |
| Background submission | above ~10 seconds of predicted runtime |
| Export link validity | 1 hour |
describe_table samples | 10 maximum |
Above the background threshold, execute_query returns a query_id instead of
rows. Poll get_query_status, then page get_query_results, or call
export_query_results for the whole set.
Reading refusals
Refusals are structured and specific. not_ready means still queued or running,
so poll again. not_available means it terminally failed or was cancelled — stop
polling and read the error. not_found for a query id means unknown or another
tenant's; existence is never leaked. forbidden means a missing scope, and no
rewrite will fix it.