Zenith EVM Explorer
K
DashboardBlocksTransactionsLinked TransactionsContractsTokensFaucetStatsAPI
DashboardBlocksTxsLinkedContracts

API Documentation

REST API endpoints for programmatic access to Zenith EVM Explorer data

Base URL

https://explorer.testnet.zenith.network/api

Network configuration

Add the network to a wallet (MetaMask → Add network) or point tooling at it with these values.

Network nameZenith Testnet
Chain ID936485 (0xe4a25)
RPC URLhttp://127.0.0.1:9200
Currency symbolZTH
Block explorer URLhttps://explorer.testnet.zenith.network

Chain ID is 936485 — verify anytime with curl "https://explorer.testnet.zenith.network/api?module=proxy&action=eth_chainId". Need testnet ZTH for gas? Use the faucet.

Rate limits & usage policy

This is a public testnet explorer with no API key. Limits are per client IP (a shared or proxied IP shares its bucket) and are set to meet or exceed a stock Blockscout's defaults, so testing here is never more constrained. Exceeding a limit returns HTTP 429 with a Retry-After header (or the Etherscan-style {status:"0"} envelope).

  • General: 10 requests / second / IP (600/min) across all endpoints, including the JSON-RPC proxy module — matches Blockscout's most generous default (its no-key IP tier is 3/s).
  • Contract verification: 30 submissions / hour / IP (compilation is expensive). Source is capped at 500 KB, only real solc release versions are accepted, and at most 2 compilations run concurrently.
  • Result sizes: list endpoints (txlist, tokentx) return up to 10,000 rows; getLogs up to 1,000 — paginate with page/offset.
  • For sustained high-throughput load testing, point your tooling at the public eth-rpc node directly rather than this explorer. Limits can be raised per deployment; they are subject to change.

REST Endpoints

GET/blocks

Fetch paginated EVM blocks. Returns an array of block objects along with a total count for pagination.

Parameters

NameTypeRequiredDescription
pagenumberOptionalPage number, starting from 1. Defaults to 1.
pageSizenumberOptionalNumber of results per page. Defaults to 25, max 100.

Example Request

curl "https://explorer.testnet.zenith.network/api/blocks?chain=evm&page=1&pageSize=10"

Example Response

{
  "data": [
    {
      "id": 1,
      "blockNumber": "13800",
      "blockHash": "0x01a6ee89...c893aa04fd",
      "parentHash": "0xf3c2a1b4...d8e9f01234",
      "timestamp": "2026-02-27T10:30:00.000Z",
      "txCount": 1,
      "gasUsed": "21000",
      "gasLimit": "30000000",
      "stateRoot": "0xab12cd34...ef567890ab"
    }
  ],
  "total": 13800
}
GET/transactions

Fetch paginated EVM transactions. Returns transaction objects with decoded data when available.

Parameters

NameTypeRequiredDescription
pagenumberOptionalPage number, starting from 1. Defaults to 1.
pageSizenumberOptionalNumber of results per page. Defaults to 25, max 100.

Example Request

curl "https://explorer.testnet.zenith.network/api/transactions?chain=evm&page=1&pageSize=5"

Example Response

{
  "data": [
    {
      "id": 1,
      "txHash": "0x160bd584...747f1a2b3c",
      "blockNumber": "13800",
      "txIndex": 0,
      "fromAddress": "0x742d35Cc...5f2bD18",
      "toAddress": "0x1234567890Ab...12345678",
      "value": "0",
      "gasUsed": "21000",
      "gasPrice": "1000000000",
      "inputData": "0x...",
      "status": 1,
      "timestamp": "2026-02-27T10:30:00.000Z"
    }
  ],
  "total": 13800
}
GET/gas

Returns the current gas price, base fee, and priority fee from the Zenith EVM RPC. All values are in wei, returned as strings.

Parameters

No parameters required.

Example Request

curl "https://explorer.testnet.zenith.network/api/gas"

Example Response

{
  "gasPrice": "1000000000",
  "baseFee": "875000000",
  "priorityFee": "125000000"
}
GET/health

Health check endpoint returning the status and latency of the explorer's backing services (database, EVM RPC, and internal indexing services). Returns HTTP 200 when all critical services are online, 503 when degraded.

Parameters

No parameters required.

Example Request

curl "https://explorer.testnet.zenith.network/api/health"

Example Response

{
  "status": "ok",
  "timestamp": "2026-02-27T10:30:00.000Z",
  "services": {
    "database": {
      "status": "online",
      "latency": 2
    },
    "evm": {
      "status": "online",
      "latency": 12,
      "blockNumber": "13800"
    }
  }
}
GET/faucet

Faucet status: whether it is enabled, the target network, the per-claim ZTH amount, and the cooldown window (minutes + a human label).

Parameters

No parameters required.

Example Request

curl "https://explorer.testnet.zenith.network/api/faucet"

Example Response

