API reference
JSON over HTTPS, cursor pagination, stable error codes. Get a free key in the dashboard, or migrate an Etherscan integration with the migration guide.
Base URLs
- REST v1
https://x.mantis.dev/v1- Etherscan-compatible
https://x.mantis.dev/apimodule/action params — see the migration guide
Authentication
Send your key any of three ways — all equivalent. Keys look like qv_live_YOUR_KEY and are shown once at creation. Requests without a key ride the anonymous tier.
# 1. Authorization header (recommended) curl "https://x.mantis.dev/v1/blocks" -H "Authorization: Bearer qv_live_YOUR_KEY" # 2. X-API-Key header curl "https://x.mantis.dev/v1/blocks" -H "X-API-Key: qv_live_YOUR_KEY" # 3. apikey query param (Etherscan-style) curl "https://x.mantis.dev/api?module=account&action=balance&address=0x…&apikey=qv_live_YOUR_KEY"
Rate limits
Two windows per key (or per IP when anonymous): a per-second rate and a daily cap. Every response carries the current state:
X-RateLimit-Limit: 20 X-RateLimit-Remaining: 19 X-RateLimit-Reset: 1752504000
Going over answers 429 with the error envelope and a Retry-After header — back off until then.
Errors
Every failure uses one envelope with a stable machine code:
{ "error": { "code": "rate_limited", "message": "…" } }| Code | HTTP | Meaning |
|---|---|---|
| invalid_param | 400 | A parameter is malformed or out of range. |
| unauthorized | 401 | The key or session is missing, unknown, or revoked. |
| payment_required | 402 | The endpoint needs a higher tier. |
| not_found | 404 | The entity isn't indexed. |
| rate_limited | 429 | Over the per-second rate or daily cap — see Retry-After. |
| internal | 500 | Something broke on our side; safe to retry. |
Tiers
| Tier | Price | Rate | Daily cap | Extras |
|---|---|---|---|---|
| Anonymous | Free | 2 rps / IP | 10k / day | UI + casual scripts |
| Free key | Free, email signup | 5 rps | 100k / day | Dashboard, usage stats |
| Pro | $49/mo | 20 rps | 2M / day | OHLC prices, internal txs, CSV export endpoints |
| Scale | $199/mo | 100 rps | 20M / day | Bulk/range endpoints, webhooks (planned), support |
Upgrade from the dashboard. Downgrades fall back to Free — keys are never revoked for billing reasons.
Endpoints
addresses
GET/v1/addresses/{addr}Address overview
Counts, first/last seen, contract and token identity. Counts cover only the indexed range (`indexed_from`); an unseen address is all-zeros, not a 404.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte address |
Examples
curl "https://x.mantis.dev/v1/addresses/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/addresses/{addr}/internalAddress internal calls
Internal (traced) calls involving the address, newest first; rows exist only for trace-indexed blocks.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte address |
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound block number. |
| before_tx | query | stringnull | no | Cursor: tx hash (hex) within `before`. |
| before_trace | query | stringnull | no | Cursor: trace address within `before`/`before_tx`. |
Examples
curl "https://x.mantis.dev/v1/addresses/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/internal" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/addresses/{addr}/pnlAddress P&L
Transfer-derived P&L per held token: weighted-average cost basis over priced inflows vs the latest price. An estimate — unpriceable components are null, never guessed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte address |
Examples
curl "https://x.mantis.dev/v1/addresses/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/pnl" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/addresses/{addr}/transfersAddress token transfers
Token transfers involving the address, newest first; `nft=true|false` filters by standard class.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte address |
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound block number. |
| before_index | query | integernull | no | Cursor: `tx_index` (txs) or `log_index` (transfers) within `before`. |
| before_batch | query | integernull | no | Cursor: `batch_index` within `before`/`before_index` (transfers only). |
| nft | query | booleannull | no | Transfers filter: `true` = NFT (721/1155) only, `false` = ERC-20 only, absent = all standards. |
Examples
curl "https://x.mantis.dev/v1/addresses/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transfers" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/addresses/{addr}/txsAddress transactions
Transactions involving the address, newest first; composite cursor `before` + `before_index`.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte address |
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound block number. |
| before_index | query | integernull | no | Cursor: `tx_index` (txs) or `log_index` (transfers) within `before`. |
| before_batch | query | integernull | no | Cursor: `batch_index` within `before`/`before_index` (transfers only). |
| nft | query | booleannull | no | Transfers filter: `true` = NFT (721/1155) only, `false` = ERC-20 only, absent = all standards. |
Examples
curl "https://x.mantis.dev/v1/addresses/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/txs" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
account
POST/v1/auth/magic-linkRequest a sign-in link
Emails a single-use magic link (15 min TTL, 3/email/hour). Always `{ sent: true }` on success; the token never appears in the response.
Examples
curl "https://x.mantis.dev/v1/auth/magic-link" \
-X POST \
-H "Authorization: Bearer qv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"email"}'POST/v1/auth/verifyRedeem a magic link
Exchanges a magic-link token for a 30-day session token (`qv_sess_…`). Each link redeems exactly once.
Examples
curl "https://x.mantis.dev/v1/auth/verify" \
-X POST \
-H "Authorization: Bearer qv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"token"}'GET/v1/meCurrent account
Email, effective tier and the tier table (rps / daily caps / prices).
Examples
curl "https://x.mantis.dev/v1/me" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/me/keysList API keys
All keys of the signed-in account, revoked ones included; only prefixes, never plaintext.
Examples
curl "https://x.mantis.dev/v1/me/keys" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
POST/v1/me/keysCreate an API key
Creates a `qv_live_…` key (max 10 active per account). The plaintext key appears only in this response — store it now.
Examples
curl "https://x.mantis.dev/v1/me/keys" \
-X POST \
-H "Authorization: Bearer qv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"name"}'DELETE/v1/me/keys/{id}Revoke an API key
Revokes (tombstones) a key immediately; revoked keys stay listed for the audit trail.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | int64 | yes | Key id from the keys list |
Examples
curl "https://x.mantis.dev/v1/me/keys/0x0000000000000000000000000000000000000000000000000000000000000000" \ -X DELETE \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/me/usageAPI usage
Hourly request counts per key over the requested window, for the dashboard usage graph.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| hours | query | integernull | no | Window size in hours (default 7 days, max 90 days). |
Examples
curl "https://x.mantis.dev/v1/me/usage" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
blocks
GET/v1/blocksList blocks
Latest blocks, newest first. Cursor-paginate with `before` = `next_before` of the previous page.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Exclusive upper bound on block number (cursor pagination). |
Examples
curl "https://x.mantis.dev/v1/blocks" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/blocks/{id}Get one block
One block by number or 0x-prefixed 32-byte hash, with its transactions.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string | yes | Block number or 0x-prefixed block hash |
Examples
curl "https://x.mantis.dev/v1/blocks/0x0000000000000000000000000000000000000000000000000000000000000000" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
contracts
GET/v1/contracts/meta/compilersList supported compiler versions
Solidity compiler versions the verifier accepts (release builds only); empty when the verifier is unavailable.
Examples
curl "https://x.mantis.dev/v1/contracts/meta/compilers" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/contracts/{addr}Contract identity and verification state
Creation info, verification record and EIP-1967 proxy detection. `contract: null` means the creation predates the indexed range, not "not a contract". If unverified, a background Sourcify lookup may be scheduled (`sourcify_lookup`).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte contract address |
Examples
curl "https://x.mantis.dev/v1/contracts/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
POST/v1/contracts/{addr}/verifyVerify contract sources
Verify Solidity standard-json sources against on-chain bytecode. Synchronous — compiles run in seconds. Fire-and-poll tooling should use the Etherscan-compatible `verifysourcecode` surface at `/api` instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed 20-byte contract address |
Examples
curl "https://x.mantis.dev/v1/contracts/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/verify" \
-X POST \
-H "Authorization: Bearer qv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"compiler_version":"compiler_version","standard_json":"standard_json"}'billing
POST/v1/me/billing/checkoutStart a subscription purchase
Creates a Stripe Checkout session for the requested tier and returns its URL.
Examples
curl "https://x.mantis.dev/v1/me/billing/checkout" \
-X POST \
-H "Authorization: Bearer qv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"tier":"tier"}'POST/v1/me/billing/portalOpen the billing portal
Creates a Stripe customer-portal session (manage/cancel the subscription) and returns its URL.
Examples
curl "https://x.mantis.dev/v1/me/billing/portal" \ -X POST \ -H "Authorization: Bearer qv_live_YOUR_KEY"
search
GET/v1/searchSearch
Type-dispatched search over blocks, transactions, addresses and tokens.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| q | query | string | yes | The raw query string. |
Examples
curl "https://x.mantis.dev/v1/search?q=value" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
tokens
GET/v1/tokensList tokens
Tokens newest first (by first-seen block), spam-filtered unless `spam=true`; cursor `before` + `before_addr`.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound on `first_seen_block`. |
| before_addr | query | stringnull | no | Cursor: address tie-break within `before` (0x-hex). |
| spam | query | booleannull | no | Include rows with `spam_score >= 0.8` (hidden by default). |
Examples
curl "https://x.mantis.dev/v1/tokens" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/tokens/{addr}/holdersToken holders
Top transfer-derived holders — served only when the derivation is provably complete (`complete: false` + empty items otherwise).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed token contract address |
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Exclusive upper bound on block number (cursor pagination). |
Examples
curl "https://x.mantis.dev/v1/tokens/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/holders" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/tokens/{addr}/ohlcToken OHLC candles
OHLC candles aggregated from our own 5-minute price buckets; no external calls at request time.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed token contract address |
| interval | query | stringnull | no | Candle width: `5m`, `1h` or `1d` (default `1h`). |
| limit | query | integernull | no | Candles returned, clamped to 1..=500 (default 168). |
Examples
curl "https://x.mantis.dev/v1/tokens/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/ohlc" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/tokens/{addr}/priceToken price
Latest own-bucket USD price + 24 h change. `price: null` = no bucket from any source yet.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed token contract address |
Examples
curl "https://x.mantis.dev/v1/tokens/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/price" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/tokens/{addr}/transfersToken transfers
Transfers of one token, newest first; composite cursor `before` + `before_index` + `before_batch`.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| addr | path | string | yes | 0x-prefixed token contract address |
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound block number. |
| before_index | query | integernull | no | Cursor: `tx_index` (txs) or `log_index` (transfers) within `before`. |
| before_batch | query | integernull | no | Cursor: `batch_index` within `before`/`before_index` (transfers only). |
| nft | query | booleannull | no | Transfers filter: `true` = NFT (721/1155) only, `false` = ERC-20 only, absent = all standards. |
Examples
curl "https://x.mantis.dev/v1/tokens/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transfers" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
txs
GET/v1/txsList transactions
Latest transactions, newest first. Composite cursor: pass back `next_before` + `next_before_index`.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integernull | no | Page size, clamped to 1..=100 (default 25). |
| before | query | integernull | no | Cursor: exclusive upper bound block number. |
| before_index | query | integernull | no | Cursor: `tx_index` (txs) or `log_index` (transfers) within `before`. |
| before_batch | query | integernull | no | Cursor: `batch_index` within `before`/`before_index` (transfers only). |
| nft | query | booleannull | no | Transfers filter: `true` = NFT (721/1155) only, `false` = ERC-20 only, absent = all standards. |
Examples
curl "https://x.mantis.dev/v1/txs" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/txs/{hash}Get one transaction
Full transaction detail by 0x-prefixed 32-byte hash.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| hash | path | string | yes | 0x-prefixed transaction hash |
Response
| block_hash | string | |
| block_number | int64 | |
| contract_created | stringnull | |
| effective_gas_price | string | |
| finality | int | |
| from | string | |
| gas_used | int64 | |
| hash | string | |
| input | string | |
| l1_fee | stringnull | |
| nonce | int64 | |
| status | integernull | |
| timestamp | int64 | |
| to | stringnull | |
| traces_indexed | boolean | |
| tx_index | int | |
| tx_type | int | |
| value | string |
Examples
curl "https://x.mantis.dev/v1/txs/0x0000000000000000000000000000000000000000000000000000000000000000" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/txs/{hash}/internalTransaction internal calls
Internal (traced) calls of one transaction; empty until the block's traces are indexed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| hash | path | string | yes | 0x-prefixed transaction hash |
Examples
curl "https://x.mantis.dev/v1/txs/0x0000000000000000000000000000000000000000000000000000000000000000/internal" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/txs/{hash}/logsTransaction logs
Event logs of one transaction; `event` names known signatures, never guesses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| hash | path | string | yes | 0x-prefixed transaction hash |
Examples
curl "https://x.mantis.dev/v1/txs/0x0000000000000000000000000000000000000000000000000000000000000000/logs" \ -H "Authorization: Bearer qv_live_YOUR_KEY"
GET/v1/txs/{hash}/transfersTransaction token transfers
Token transfers (ERC-20/721/1155) decoded from one transaction.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| hash | path | string | yes | 0x-prefixed transaction hash |
Examples
curl "https://x.mantis.dev/v1/txs/0x0000000000000000000000000000000000000000000000000000000000000000/transfers" \ -H "Authorization: Bearer qv_live_YOUR_KEY"