Skip to content

You are viewing Arc Testnet (chain 5042002). Tokens here have no value.

USDC Price:$1.0000Gas:
Arcscan

The Arc mainnet API

Every block of Arc mainnet, from the genesis block to the one being proposed right now, over a typed REST API and over an Etherscan-shaped one your existing code already speaks.

You are on the testnet site

This page is about Arc mainnet, chain 5042: every route, figure and example on it was measured against https://api-testnet.arc-scan.io. The header and footer around it belong to the testnet site, which serves chain 5042002, and nothing below describes that chain. Read it as the mainnet offer it is, and switch hosts before you call anything here.

Indexed from block 0

Chain 5042 is indexed from its genesis block with no gaps, and the node behind it keeps full history. Any block, any transaction, any receipt, any balance, as far back as the chain goes.

Take none of that on trust: one call states it, and the figures below are read from that call.

Read from /v1/chain, and refreshed at most once an hour.

Base URL

One base URL, and it is this.

https://api-testnet.arc-scan.io

Callable straight from a browser: a response carries access-control-allow-origin: * and allows GET, HEAD and OPTIONS. It exposes ETag, the rate-limit headers and X-Request-Id, so a client can read them rather than guess. Only those three methods, though — a browser cannot POST here, which is why the MCP endpoint is not reachable this way. curl, a backend, a bot or an indexer are unaffected.

Start here

Every command on this page was run against the live service, and every response shown is what came back.

What is held, and how fresh it is

Chain constants, node capabilities and exactly which blocks are indexed. One call, and nothing else on this page has to be taken on trust.

curl -s -H 'User-Agent: my-app/1.0' https://api-testnet.arc-scan.io/v1/chain

It returned

{
  "chain_id": 5042,
  "name": "Arc",
  "is_testnet": false,
  "mainnet_soon": false,
  "native": {
    "symbol": "USDC",
    "decimals": 18
  },
  "erc20_native": {
    "address": "0x3600000000000000000000000000000000000000",
    "decimals": 6
  },
  "block_time_ms": 506,
  "finality": "instant",
  "capabilities": {
    "ots": false,
    "ots_search": false,
    "trace": true,
    "debug": false,
    "archive": true,
    "tx_index": true,
    "holder_index": true,
    "verified_source": false,
    "verified_source_note": "<-- elided -->",
    "internal_transactions": true
  },
  "index": {
    "available": true,
    "streams": [
      {
        "stream": "balances",
        "genesis_block": 0,
        "last_contiguous_block": 13849844,
        "from_block": 0,
        "to_block": 13849844,
        "ranges": 1,
        "blocks_indexed": 13849845,
        "contiguous_from_genesis": true
      },
      {
        "stream": "chain",
        "genesis_block": 0,
        "last_contiguous_block": 13849856,
        "from_block": 0,
        "to_block": 13849856,
        "ranges": 1,
        "blocks_indexed": 13849857,
        "contiguous_from_genesis": true
      },
      {
        "stream": "traces",
        "genesis_block": 0,
        "last_contiguous_block": -1,
        "from_block": null,
        "to_block": null,
        "ranges": 0,
        "blocks_indexed": 0,
        "contiguous_from_genesis": false
      }
    ],
    "head_block": 13849856,
    "chain_blocks_indexed": 13849857,
    "chain_genesis_block": 0,
    "chain_first_indexed_block": 0,
    "covers_chain_from_block": 0,
    "complete_above_start_block": true,
    "unindexed_blocks_below_start": 0,
    "complete": true,
    "message": null
  },
  "capabilities_note": null,
  "capabilities_note_phrases": []
}

Send a User-Agent

Name your client in a User-Agent header. Our edge answers error 1010 to several default agent strings — Python-urllib/3.12 gets a 403 — so an untouched HTTP client fails on its first request before it ever reaches us.

The call your existing Etherscan code already makes

The key goes in the query string as <mono>apikey</mono>, which is where Etherscan clients already put it.