{
  "enabled": true,
  "networkId": "final-testnet",
  "networkLabel": "Testnet",
  "zthAmount": "100",
  "cooldownMinutes": 30,
  "cooldownLabel": "30 min"
}
POST/faucet

Request testnet ZTH (native gas token) for an address. Subject to a per-address and per-IP cooldown (HTTP 429 with Retry-After when on cooldown).

Parameters

NameTypeRequiredDescription
addressstringRequiredRecipient 0x address (JSON body: { "address": "0x…" }).

Example Request

curl -X POST "https://explorer.testnet.zenith.network/api/faucet" -H "Content-Type: application/json" -d '{"address":"0x0000000000000000000000000000000000000000"}'

Example Response

{
  "ok": true,
  "zthTxHash": "0x0076230d...247bc762",
  "zthAmount": "100"
}

Server-Sent Events (SSE)

SSE/stream

Real-time event stream using Server-Sent Events (SSE). Subscribe to a channel to receive live updates as new blocks and transactions are indexed. Events are delivered via PostgreSQL LISTEN/NOTIFY.

Parameters

NameTypeRequiredDescription
channelstringOptionalThe event channel to subscribe to. Defaults to "evm:block".

Available Channels

ChannelPG ChannelDescription
evm:blockevm_blockNew EVM blocks and transactions indexed from the Zenith EVM eth-rpc
evm:transactionevm_blockAlias for evm:block (transactions are included in block events)

Event Format

Events follow the standard SSE format. Each event contains a JSON payload in the data field. Only events with a type or correlationId field are forwarded. The server sends periodic keepalive comments (lines starting with :) to maintain the connection.

Example: Connect with curl

curl -N "https://explorer.testnet.zenith.network/api/stream?channel=evm:transaction"

Example: Connect with JavaScript

const source = new EventSource("/api/stream?channel=evm:transaction");

source.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("New event:", data);
};

source.onerror = (err) => {
  console.error("SSE error:", err);
};

Example: EVM Transaction Event

data: {"type":"evm","id":"0x160bd584...","hash":"0x160bd584...","timestamp":"2026-02-27T10:30:00.000Z","description":"EVM tx 0x742d35...→ 0x123456..."}

Contract Verification (Etherscan-compatible)

GET / POST/api

An Etherscan-compatible endpoint so standard EVM tooling can verify contracts against this explorer. Submitted source is compiled with solc and matched against the on-chain runtime bytecode (tolerating trailing metadata & immutables). Verified contracts decode across the explorer and expose their source on the address page.

Supported actions (module=contract)

actionDescription
verifysourcecodePOST source (solidity-single-file or solidity-standard-json-input) → returns a GUID. Compiles + bytecode-matches, then stores the ABI & source.
checkverifystatusPoll a GUID: “Pass - Verified”, “Pending in queue”, or a failure reason.
getabiReturns the verified ABI as a JSON string.
getsourcecodeReturns source, ContractName, CompilerVersion, OptimizationUsed, Runs, ConstructorArguments, etc.
getcontractcreationFor contractaddresses (CSV, up to 10): returns each contract's creator address and creation txHash.
verifyproxycontractDetects a proxy's implementation (EIP-1967 / EIP-1822 / beacon slots, or expectedimplementation) and links it → GUID.
checkproxyverificationPoll a proxy-verification GUID; on success getsourcecode reports Proxy:"1" + Implementation.

Verify with Foundry

forge verify-contract \
  --verifier etherscan \
  --verifier-url https://explorer.testnet.zenith.network/api \
  --compiler-version v0.8.35+commit.47b9dedd \
  <ADDRESS> src/MyContract.sol:MyContract

Or call the API directly

# Submit
curl -X POST "https://explorer.testnet.zenith.network/api" \
  -d "module=contract&action=verifysourcecode&codeformat=solidity-single-file" \
  --data-urlencode "[email protected]" \
  --data-urlencode "contractaddress=0x..." \
  --data-urlencode "contractname=MyContract" \
  --data-urlencode "compilerversion=v0.8.35+commit.47b9dedd" \
  -d "optimizationUsed=0&runs=200"
# → {"status":"1","result":"<GUID>"}

# Poll
curl "https://explorer.testnet.zenith.network/api?module=contract&action=checkverifystatus&guid=<GUID>"
# → {"status":"1","message":"Perfect match","result":"Pass - Verified"}

solc 0.8.35 is bundled; any other valid compiler version is fetched on demand (the native solc binary, run server-side) and cached, so contracts built with any solc release verify. First use of a new version adds a few seconds while it downloads. Verification is limited to 30/hour per IP with a 500KB source cap (see “Rate limits” above); an admin token bypasses the limits.

Hardhat 3 config (hardhat.config.ts)

