Validate a read-only blockchain SQL query without executing it. Returns query acceptance, rewritten SQL, scan estimates, scan budgets, referenced tables and warnings without executing the query. Use one Toolmu account and a shared prepaid balance across available Tools. Pay per use; no separate supplier subscription is required. The current execution ceiling for this Tool is 0.0288 Toolmu credits per call. This is a maximum, not the settled charge. Before execution, get the current Tool contract and check availability, the latest maximumCredits, your balance and budget. Supplier response credits_used, when present, describes supplier API credits and is not the Toolmu customer charge.
Up to 0.0288 credits / call
The final charge is based on confirmed usage. Unused reserved credits return to your available balance.
Surf
SQL Syntax Checker for Blockchain Queries
Validate a read-only blockchain SQL query without executing it. Returns query acceptance, rewritten SQL, scan estimates, scan budgets, referenced tables and warnings without executing the query. Use one Toolmu account and a shared prepaid balance across available Tools. Pay per use; no separate supplier subscription is required. The current execution ceiling for this Tool is 0.0288 Toolmu credits per call. This is a maximum, not the settled charge. Before execution, get the current Tool contract and check availability, the latest maximumCredits, your balance and budget. Supplier response credits_used, when present, describes supplier API credits and is not the Toolmu customer charge.
You receive
Returns query acceptance, rewritten SQL, scan estimates, scan budgets, referenced tables and warnings without executing the query. Preflight acceptance and estimates do not mean the query ran or returned data. Keep warnings and explicit scan limits visible.
Start with your task
Tell me what you want to find out, or paste something you already have. I’ll check whether it only looks at existing data, roughly how much data it may need to review, and what details are missing. I won’t run it.
Inputs & outputs
Inspect the current inputs, availability, and maximum charge before starting.
Input schema
Input schema
Field / Path
Type
Requirement
Meaning
bodybody
object
Required
Required fields
sql
sqlbody.sql
string
Required
Read-only ClickHouse SELECT/WITH query to validate and estimate WITHOUT executing. Same shape and rules as /onchain/sql. Rules (server-enforced or query-killing): SELECT/WITH only (read-only); table references must be database-qualified as agent.<table>; ALWAYS filter on block_date or block_number (partition key — without it the query times out); compare address columns directly against lowercase literals (wrapping the column in lower() is rejected); never filter on symbol columns (unindexed full scan, and symbol matches surface scam clones — resolve a ticker to a contract address with /search/token first); on transfer tables use separate UNION ALL branches instead of OR across from/to; use single quotes for strings, e.g. toDate('2026-04-07').
Minimum length
1
max_rowsbody.max_rows
integer
Optional
Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000.
Minimum
1
Maximum
10000
View raw JSON
{
"type": "object",
"required": [
"body"
],
"properties": {
"body": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"sql"
],
"~standard": {
"vendor": "zod",
"version": 1,
"jsonSchema": {}
},
"properties": {
"sql": {
"type": "string",
"minLength": 1,
"description": "Read-only ClickHouse SELECT/WITH query to validate and estimate WITHOUT executing. Same shape and rules as /onchain/sql. Rules (server-enforced or query-killing): SELECT/WITH only (read-only); table references must be database-qualified as agent.<table>; ALWAYS filter on block_date or block_number (partition key — without it the query times out); compare address columns directly against lowercase literals (wrapping the column in lower() is rejected); never filter on symbol columns (unindexed full scan, and symbol matches surface scam clones — resolve a ticker to a contract address with /search/token first); on transfer tables use separate UNION ALL branches instead of OR across from/to; use single quotes for strings, e.g. toDate('2026-04-07')."
},
"max_rows": {
"type": "integer",
"maximum": 10000,
"minimum": 1,
"description": "Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Result schema
Output fields have not been documented yet.
Additional notes
Validate a read-only blockchain SQL query without executing it
How to use this Tool
Use the deployed input fields below. Required fields must be supplied; optional filters narrow the result.
body.sql (Required): Read-only ClickHouse SELECT/WITH query to validate and estimate WITHOUT executing. Same shape and rules as /onchain/sql. Rules (server-enforced or query-killing): SELECT/WITH only (read-only); table references must be database-qualified as agent.<table>; ALWAYS filter on block_date or block_number (partition key — without it the query times out); compare address columns directly against lowercase literals (wrapping the column in lower() is rejected); never filter on symbol columns (unindexed full scan, and symbol matches surface scam clones — resolve a ticker to a contract address with /search/token first); on transfer tables use separate UNION ALL branches instead of OR across from/to; use single quotes for strings, e.g. toDate('2026-04-07').
body.max_rows (Optional): Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000.
What this Tool returns
Returns query acceptance, rewritten SQL, scan estimates, scan budgets, referenced tables and warnings without executing the query.
Response fields and how to read them
The table follows the official response contract, including nested fields and useful response metadata. [] denotes an array item. Required means required within its parent object, not that a conditional parent always exists. A nullable type permits null; an optional field can be absent. Use the documented conditions below to distinguish missing, empty and zero values. Units and reporting windows apply only where explicitly documented.
Field, type and presence
Meaning and conditions
data.accepted
boolean; Required within parent
Whether the plan remains within required filters and configured scan budgets
data.budget
object; Required within parent
Server-enforced scan and execution budgets
data.budget.max_bytes_to_read
integer; Required within parent; format: int64
Maximum ClickHouse bytes the query may read; zero means disabled
data.budget.max_execution_time_seconds
integer; Required within parent; format: int64
Synchronous execution-time budget in seconds
data.budget.max_rows_to_read
integer; Required within parent; format: int64
Maximum ClickHouse rows the query may read; zero means disabled
data.estimate
object; Required within parent
Estimated physical scan returned before execution
data.estimate.by_table
array | null; Required within parent
Per-physical-table estimates
data.estimate.by_table.[].bytes
integer; Required within parent; format: int64
Estimated bytes derived from current physical table size
data.estimate.by_table.[].database
string; Required within parent
Physical ClickHouse database
data.estimate.by_table.[].marks
integer; Required within parent; format: int64
Estimated index granules to read
data.estimate.by_table.[].parts
integer; Required within parent; format: int64
Estimated active data parts
data.estimate.by_table.[].rows
integer; Required within parent; format: int64
Estimated rows to read
data.estimate.by_table.[].table
string; Required within parent
Physical ClickHouse table
data.estimate.bytes
integer; Required within parent; format: int64
Estimated bytes derived from physical table bytes per row
data.estimate.marks
integer; Required within parent; format: int64
Estimated index granules to read
data.estimate.parts
integer; Required within parent; format: int64
Estimated active data parts
data.estimate.rows
integer; Required within parent; format: int64
Estimated rows to read
data.executed_sql
string; Required within parent
Final SQL after server row limits and scan budgets are applied; preflight does not execute it
data.query_id
string; Required within parent
ClickHouse query ID used for this EXPLAIN ESTIMATE operation
data.request_id
string; Required within parent
Request correlation ID echoed in the X-Request-ID response header
data.sql
string; Required within parent
Original submitted SQL
data.tables
array | null; Required within parent
Allowlisted logical tables and bounded physical source metadata used by the plan
data.tables.[].columns
array | null; Required within parent
List of columns in this table
data.tables.[].columns.[].comment
string; Optional within parent
Column comment or description
data.tables.[].columns.[].name
string; Required within parent
Column name
data.tables.[].columns.[].type
string; Required within parent
Column data type like `UInt64`, `String`, or `DateTime`
data.tables.[].database
string; Required within parent
Database name (always `agent`)
data.tables.[].engine
string; Optional within parent
Logical table engine, commonly View
data.tables.[].partition_key
string; Optional within parent
Logical table PARTITION BY expression when applicable
data.tables.[].physical_sources
array | null; Optional within parent
Bounded physical source metadata for a selected logical view
data.tables.[].physical_sources.[].database
string; Required within parent
Physical ClickHouse database
data.tables.[].physical_sources.[].engine
string; Required within parent
Physical ClickHouse table engine
data.tables.[].physical_sources.[].partition_key
string; Optional within parent
Physical PARTITION BY expression
data.tables.[].physical_sources.[].primary_key
string; Optional within parent
Physical primary-key expression
data.tables.[].physical_sources.[].sorting_key
string; Optional within parent
Physical ORDER BY expression
data.tables.[].physical_sources.[].table
string; Required within parent
Physical ClickHouse table
data.tables.[].physical_sources.[].total_bytes
integer; Optional within parent; format: int64
Current compressed bytes from system.tables
data.tables.[].physical_sources.[].total_rows
integer; Optional within parent; format: int64
Current physical row estimate from system.tables
data.tables.[].primary_key
string; Optional within parent
Logical table primary-key expression when applicable
data.tables.[].sorting_key
string; Optional within parent
Logical table ORDER BY expression when applicable
data.tables.[].table
string; Required within parent
Logical table name
data.tables.[].total_bytes
integer; Optional within parent; format: int64
Logical table compressed bytes when available
data.tables.[].total_rows
integer; Optional within parent; format: int64
Logical table row estimate when available
data.warnings
array | null; Required within parent
Deterministic guardrail findings and recommended actions
data.warnings.[].code
string; Required within parent
Stable machine-readable warning code
data.warnings.[].message
string; Required within parent
Human-readable explanation
data.warnings.[].recommended_action
string; Required within parent
Concrete action that preserves the requested query semantics
data.warnings.[].severity
string; Required within parent; enum: ["warning", "error"]
Warning is advisory; error makes accepted false
meta.cached
boolean; Required within parent
Whether this response was served from cache
meta.credits_used
integer; Required within parent; format: int64
Credits deducted for this request
meta.empty_reason
string; Optional within parent
Hint explaining why the data array is empty, when applicable
Coverage, units and freshness
Preflight acceptance and estimates do not mean the query ran or returned data. Keep warnings and explicit scan limits visible.
Inspect any returned observation time, cache status, watermark, pagination and errors using their documented meanings. A successful request alone does not establish complete coverage. Where no freshness or completeness guarantee is documented, treat it as unknown. Saved Examples are historical and viewing them does not refresh data or execute a new call.
Data source and references
Surf supplies this endpoint through its Data API. Response contract and deployed Tool inputs reviewed on 2026-10-03 against official OpenAPI v0.2.102. This is a contract review date, not a data observation time. Coverage depends on the selected endpoint and request.
Use one Toolmu account and a shared prepaid balance across available Tools. Pay per use; no separate supplier subscription is required. The current execution ceiling for this Tool is 0.0288 Toolmu credits per call. This is a maximum, not the settled charge. Before execution, get the current Tool contract and check availability, the latest maximumCredits, your balance and budget. Supplier response credits_used, when present, describes supplier API credits and is not the Toolmu customer charge.
Check whether [daily Ethereum transfers from October 1 to October 7] can be looked up without changing anything. Estimate how much data it may need to review, but do not run it.
I want to know [how many transactions happened on Base each day over the past 30 days]. Tell me if you need more details before checking. Do not run it.
Tell me what you want to find out, or paste something you already have. I’ll check whether it only looks at existing data, roughly how much data it may need to review, and what details are missing. I won’t run it.
Review something I already have
Please review [the data request I already wrote]. Tell me whether it is clear and asks to look at too much information. Do not run it.
Questions about this tool.
Inputs, results and details to know before running it.
body.sql (Required): Read-only ClickHouse SELECT/WITH query to validate and estimate WITHOUT executing. Same shape and rules as /onchain/sql. Rules (server-enforced or query-killing): SELECT/WITH only (read-only); table references must be database-qualified as agent.<table>; ALWAYS filter on block_date or block_number (partition key — without it the query times out); compare address columns directly against lowercase literals (wrapping the column in lower() is rejected); never filter on symbol columns (unindexed full scan, and symbol matches surface scam clones — resolve a ticker to a contract address with /search/token first); on transfer tables use separate UNION ALL branches instead of OR across from/to; use single quotes for strings, e.g. toDate('2026-04-07'). body.max_rows (Optional): Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000.
Returns query acceptance, rewritten SQL, scan estimates, scan budgets, referenced tables and warnings without executing the query.
Preflight acceptance and estimates do not mean the query ran or returned data. Keep warnings and explicit scan limits visible.
Use one Toolmu account and a shared prepaid balance across available Tools. Pay per use; no separate supplier subscription is required. The current execution ceiling for this Tool is 0.0288 Toolmu credits per call. This is a maximum, not the settled charge. Before execution, get the current Tool contract and check availability, the latest maximumCredits, your balance and budget. Supplier response credits_used, when present, describes supplier API credits and is not the Toolmu customer charge.
Ask your agent to Validate a read-only blockchain SQL query without executing it. Provide the required inputs above. If Toolmu is already connected, reuse that connection; otherwise use the setup instructions on this page. Before a paid execution, the agent must read the current Tool contract and check availability, the credit ceiling, balance, budget and your authorization. It should then execute the Tool and explain the returned fields and limitations.
Inspect any returned observation time, cache status, watermark, pagination and errors using their documented meanings. A successful request alone does not establish complete coverage. Where no freshness or completeness guarantee is documented, treat it as unknown. Saved Examples are historical and viewing them does not refresh data or execute a new call.