curl -s -H 'User-Agent: my-app/1.0' "https://api-testnet.arc-scan.io/api?module=account\
&action=txlist&address=0x03a13352ef67977d1601ec1276e9bc27c0ee7b75\
&startblock=13800000&endblock=13830000&page=1&offset=1&sort=desc\
&apikey=YourApiKeyToken"

It returned

{
  "status": "1",
  "message": "OK",
  "result": [
    {
      "blockNumber": "13830000",
      "timeStamp": "1785842041",
      "hash": "0x3ae69af3843877c10d1aedde0fb299f0de358a76c4b704f338fc738b5d952ef5",
      "nonce": "88966",
      "blockHash": "",
      "transactionIndex": "0",
      "from": "0x92Df01DB3C69a49f4c4E694849E44C75D62B6752",
      "to": "0x03a13352eF67977d1601ec1276e9BC27C0Ee7b75",
      "value": "0",
      "gas": "598264",
      "gasPrice": "40000000000",
      "isError": "0",
      "txreceipt_status": "1",
      "input": "",
      "contractAddress": "",
      "cumulativeGasUsed": "348673",
      "gasUsed": "348673",
      "confirmations": "2933",
      "methodId": "0x38aaba3d",
      "functionName": "open"
    }
  ]
}

Moving existing Etherscan code

Change the base URL. Keep sending apikey as a query parameter. Nothing else changes: the envelope, the string-typed result and the HTTP 200 on every answer are the same contract.

A CSV of one address's transactions

Every export is about one address, so <mono>address</mono> is required and a block or date range narrows it. Four datasets — <mono>transactions</mono>, <mono>internal</mono>, <mono>logs</mono>, <mono>token-transfers</mono> — and <mono>/v1/export/limits</mono> states the caps before you meet them.

curl -s -H 'User-Agent: my-app/1.0' "https://api-testnet.arc-scan.io/v1/export/transactions/csv\
?address=0x03a13352ef67977d1601ec1276e9bc27c0ee7b75\
&from_block=13800000&to_block=13800010"

It returned

block_number,block_time_utc,block_timestamp,tx_hash,tx_index,from,to,created_contract,direction,value_raw,value_18dec,fee_raw,fee_18dec,gas_limit,gas_used,effective_gas_price_raw,nonce,tx_type,method_id,input_size,status
13800001,2026-08-04T07:00:48Z,1785826848,0xb244d2791aa392fcc49e2c6bca9df0b6c402da2c1cd322f6356724fb77cc3131,0,0x8031885f93e31676132128557e987a011ff99d27,0x03a13352ef67977d1601ec1276e9bc27c0ee7b75,,in,0,0,13951720000000000,0.01395172,570664,348793,40000000000,141603,2,0x38aaba3d,516,success

New blocks are pushed, not polled

/v1/stream/head is a real text/event-stream: one event per committed block, about two a second on a half-second chain, each carrying the server's own clock so a consumer can correct for skew. Hold the connection open and the blocks arrive. There is nothing to poll and no interval to tune.

Follow the head of the chain

This command does not return. Two consecutive events from a live connection are shown below, three seconds apart.

curl -N -H 'User-Agent: my-app/1.0' https://api-testnet.arc-scan.io/v1/stream/head

It returned

event: head
data: {"height": 13830746, "hash": "0xc580470583007f827ebfb3098b66d0682528c4ebaca4eb1213ab992c5952e65e", "timestamp": 1785842418, "tx_count": 1, "server_now": 1785842422, "available": true}

event: head
data: {"height": 13830751, "hash": "0x63d064be03dc0f5d530e10350b8dddd3de2cc8e6dbbffbe59306bb9fdc96c162", "timestamp": 1785842421, "tx_count": 1, "server_now": 1785842422, "available": true}

What is served

Checked one route at a time against the running mainnet service, rather than generated from a schema. The service publishes more routes than these; what is listed is what is supported.