// Requires an up-to-date @nomicfoundation/hardhat-verify — Hardhat 3.0.6
// had a bug where chainDescriptors.apiUrl was ignored (fixed upstream).
chainDescriptors: {
  936485: {
    name: "Zenith",
    blockExplorers: {
      etherscan: {
        name: "Zenith Explorer",
        url: "https://explorer.testnet.zenith.network",
        apiUrl: "https://explorer.testnet.zenith.network/api",
      },
    },
  },
},
verify: { etherscan: { apiKey: "unused" } }, // any non-empty string; this API ignores it

Hardhat 2 config (hardhat.config.js)

etherscan: {
  apiKey: { zenith: "unused" },
  customChains: [{
    network: "zenith",
    chainId: 936485,
    urls: { apiURL: "https://explorer.testnet.zenith.network/api", browserURL: "https://explorer.testnet.zenith.network" },
  }],
}

Chain ID is 936485 — not 1337. Hardhat refuses to verify when the connected chain id doesn't match its config (and treats 1337/31337 as local dev chains), so configs copied from older docs with chainId 1337 fail. Confirm with curl "https://explorer.testnet.zenith.network/api?module=proxy&action=eth_chainId".

Tooling notes: Hardhat 3 verification works via chainDescriptors (above) on an up-to-date hardhat-verify; versions around 3.0.6 ignored the custom apiUrl and silently called etherscan.io — upgrade if verification seems to hit the wrong host. The @wagmi/cli etherscan plugin is hardcoded to etherscan.io — use its blockExplorer plugin with this API instead. The chainid and apikey params sent by Etherscan-v2-style clients are accepted and ignored.

viem / wagmi chain config

blockExplorers: {
  default: {
    name: "Zenith Explorer",
    url: "https://explorer.testnet.zenith.network",
    apiUrl: "https://explorer.testnet.zenith.network/api",
  },
}
GET/api— account & proxy modules

Beyond the contract module, the API implements the Etherscan account and proxy modules, so tools like Foundry cast, Brownie, ApeWorX, truffle-plugin-verify, and ethers' EtherscanProvider work directly.

module=account

txlistNormal transactions for an address (incl. the contract-creation tx, for constructor-arg recovery). Params: address, startblock, endblock, page, offset, sort.
tokentx / tokennfttxERC-20 / ERC-721 transfer events involving an address, with token name/symbol/decimals.
balance / balancemultiNative balance for one or many (comma-separated) addresses.
tokenbalanceERC-20 balanceOf. Params: contractaddress, address. Returns the raw (undivided) unit string.
txlistinternalReturns empty — internal-call traces are not indexed.

module=proxy

JSON-RPC passthrough to the network node — eth_blockNumber, eth_getTransactionByHash, eth_getCode, eth_call, etc. Returns the raw JSON-RPC response ({jsonrpc,id,result}).

module=stats & module=block

stats/tokensupply — live ERC-20 totalSupply (param: contractaddress). stats/ethprice — canonical shape with zero values (testnet token has no market price; lets hardhat-gas-reporter and similar degrade gracefully). block/getblocknobytime — closest block number for a unix timestamp (params: timestamp, closest=before|after).

module=logs

getLogs — event logs by address, fromBlock/toBlock, and topic0–topic3 (numeric fields hex-encoded, Etherscan shape). Used by OpenZeppelin Upgrades proxy verification.

Examples

# address transaction history
curl "https://explorer.testnet.zenith.network/api?module=account&action=txlist&address=0x...&sort=desc"

# ERC-20 transfers for an address
curl "https://explorer.testnet.zenith.network/api?module=account&action=tokentx&address=0x..."

# proxy JSON-RPC
curl "https://explorer.testnet.zenith.network/api?module=proxy&action=eth_blockNumber"
# → {"jsonrpc":"2.0","id":1,"result":"0x..."}

# event logs
curl "https://explorer.testnet.zenith.network/api?module=logs&action=getLogs&address=0x...&topic0=0xddf2..."

# link a proxy to its implementation
curl -X POST "https://explorer.testnet.zenith.network/api" -d "module=contract&action=verifyproxycontract&address=0x<proxy>"
curl "https://explorer.testnet.zenith.network/api?module=contract&action=checkproxyverification&guid=<GUID>"

Explorer URL Routes (EIP-3091)

MetaMask and Etherscan-style tooling build links with these paths. They are served directly at HTTP 200 (internal rewrites, so the URL stays put), so configure a wallet's block-explorer URL as https://explorer.testnet.zenith.network (no trailing slash).

RouteServes
/tx/:hash/transactions/:hash
/address/:address/addresses/:address
/block/:number/blocks/:number
/token/:address/addresses/:address

Notes

  • All numeric values that may exceed JavaScript's Number.MAX_SAFE_INTEGER (such as wei values and block numbers) are serialized as strings.
  • Pagination uses 1-based page numbering. REST list endpoints return up to 100 rows per page; the Etherscan account endpoints return up to 10,000 via offset.
  • All timestamps are returned as ISO 8601 strings.
  • Error responses use standard HTTP status codes with a JSON body containing an error field.
  • The SSE stream creates a dedicated PostgreSQL connection per subscriber. Clients should close connections when no longer needed.