Total Volume
—
Endpoints
—
Cached Answers
—
Packets Minted
—
— Live activity

Everything the gateway has recorded on chain, newest first. Bought is an agent minting prepaid quota; Called is quota being spent on an upstream request; Cached is an answer entering the shared cache, where any agent can reuse it for free until it expires; Committed is a batch of new answers written to Arc as one Merkle root: once 16 are waiting, or after 24 hours at most.

Wallet Service Event Detail Amount Time

Choose a wallet to continue

Arcapis currently supports MetaMask on . More wallets are coming soon.

Need USDC?

You need USDC on to pay for API calls. Connect a wallet, then choose Deposit to get its address as a QR code and send USDC to it.

Open Circle faucet (testnet)
⚠ Treasury address is a placeholder. Set TREASURY_ADDRESS in Netlify env vars (or in x402-challenge.js) before going live, or test payments will go to a placeholder address.
Available endpoints
Run request

Select an endpoint to begin.

Endpoint fee (× 1) — USDC
Arc gas (est.) — USDC
Total — USDC
Connect wallet to continue
—
—
Note. Packets are derived from confirmed payments under your connected wallet. URLs are deterministic per wallet × endpoint — keep them private.
Coming soon

Bring your own endpoint.

Self-serve provider onboarding: drop in a YAML spec or an OpenAPI URL, set your price, and we ship an arcapis.dev endpoint that handles billing, gas, and payouts in USDC.

YAML config Auto OpenAPI import Per-route pricing USDC payouts Webhook alerts
Non-custodial. Listing only grants the marketplace contract permission to move that one packet on sale — it never takes custody. Cancel any time, or revoke the approval directly on to walk away.
What arcapis is

A pay-per-call gateway for AI APIs on Arc. You buy a packet — an ERC-721 NFT that represents N prepaid calls to one endpoint — then your agent calls through the gateway. Two things set it apart from a plain API key:

1. Per-call EIP-712 auth. Every request carries a fresh signature instead of a long-lived bearer token, so a leaked signature risks one call, not your whole quota.
2. A cross-agent cache. Cacheable results are pinned to IPFS and shared across every agent — the first caller pays, everyone after reuses it free.

Quickstart

1. Buy a packet on the Buy APIs page (mint an NFT with quota). 2. Install the SDK. 3. Call.

npm i arcapis-sdk ethers
import { ArcApis } from 'arcapis-sdk';
import { Wallet } from 'ethers';

const arc = new ArcApis({
  signer: new Wallet(process.env.AGENT_PRIVATE_KEY),
  packetTokenId: 5,          // the packet you just bought
});

const r = await arc.call('embed', { input: 'hello agentic economy' });

if (r._cached) {
  console.log('FREE — cache hit, quota unchanged');
} else {
  console.log('PAID — quota now', r.calls_remaining);
}

No build step? Sign the EIP-712 message yourself and POST /api/call/<packetId>. The domain, types and headers are in the SDK README on npm.

Each call is sold at a fixed price, so each has a size limit. Text is measured in UTF-8 bytes: an English character is one byte, most other scripts take two to four. Chat: up to 8,000 bytes of text in, in up to 100 messages, and 1,024 tokens out, on the endpoint's own model. Embeddings: up to 16,000 bytes in up to 100 texts per call. Image: a prompt of up to 1,000 bytes; each call returns one 1024×1024 JPEG at medium quality, base64 in result.data[0].b64_json. A larger request is refused with 413 before any quota is spent.

Images usually come back in the same response (about 20 seconds). One that takes longer than about 40 seconds answers 202 with a job_id: GET /api/jobs/<job_id> until it answers 200 with the image (kept 24 hours). The call is taken once and refunded only if the provider fails; the SDK waits for you. Each IP address may make 300 calls a minute (429 past that).

