Dune Analytics API
A skill for querying and analyzing blockchain data via the Dune Analytics API.
Setup
pip install dune-client
Set DUNE_API_KEY via environment variable, .env file, or agent config.
⚠️ Usage Rules
- Read before writing SQL — Select and read the relevant reference files (see Reference Selection) before writing any query. Do not skip this step.
- Prefer Private Queries — Try
is_private=True first. Fall back to public if it fails (free plan), and notify the user.
- Don't create duplicates — Reuse/update existing queries unless explicitly asked to create new ones.
- Confirm before updating — Ask the user before modifying an existing query.
- Track credits — Report credits consumed after each execution. See query-execution.md.
Reference Selection
Before writing any SQL, route to the correct reference file(s) based on your task:
| Task involves... |
Read this reference |
| Finding tables / inspecting schema / discovering protocols |
table-discovery.md |
| Finding decoded tables by contract address |
table-discovery.md |
| Searching Dune documentation / guides / examples |
table-discovery.md |
| Wallet / address tracking / router identification |
wallet-analysis.md |
| Table selection / common table names |
common-tables.md |
| SQL performance / complex joins / array ops |
sql-optimization.md |
| API calls / execution / caching / parameters |
query-execution.md |
| Uploading CSV/NDJSON data to Dune |
data-upload.md |
If your task spans multiple categories, read all relevant files. Do not guess table names or query patterns — the references contain critical details (e.g., specialized tables, anti-patterns) that are not covered in this overview.
Quick Start
from dune_client.client import DuneClient
from dune_client.query import QueryBase
import os
client = DuneClient(api_key=os.environ['DUNE_API_KEY'])
# Execute a query
result = client.run_query(query=QueryBase(query_id=123456), performance='medium', ping_frequency=5)
print(f"Rows: {len(result.result.rows)}")
# Get cached result (no re-execution)
result = client.get_latest_result(query_id=123456)
# Get/update SQL
sql = client.get_query(123456).sql
client.update_query(query_id=123456, query_sql="SELECT ...")
# Upload CSV data (quick, overwrites existing)
client.upload_csv(
data="col1,col2\nval1,val2",
description="My data",
table_name="my_table",
is_private=True
)
# Create table + insert (supports append)
client.create_table(
namespace="my_user",
table_name="my_table",
schema=[{"name": "col1", "type": "varchar"}, {"name": "col2", "type": "double"}],
is_private=True
)
import io
client.insert_data(
namespace="my_user",
table_name="my_table",
data=io.BytesIO(b"col1,col2\nabc,1.5"),
content_type="text/csv"
)
Subscription Tiers
| Method |
Description |
Plan |
run_query |
Execute saved query (supports {{param}}) |
Free |
run_sql |
Execute SQL directly (no params) |
Plus |
Key Concepts
dex.trades vs dex_aggregator.trades
| Table |
Use Case |
Volume |
dex.trades |
Per-pool analysis |
⚠️ Inflated ~30% (multi-hop counted multiple times) |
dex_aggregator.trades |
User/wallet analysis |
Accurate |
⚠️ For wallet/address analysis, use dex_aggregator.trades with tx_to matching router addresses from dune.lz_web3.dataset_crypto_wallet_router. Do not use labels.all for wallet router lookups. See wallet-analysis.md for full patterns.
Solana has no dex_aggregator_solana.trades. Dedupe by tx_id:
SELECT tx_id, MAX(amount_usd) as amount_usd
FROM dex_solana.trades
GROUP BY tx_id
Data Freshness
| Layer |
Delay |
Example |
| Raw |
< 1 min |
ethereum.transactions, solana.transactions |
| Decoded |
15-60 sec |
uniswap_v3_ethereum.evt_Swap |
| Curated |
~1 hour+ |
dex.trades, dex_solana.trades |
Query previous day's data after UTC 12:00 for completeness.
References
Detailed documentation is organized in the references/ directory:
| File |
Description |
| table-discovery.md |
Table discovery: search tables by name, inspect schema/columns, list schemas and uploads |
| query-execution.md |
API patterns: execute, update, cache, multi-day fetch, credits tracking, subqueries |
| common-tables.md |
Quick reference of commonly used tables: raw, decoded, curated, community data |
| sql-optimization.md |
SQL optimization: CTE, JOIN strategies, array ops, partition pruning |
| wallet-analysis.md |
Wallet tracking: Solana/EVM queries, multi-chain aggregation, fee analysis |
| data-upload.md |
Data upload: CSV/NDJSON upload, create table, insert data, manage tables, credits |
1---2name: dune-analytics-api3description: Dune Analytics API for blockchain data queries. Use for: (1) Discovering tables and inspecting schemas, (2) Executing/refreshing Dune queries, (3) SQL query optimization for Solana/EVM chains, (4) Understanding dex.trades vs dex_aggregator.trades, (5) Working with Solana transactions and log parsing, (6) Managing query parameters and results, (7) Uploading CSV/NDJSON data to Dune tables, (8) Finding decoded tables by contract address, (9) Searching Dune documentation. Triggers on: Dune query, blockchain data, DEX trades, Solana transactions, on-chain analytics, query optimization, data upload, CSV upload, table discovery, find table, schema inspection, contract address lookup, decoded tables, search docs.4---5
6# Dune Analytics API
7
8A skill for querying and analyzing blockchain data via the [Dune Analytics](https://dune.com) API.
9
10## Setup
11
12```bash
13pip install dune-client
14```
15
16Set `DUNE_API_KEY` via environment variable, `.env` file, or agent config.
17
18## ⚠️ Usage Rules
19
201. **Read before writing SQL** — Select and read the relevant reference files (see [Reference Selection](#reference-selection)) **before** writing any query. Do not skip this step.
212. **Prefer Private Queries** — Try `is_private=True` first. Fall back to public if it fails (free plan), and notify the user.
223. **Don't create duplicates** — Reuse/update existing queries unless explicitly asked to create new ones.
234. **Confirm before updating** — Ask the user before modifying an existing query.
245. **Track credits** — Report credits consumed after each execution. See [query-execution.md](references/query-execution.md#credits-tracking).
25
26## Reference Selection
27
28**Before writing any SQL, route to the correct reference file(s) based on your task:**
29
30| Task involves... | Read this reference |
31|-----------------|-------------------|
32| Finding tables / inspecting schema / discovering protocols | [table-discovery.md](references/table-discovery.md) |
33| Finding decoded tables by contract address | [table-discovery.md](references/table-discovery.md#search-tables-by-contract-address) |
34| Searching Dune documentation / guides / examples | [table-discovery.md](references/table-discovery.md#search-dune-documentation) |
35| Wallet / address tracking / router identification | [wallet-analysis.md](references/wallet-analysis.md) |
36| Table selection / common table names | [common-tables.md](references/common-tables.md) |
37| SQL performance / complex joins / array ops | [sql-optimization.md](references/sql-optimization.md) |
38| API calls / execution / caching / parameters | [query-execution.md](references/query-execution.md) |
39| Uploading CSV/NDJSON data to Dune | [data-upload.md](references/data-upload.md) |
40
41If your task spans multiple categories, read **all** relevant files. Do not guess table names or query patterns — the references contain critical details (e.g., specialized tables, anti-patterns) that are not covered in this overview.
42
43## Quick Start
44
45```python
46from dune_client.client import DuneClient
47from dune_client.query import QueryBase
48import os
49
50client = DuneClient(api_key=os.environ['DUNE_API_KEY'])
51
52# Execute a query
53result = client.run_query(query=QueryBase(query_id=123456), performance='medium', ping_frequency=5)
54print(f"Rows: {len(result.result.rows)}")
55
56# Get cached result (no re-execution)
57result = client.get_latest_result(query_id=123456)
58
59# Get/update SQL
60sql = client.get_query(123456).sql
61client.update_query(query_id=123456, query_sql="SELECT ...")
62
63# Upload CSV data (quick, overwrites existing)
64client.upload_csv(
65 data="col1,col2\nval1,val2",
66 description="My data",
67 table_name="my_table",
68 is_private=True
69)
70
71# Create table + insert (supports append)
72client.create_table(
73 namespace="my_user",
74 table_name="my_table",
75 schema=[{"name": "col1", "type": "varchar"}, {"name": "col2", "type": "double"}],
76 is_private=True
77)
78import io
79client.insert_data(
80 namespace="my_user",
81 table_name="my_table",
82 data=io.BytesIO(b"col1,col2\nabc,1.5"),
83 content_type="text/csv"
84)
85```
86
87## Subscription Tiers
88
89| Method | Description | Plan |
90|--------|-------------|------|
91| `run_query` | Execute saved query (supports `{{param}}`) | Free |
92| `run_sql` | Execute SQL directly (no params) | Plus |
93
94## Key Concepts
95
96### dex.trades vs dex_aggregator.trades
97
98| Table | Use Case | Volume |
99|-------|----------|--------|
100| `dex.trades` | Per-pool analysis | ⚠️ Inflated ~30% (multi-hop counted multiple times) |
101| `dex_aggregator.trades` | User/wallet analysis | Accurate |
102
103> ⚠️ **For wallet/address analysis**, use `dex_aggregator.trades` with `tx_to` matching router addresses from `dune.lz_web3.dataset_crypto_wallet_router`. Do **not** use `labels.all` for wallet router lookups. See [wallet-analysis.md](references/wallet-analysis.md) for full patterns.
104
105Solana has no `dex_aggregator_solana.trades`. Dedupe by `tx_id`:
106```sql
107SELECT tx_id, MAX(amount_usd) as amount_usd
108FROM dex_solana.trades
109GROUP BY tx_id
110```
111
112### Data Freshness
113
114| Layer | Delay | Example |
115|-------|-------|---------|
116| Raw | < 1 min | `ethereum.transactions`, `solana.transactions` |
117| Decoded | 15-60 sec | `uniswap_v3_ethereum.evt_Swap` |
118| Curated | ~1 hour+ | `dex.trades`, `dex_solana.trades` |
119
120Query previous day's data after **UTC 12:00** for completeness.
121
122## References
123
124Detailed documentation is organized in the `references/` directory:
125
126| File | Description |
127|------|-------------|
128| [table-discovery.md](references/table-discovery.md) | Table discovery: search tables by name, inspect schema/columns, list schemas and uploads |
129| [query-execution.md](references/query-execution.md) | API patterns: execute, update, cache, multi-day fetch, credits tracking, subqueries |
130| [common-tables.md](references/common-tables.md) | Quick reference of commonly used tables: raw, decoded, curated, community data |
131| [sql-optimization.md](references/sql-optimization.md) | SQL optimization: CTE, JOIN strategies, array ops, partition pruning |
132| [wallet-analysis.md](references/wallet-analysis.md) | Wallet tracking: Solana/EVM queries, multi-chain aggregation, fee analysis |
133| [data-upload.md](references/data-upload.md) | Data upload: CSV/NDJSON upload, create table, insert data, manage tables, credits |