API
How to call Starkscan REST—base URL, auth, lists, errors. Paths live in the API reference.
How to call Starkscan REST—base URL, auth, lists, errors. Paths live in the API reference.
The explorer, SDK, and CLI share one REST contract. For every path and field, open the API reference or mezcal-openapi.yaml. This page is how to use the API: URL shape, keys, paging, mistakes we see in the wild.
Hosted external lane:
MEZCAL_BASE_URL = https://<host>/api/v1/... → example: https://<host>/api/v1/SN_MAIN/status/v1/... explorer lane for external integrations; it is reserved for app traffic on Starkscan-hosted pages.Same objects as JSON: Dashboard · Transactions · Contracts · Watchlist
The sidebar under API reference is the full list. This table orients you:
| Tag | Covers |
|---|---|
| Account | Session-authenticated self-serve API-key lifecycle and usage |
| Addresses | Activity, txs, holdings, aggregate views |
| Blocks | Block metadata and lists |
| Contracts | Class, verification, reads |
| Reference | Generated OpenAPI artifacts and reference surfaces |
| Search | Explorer search |
| Status | Chain status |
| Tokens | Metadata, supply, balances, transfers |
| Transactions | Detail, previews, related reads |
| Utilities | Helpers; key tier may vary (Advanced utilities) |
Protocol-domain surfaces are not part of the public preview docs contract until Starkscan exposes them explicitly.
| Tier | Meaning |
|---|---|
| Official public API | Default contract in /docs and Scalar |
| Advanced utilities | Supported, often needs a broader key |
| Partner | Partner-only indexed analytics such as token-holder census |
| Internal-only | App or ops; not your integration contract |
Start on the official tier. Add utilities only for batch jobs that truly need them.
The OpenAPI reference includes x-mezcal-certification on each operation.
| State | Use it how |
|---|---|
certified | Safe default for production client workflows. Current launch set: status, block read, tx read, token total supply, and token balance-of. |
beta | Usable with named clients and explicit limits. Treat indexed lists, holder census, and protocol routes as beta until their reconciliation gates are complete. |
experimental | Partner preview only. Do not depend on schema stability. |
unsupported | Not for client use. |
Correctness is the hard launch gate. For token reads, use block_tag=<block_number> or block_tag=<block_hash> when you need reproducible exactness; latest and pending are live moving state. If a route is slow but certified, use backoff, caching, or a lower quota. If a route is fast but not yet reconciled, keep it out of unattended production paths.
/v1/me/* is the personal-workspace control plane behind the signed-in /api-key experience.
X-Starkscan-Api-Key.GET / HEAD / OPTIONS may use the hosted browser session cookie or a bearer session token.POST / DELETE must use Authorization: Bearer <session_token>.GET /v1/me/api-keys lists metadata only.POST /v1/me/api-keys issues or rotates the default live read key.DELETE /v1/me/api-keys/{public_id} revokes one key.GET /v1/me/usage returns recent request activity, failures, and per-key aggregates.See Self-serve account routes for the exact auth shape and examples.
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/status"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/token/{token}/total-supply?block_tag=latest"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/token/{token}/balance-of/{address}?block_tag=latest"
For deterministic checks, resolve a block first and pass it as block_tag:
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/token/{token}/balance-of/{address}?block_tag=10000000"
The safe block reads in the public spec come with concrete examples and defaults:
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/blocks?limit=25"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/block/8717378?tx_limit=50"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/block/8717378/txs?limit=25"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/address/{address}/activity?limit=50"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/address/{address}/transactions?limit=50"
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/address/{address}/token-holdings"
Filter transfers to several wallets—repeat address=:
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/token/{token}/transfers?address={walletA}&address={walletB}&limit=100"
One POST for many summaries (utility tier):
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
-d '{"addresses":["{walletA}","{walletB}","{walletC}"]}' \
"$MEZCAL_BASE_URL/v1/SN_MAIN/address/summaries"
Full scripted loop: Monitor 10 wallets.
POST …/tx/previews → body {"hashes":[...]}POST …/address/summaries → body {"addresses":[...]}GET …/contract/.../read → Starknet selector, not a Cairo nameGET …/verification 404 → no record yet, not a missing routeX-Starkscan-Api-Keybalance-of — you know the contract address.token-holdings — you care about the wallet; symbols like USDC can point at more than one live contract.balance-of; use holdings.completeness.complete=true; legacy clients should also require exact=true, truncated=false, and completeness.reasonCode="complete".GET /v1/{chain}/token/{token}/holders is a partner-tier indexed holder census for token-contract-first analytics. It is not a substitute for transfer-history replay and is intentionally outside the default read-key lane.Partner holder example:
curl \
-H "X-Starkscan-Api-Key: $MEZCAL_API_KEY" \
"$MEZCAL_BASE_URL/v1/SN_MAIN/token/{token}/holders?limit=50"
/v1/{chain}/*, send X-Starkscan-Api-Key.mzk_live_key_51199d...REDACTED./v1/me/*, use Better Auth sessions for your personal Starkscan workspace: cookie auth for safe reads, bearer token required for POST / DELETE.X-Request-Id when you open a support thread.code, message, docSlug, and requestId. The X-Request-Id header is canonical.X-Mezcal-Route-Class when present so agents can back off by class. The route-class response header keeps its legacy name for compatibility while API-key requests accept X-Starkscan-Api-Key.503 as retryable when it indicates temporary unavailability, and honor Retry-After when present.rust-exp/scripts/agent-api-conformance-smoke.sh against the target host; it validates auth failures, request IDs, holdings completeness, and the published OpenAPI agent contract without printing the full key.HTTP/1.1 503 Service Unavailable
Retry-After: 5
X-Request-Id: mzk-...
Content-Type: application/json; charset=utf-8
{"code":"service_unavailable","message":"Temporarily unavailable","docSlug":"api/retry","requestId":"mzk-..."}
Honor Retry-After. Do not spin in a tight loop.
HTTP/1.1 401 Unauthorized
X-Request-Id: mzk-...
WWW-Authenticate: Bearer realm="mezcal", error="invalid_token"
Content-Type: application/json; charset=utf-8
{"code":"unauthorized","message":"Unauthorized","docSlug":"api/auth","requestId":"mzk-..."}
HTTP/1.1 403 Forbidden
X-Request-Id: mzk-...
WWW-Authenticate: Bearer realm="mezcal", error="insufficient_scope", scope="batch"
Content-Type: application/json; charset=utf-8
{"code":"forbidden","message":"Forbidden","docSlug":"api/auth","requestId":"mzk-..."}
| Need | Doc |
|---|---|
| Typed TS | SDK |
| Shell | CLI |
| MCP | MCP quickstart |
| Click-only | Explorer |