EndpointWhat it answers
/v1/chainChain id, native token, node capabilities, and the exact block range held by each indexer stream.
/v1/network/status/v1/network/validatorsThe chain head and its age in seconds, the measured block time, and the active validator set.
/v1/blocks/v1/blocks/{ref}/v1/blocks/{ref}/txsBlocks newest first, one block, and the transactions inside it. Every block names the validator that proposed it.
/v1/txs/v1/txs/{hash}/v1/txs/{hash}/trace/v1/txs/{hash}/rawTransactions newest first, one transaction with its status and revert reason, the internal call frames recovered for it, and the unmodified node objects behind it.
/v1/address/{addr}/v1/address/{addr}/txs/v1/address/{addr}/logs/v1/address/{addr}/activityAn address with its balance and activity, the transactions it sent and received, the logs it emitted, and one merged timeline of everything that touched it.
/v1/address/{addr}/tokens/v1/address/{addr}/facts/v1/address/{addr}/contractToken balances held by an address, how it was funded and when it was first and last active, and, for a contract, its deployed bytecode.
/v1/tokens/{addr}/v1/tokens/{addr}/holders/v1/tokens/{addr}/transfersOne token's on-chain facts, its holders ranked by balance, and its transfers.
/v1/approvals/{addr}Every ERC-20, ERC-721 and ERC-1155 approval an address has granted and not revoked.
/v1/search/v1/search/suggestResolve a height, hash, address or token, with suggestions as you type.
/v1/stats/summary/v1/stats/gas/v1/stats/tx-historyNetwork summary, gas statistics, and the daily transaction history over complete UTC days.
/v1/charts/v1/charts/{metric}/v1/charts/{metric}/csvA catalogue of twenty-four daily metrics, each readable as JSON or as CSV.
/v1/explore/*Chain-wide lists: accounts, contracts, tokens, token transfers, address labels, a directory of named entities, and top statistics over a chosen window.
/v1/filter/limits/v1/filter/transactions/v1/filter/token-transfersQuery transactions and token transfers by address, method, amount, asset, status and range. The limits route states the bounds before you hit them.
/v1/export/limits/v1/export/resolve/v1/export/{dataset}/csvCSV for transactions, internal transactions, logs and token transfers, plus a route that maps a date range onto a block range.An export is always about one address: address is required, and a range narrows it rather than replacing it.
/v1/actions/categoriesThe categories used to classify what a transaction actually did.
/v1/stream/headServer-sent events, one per committed block, each carrying the server's clock so a consumer can correct for skew.

The Etherscan-shaped surface

One path, dispatching on module and action in the query string. Every answer is HTTP 200, so a strict client library cannot crash on a status code. Both GET and form-encoded POST are accepted, and module=proxy passes thirteen JSON-RPC methods straight through to the node.

moduleactionWhat it answers
accountbalanceNative balance, 18-decimal integer string
accountbalancemultiUp to 20 addresses per call
accounttxlistTransactions sent or received by an address, read from the index
accounttokentxServed from the scanned window; requires startblock and endblockThe token name, symbol and decimal fields come back empty on this chain. Read a token's scale from the token route, never from a transfer row.
accounttokenbalanceGenuine ERC-20 query; returns the contract's own decimal scale
accountaddresstokenbalanceEvery token balance held by one address
blockgetblockrewardblockReward is the sum of transaction fees; there is no issuance and no uncle reward
blockgetblocknobytimeBinary search over heights; immutable, cached permanently
blockgetblockcountdownUses the measured block time, not a constant
transactiongetstatusExecution status
transactiongettxreceiptstatusReceipt status
logsgetLogsRange-clamped; an over-range request names the maximum span
contractgetabiThe ABI of a contract verified on ArcscanNo contract on this chain is verified yet, so getabi answers NOTOK and getsourcecode answers an empty record. The deployed bytecode is served either way.
contractgetsourcecodeVerified source, compiler settings and ABINo contract on this chain is verified yet, so getabi answers NOTOK and getsourcecode answers an empty record. The deployed bytecode is served either way.
tokentokenholderlistHolders and balances for one token
statstokensupplyTotal supply, read from the contract
statsethsupplyNative supply, 18-decimal integer string
statsethpriceThe gas token is a dollar by construction, so this reports 1.00
statsdailytxnfeeTotal transaction fees per complete UTC day
statsdailynewaddressAddresses seen for the first time, per complete UTC day
proxyeth_*Block, transaction, call, code, storage, gas and raw-send methods

Rate limit, errors and paging

Rate limit

A public caller gets a burst of 300 requests that refills at 60 a second. Every response states where you are, and a refusal is HTTP 429 carrying retry-after.

The bucket is keyed on the calling address as our edge sees it, so callers sharing one NAT or one cloud egress address share one bucket.

x-ratelimit-limit: 300
x-ratelimit-remaining: 299

Errors

On /api a refusal is HTTP 200 with status set to 0 and a sentence in result saying why, never a 404, so a strict client library cannot crash on it.

On /v1 a request rejected as invalid comes back through the edge as a 404 rather than a 400. Check the parameters before concluding that a route does not exist.

Paging

List routes are cursor-paged: an answer carries page.next, and passing it back as cursor returns the following page. Page size is capped at 100.

What this API does not answer

Published so you can build around it rather than discover it.

Internal transactions

Ask about one transaction and you get its internal calls: the per-transaction trace route answers 200 with the real frames, and account/txlistinternal returns the same frames when you pass txhash. Ask about an address or about the whole chain and you get a refusal instead, because Arcscan's own traces index holds no blocks on this deployment: /v1/explore/internal-txs answers 501 CAPABILITY_UNAVAILABLE with the missing capability named, account/txlistinternal by address refuses and says why, and the internal CSV export comes back with its header and no rows. That is a refusal you can detect, never a short list you cannot. State changes are a separate gap: the per-transaction state route still answers 501, because a state diff has to be produced by re-executing the transaction against the state as it stood before its block, and the endpoint this chain is read from does not serve the calls that needs.

How far one log query reaches

logs/getLogs answers on chain 5042 over a span of at most 10,000 blocks, and a request wider than that is refused with the maximum named rather than quietly answered from part of the range. account/tokentx answers too, and needs startblock and endblock spanning at most 200,000 blocks. Neither cap applies to our own index, which is where the wider questions are answered: logs per address on the address logs route, transfers per token on the token transfers route, and chain-wide through /v1/explore/token-transfers.

Verified source

Our verification provider does not cover chain 5042, so no mainnet contract is verified here today and none can be until it does. The deployed bytecode, the creation bytecode and the contract's creator are served regardless.

Off-chain data

No oracle prices, no market capitalisation, no logos, no websites, no curated exchange labels. The address labels published here are the ones provable from chain data — validators, system contracts, contracts we watched deploy — and there will not be a guessed one.

Actions that answer with a refusal

Each carries its own reason in the result rather than one generic error.

contract.getcontractcreation
The node behind chain 5042 does not expose the otterscan namespace. A contract's creator and creation transaction are on the address contract route.
account.getminedblocks
Arc has no mining and no block reward: blocks are proposed by a rotating BFT validator set, and the only value in a block is its transaction fees. The proposer column also carries no index, so this could not be answered without a full table scan. The blocks route names the validator instead.
account.tokennfttx
ERC-721 transfers are indexed, but not by address — the transfer table has no sender-and-recipient index, so filtering by an address would be a full scan. They are readable per token and chain-wide.
account.token1155tx
The same, for ERC-1155.
account.addresstokennftbalance
Our balances stream stores fungible balances only — one amount per token and holder, with no token-id dimension — so an NFT inventory cannot be read from it. The ERC-20 form of the question is answered.
token.tokeninfo
Most of this action's fields are off-chain: price, market capitalisation, website, social links. Arcscan holds no off-chain token data and consults no price oracle. The on-chain half — name, symbol, decimals, total supply, holder count — is served by the token route.
contract.verifysourcecode
Verification does not take Etherscan's flattened-source form fields. Submit Solidity standard JSON through the verification page, which is where that route is reachable.

Asking for a key

If you are building on this data, write and say who you are, what you are building, and roughly what volume you expect. That shapes what the key system has to do, and it is how you hear about a dedicated API address before it is announced.

Until then the base URL above serves you unauthenticated, and an apikey parameter is accepted and ignored, so an existing Etherscan client keeps working unchanged.

The full route-by-route reference, generated from the service's own schema, is on the API documentation page.

Arc mainnet API — Circle's Arc, chain ID 5042 | Arcscan