curl -X POST "https://api.dune.com/api/v1/contracts/decode" \
-H "X-DUNE-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": [{"type": "event", "name": "Transfer", "inputs": []}],
"has_multiple_instances": false,
"is_created_by_factory": false,
"is_manual_abi": false,
"is_proxy": false,
"idempotency_key": "uniswap-token/ethereum/1"
}
]
}'
import json
import requests
url = "https://api.dune.com/api/v1/contracts/decode"
headers = {"X-DUNE-API-KEY": "YOUR_API_KEY"}
with open("UniswapToken.abi.json") as f:
abi = json.load(f)
payload = {
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": abi,
"has_multiple_instances": False,
"is_created_by_factory": False,
"is_manual_abi": False,
"is_proxy": False,
"idempotency_key": "uniswap-token/ethereum/1",
}
]
}
response = requests.post(url, json=payload, headers=headers)
for result in response.json()["results"]:
print(result)
const url = 'https://api.dune.com/api/v1/contracts/decode';
const response = await fetch(url, {
method: 'POST',
headers: {
'X-DUNE-API-KEY': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
submissions: [
{
blockchain_name: 'ethereum',
address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
project_name: 'uniswap',
contract_name: 'UniswapToken',
abi: [{ type: 'event', name: 'Transfer', inputs: [] }],
has_multiple_instances: false,
is_created_by_factory: false,
is_manual_abi: false,
is_proxy: false,
idempotency_key: 'uniswap-token/ethereum/1'
}
]
})
});
const data = await response.json();
console.log(data.results);
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending"
},
{
"index": 1,
"error": "abi must be valid JSON"
}
]
}
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending",
"replayed": true
}
]
}
{
"error": "Resubmissions and multi-chain batches require a paid team plan. Submit new contracts for one chain at a time, or upgrade your plan."
}
Contract Decoding
Submit Contracts for Decoding
Submit up to 100 contracts (with their ABIs) for decoding in one request. Each item is validated and queued independently; the response reports a per-item result matched by index. Successful items are queued as “pending” and can be tracked with GET /v1/contracts/submissions or at dune.com/workspace. Submissions are attributed to the user who created the API key. “upgrade” submissions and protected namespaces are always routed to manual review.
POST
/
v1
/
contracts
/
decode
curl -X POST "https://api.dune.com/api/v1/contracts/decode" \
-H "X-DUNE-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": [{"type": "event", "name": "Transfer", "inputs": []}],
"has_multiple_instances": false,
"is_created_by_factory": false,
"is_manual_abi": false,
"is_proxy": false,
"idempotency_key": "uniswap-token/ethereum/1"
}
]
}'
import json
import requests
url = "https://api.dune.com/api/v1/contracts/decode"
headers = {"X-DUNE-API-KEY": "YOUR_API_KEY"}
with open("UniswapToken.abi.json") as f:
abi = json.load(f)
payload = {
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": abi,
"has_multiple_instances": False,
"is_created_by_factory": False,
"is_manual_abi": False,
"is_proxy": False,
"idempotency_key": "uniswap-token/ethereum/1",
}
]
}
response = requests.post(url, json=payload, headers=headers)
for result in response.json()["results"]:
print(result)
const url = 'https://api.dune.com/api/v1/contracts/decode';
const response = await fetch(url, {
method: 'POST',
headers: {
'X-DUNE-API-KEY': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
submissions: [
{
blockchain_name: 'ethereum',
address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
project_name: 'uniswap',
contract_name: 'UniswapToken',
abi: [{ type: 'event', name: 'Transfer', inputs: [] }],
has_multiple_instances: false,
is_created_by_factory: false,
is_manual_abi: false,
is_proxy: false,
idempotency_key: 'uniswap-token/ethereum/1'
}
]
})
});
const data = await response.json();
console.log(data.results);
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending"
},
{
"index": 1,
"error": "abi must be valid JSON"
}
]
}
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending",
"replayed": true
}
]
}
{
"error": "Resubmissions and multi-chain batches require a paid team plan. Submit new contracts for one chain at a time, or upgrade your plan."
}
Minimum required API key scope:
Read/Write. Submissions are attributed to the user who created the API key.Description
Submit up to 100 contracts for decoding in a single request. Each item is validated and queued independently: the response carries one result per item, matched byindex, so a bad ABI in one item does not stop the others.
Successful items are queued as pending and can be tracked with List Contract Submissions or in the Dune UI. Items that fail validation carry an error describing what to fix.
ABI upgrades, renames, deletions, and submissions to protected namespaces are always routed to manual review. Expect them to show
needs_manual_review rather than being decoded automatically.Request Fields
Each entry insubmissions mirrors the fields of the submission form. See the decoding guide for what the flags mean.
| Field | Notes |
|---|---|
blockchain_name | Chain the contract is deployed on, e.g. ethereum, base. Must be a chain Dune decodes. |
address | Contract address. Hex for EVM chains; Tron base58 addresses are accepted when blockchain_name is tron. |
project_name | Namespace the decoded tables are grouped under. Case is preserved. |
contract_name | Contract name used in decoded table names. Case is preserved. |
abi | The ABI as a JSON array, or as a string containing the JSON array (the shape most exports produce). |
has_multiple_instances | true for dynamic contracts sharing one ABI. |
is_created_by_factory | true for contracts created by a factory. |
is_proxy | true when the address is a proxy; submit the implementation’s ABI. |
is_manual_abi | true when the ABI was written or edited by hand rather than fetched from an explorer. |
submission_type | new (default), upgrade, rename, delete, or other. |
resubmission_reason | Why you are resubmitting. Required for delete and other. |
old_project_name, old_contract_name | Required for rename: the names the contract is decoded under today. project_name and contract_name then carry the new names. |
idempotency_key | Optional, at most 128 characters, unique per account. See below. |
delete, project_name and contract_name name the contract to remove.
Idempotency
If a request fails part way through or you lose the response, retrying a batch without keys creates duplicate submissions. Give each item anidempotency_key you control, such as abi-refresh-2026-09-10/0. Resubmitting an item whose key you already used returns the existing submission with replayed: true instead of creating a new one. Keys are scoped to your account.
Plan Requirements
- Free plans can submit new contracts for a single blockchain per request.
- Batches spanning more than one
blockchain_name, and anyupgrade,rename,delete, orothersubmission, require the plan behind the API key to be paid (the team’s plan for a team key). Otherwise the request fails with403and a reason. - Read-only plans cannot submit.
Pricing
Submitting contracts does not consume credits.Related Endpoints
- List Contract Submissions - Track the status of your submissions
curl -X POST "https://api.dune.com/api/v1/contracts/decode" \
-H "X-DUNE-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": [{"type": "event", "name": "Transfer", "inputs": []}],
"has_multiple_instances": false,
"is_created_by_factory": false,
"is_manual_abi": false,
"is_proxy": false,
"idempotency_key": "uniswap-token/ethereum/1"
}
]
}'
import json
import requests
url = "https://api.dune.com/api/v1/contracts/decode"
headers = {"X-DUNE-API-KEY": "YOUR_API_KEY"}
with open("UniswapToken.abi.json") as f:
abi = json.load(f)
payload = {
"submissions": [
{
"blockchain_name": "ethereum",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"project_name": "uniswap",
"contract_name": "UniswapToken",
"abi": abi,
"has_multiple_instances": False,
"is_created_by_factory": False,
"is_manual_abi": False,
"is_proxy": False,
"idempotency_key": "uniswap-token/ethereum/1",
}
]
}
response = requests.post(url, json=payload, headers=headers)
for result in response.json()["results"]:
print(result)
const url = 'https://api.dune.com/api/v1/contracts/decode';
const response = await fetch(url, {
method: 'POST',
headers: {
'X-DUNE-API-KEY': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
submissions: [
{
blockchain_name: 'ethereum',
address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
project_name: 'uniswap',
contract_name: 'UniswapToken',
abi: [{ type: 'event', name: 'Transfer', inputs: [] }],
has_multiple_instances: false,
is_created_by_factory: false,
is_manual_abi: false,
is_proxy: false,
idempotency_key: 'uniswap-token/ethereum/1'
}
]
})
});
const data = await response.json();
console.log(data.results);
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending"
},
{
"index": 1,
"error": "abi must be valid JSON"
}
]
}
{
"results": [
{
"index": 0,
"submission_id": "0b1e4c2a-7d3f-4e5b-9a6c-8d7e6f5a4b3c",
"status": "pending",
"replayed": true
}
]
}
{
"error": "Resubmissions and multi-chain batches require a paid team plan. Submit new contracts for one chain at a time, or upgrade your plan."
}
Headers
API Key for the service
Query Parameters
API Key, alternative to using the HTTP header X-Dune-Api-Key
Body
application/json
Batch of contract submissions
Required array length:
1 - 100 elementsShow child attributes
Show child attributes
Response
OK
Show child attributes
Show child attributes
Was this page helpful?