Audio: send { audio: <base64>, filename: 'clip.mp3', language: 'vi' } to transcribe — flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav or webm, up to 4 MB. Each started five minutes of audio uses one call; the response's calls_used says how many.

The cross-agent cache

The cache key is keccak256(endpointId + body) — the packet ID is deliberately excluded, so a result one agent paid for is reused by every agent. The first agent to embed "summarise CCTP v2" pays; everyone after gets the same vector free until it expires.

CategoryCache TTLWhy
VECTOR30 days after last use, at most 90Embeddings are deterministic
LLM / IMAGE / AUDIOneverPer-prompt / creative output — always fresh

A cache hit returns the same shape as a paid call, plus a _cached block and an unchanged calls_remaining:

{
  "endpoint": "embed",
  "calls_remaining": 5,          // unchanged on a hit
  "result": { /* upstream body, fetched from IPFS */ },
  "_cached": { "hit": true, "age_seconds": 18, "ttl_seconds": 2592000, "cid": "bafkrei…", "batch": "0x3f9a…" }
}

Answers are committed to Arc in batches — one Merkle root per batch in CacheRootRegistry, with the batch itself on IPFS. A batch is committed once 16 answers are waiting, or once the oldest has waited 24 hours. _cached.batch names the root; GET /api/cache/proof?q=<queryHash> returns the proof, and CacheRootRegistry.verifyEntry checks it for free. Until its batch is committed, an answer reads "batch": null.

The copy behind _cached.cid is sealed, so only a caller holding the request can read it: { enc: "A256GCM", iv, tag, ct } in base64, AES-256-GCM under a key from HKDF-SHA256 over endpointId|body (the body as JSON with its keys sorted), salt arcapis-cache-v1, info answer. The result you are served is already opened.

To keep a call’s answer out of the cache — neither stored nor shared — send the header X-Arcapis-Cache: off (SDK: { cache: 'off' }). The call is charged as usual, an answer already cached can still be served to it for free, and a paid response says "cache_stored": false. Any value but on or off is refused with 400 before anything is spent.

Endpoints

Each endpoint answers with its own model; an answer from any other model is refused and the call refunded. Some endpoints are routed to a newer model of the same kind that costs less upstream (for example chat to GPT-6 Luna, once that is open); model in the response names the model that answered.

The catalogue as registered on chain, with the model each endpoint runs. Endpoints that are not open yet are listed as Inactive on the Buy APIs page.

IDNameCategoryModelPrice / call
Loading…
Authentication

Per-call EIP-712 (recommended). Each request signs a message binding packetId + endpointId + bodyHash + nonce + validUntil. A leaked signature is good for one call, not the whole packet. The SDK does this automatically.

Bearer (legacy). Authorization: Bearer ak_… still works server-side for older clients, but a leaked key drains the full quota until revoked — prefer EIP-712.

Errors and retries

A refused call spends nothing unless the table says otherwise. The SDK retries 409, 429 and 503 on its own, signing each attempt afresh.

StatuserrorMeaning
402packet_depletedNot enough calls left for this request (calls_needed says how many). Buy a new packet.
409quota_busyOther requests hold the packet's last calls right now. Retry in a moment.
413 / 400—The request is over the endpoint's size limits.
423packet_listed, packet_lockedThe packet is listed for sale, or its owner is listing it. Calls resume when that ends.
429rate_limitedMore than 120 calls on this packet in the last minute.
502upstream_failedThe provider returned an error, or did not answer within 45 seconds. The call was refunded.
503endpoint_unavailableThe endpoint is not being served right now. Nothing was spent; do not retry in a loop.
503upstream_rate_limitedThe provider is rate-limited. The call was refunded; retry after Retry-After.
503maintenanceArcapis is paused for maintenance; message says what. Do not retry in a loop.
Contracts — (chainId )
ContractAddressRole
Loading…

Every contract is source-verified — read the code and live state at .

Full SDK reference and the EIP-712 message format: arcapis-sdk on npm.