---
title: "Blockchain Structured Query"
method: POST
path: "/gateway/v1/onchain/query"
tags: ["Onchain"]
---

# Blockchain Structured Query

`POST /gateway/v1/onchain/query`

Send a JSON object describing the query. Example: `{"source":"agent.ethereum_dex_trades","fields":["block_time"],"filters":[{"field":"block_date","op":"gte","value":"2025-03-01"}],"limit":1}`.

Use this endpoint when you want structured filtering without writing raw SQL. Discover tables and columns first with `GET /v1/onchain/schema`.

Key rules:
- Source format: `agent.<table_name>`
- Max 10,000 rows (default 20), 30s timeout
- Always filter on `block_date` for large tables
- **Never filter by** `symbol` — it is unindexed (full scan). To resolve a ticker to a contract address, use `GET /v1/search/token?q={symbol}&chain={chain}` and filter by `contract_address` instead
- For transfer tables, `amount` is decimal-adjusted display units; `amount_raw` is the original base-unit value

Data refresh: ~24 hours.

Example

```json
{
  "source": "agent.ethereum_dex_trades",
  "fields": ["block_time", "project", "token_pair", "amount_usd", "taker"],
  "filters": [
    {"field": "block_date", "op": "gte", "value": "2025-03-01"},
    {"field": "project", "op": "eq", "value": "uniswap"},
    {"field": "amount_usd", "op": "gte", "value": 100000}
  ],
  "sort": [{"field": "amount_usd", "order": "desc"}],
  "limit": 20
}
```

## Request body

- StructuredQuery
  - `$schema` string, uri — A URL to the JSON Schema for this object.
  - `fields` string[], nullable — Columns to return. Omit to return all columns.
  - `filters` StructuredFilter[], nullable — WHERE conditions (ANDed together)
    - `field` string, required — Column name to filter on like `block_number` or `from_address`
    - `op` string, required — Comparison operator: eq, neq, gt, gte, lt, lte, like, in, not_in. For `in`/`not_in`, value must be a JSON array
    - `value` unknown, required
  - `limit` integer — Max rows to return. Default 20, max 10000
  - `offset` integer — Rows to skip for pagination. Default 0
  - `sort` StructuredSort[], nullable — ORDER BY clauses
    - `field` string, required — Column name to sort by like `gas`, `block_number`, or `amount_usd`
    - `order` string — Sort direction: asc (default) or desc
  - `source` string, required — Fully-qualified table name like `agent.ethereum_yields_daily`. Use GET /v1/onchain/schema for available tables.

## Response `200`

OK

- DataResponseOnchainRow
  - `$schema` string, uri — A URL to the JSON Schema for this object.
  - `data` object[], nullable, required
  - `meta` OffsetMeta, required
    - `cached` boolean, required — Whether this response was served from cache
    - `credits_used` integer, required — Credits deducted for this request
    - `empty_reason` string — Hint explaining why the data array is empty, when applicable
    - `has_more` boolean — Whether more items may exist beyond this response. For offset-paged endpoints, continue with a larger offset. For time-series endpoints without offset/cursor controls, true means the requested time range hit an upstream cap; narrow from/to to continue. Omitted when exhaustion cannot be proven.
    - `limit` integer, required — Maximum number of items returned in this response
    - `offset` integer, required — Number of items skipped (pagination offset)
    - `total` integer — Total number of matching items (before pagination). Omitted when total is unknown.
    - `watermark` integer — Warehouse watermark (Unix seconds) this response was computed at, on warehouse-backed endpoints (e.g. Hyperliquid /trades/aggregate) — rows up to this time come from the warehouse, newer rows from the live tail. Omitted elsewhere.

## Other responses

- `default` — Error

---

[API](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api.md) · [All operations](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/asksurf/asksurf-public-rest-api/revisions/498f461e81c4/schema)
