Everything one USDC send on Arc needs.
Show the token, show the balance, check the address, send, show the history. Five calls, read live from Arc mainnet, from $0.001 each. One key, plain fetch, no wallet.
// .env: APEX_KEY=apx_... (one-time, by card: apexfaucet.xyz/pass)
const r = await fetch('https://apexfaucet.xyz/api/x402/arc-send-guard?from=' + from + '&to=' + to,
{ headers: { Authorization: 'Bearer ' + process.env.APEX_KEY } })
const { data } = await r.json()
if (data.verdict === 'stop') throw new Error(data.reasons[0].message)
Get a key: $5 of credit by card. Each call takes its own price from it: 5,000 price checks, or 1,666 history calls, or any mix. Or the package: npm install apex-arc (GitHub).
The five calls
| Call | What it answers | Price |
|---|---|---|
arc-send-guard | Before a send: stop / check / ok. Address-poisoning lookalikes, forged-transfer bait, token contracts, OFAC and USDC blacklist, fake USDC. | $0.001 |
arc-price | USD price from the deepest Uniswap v4 USDC pool, the 24 h change, liquidity warnings. | $0.001 |
arc-wallet | What an address holds, in USD per token. | $0.002 |
arc-transfers | The last 50 transfers, USD then and now, net flow per token, poisoning flags. | $0.003 |
arc-token-info | What a token is: supply, Circle's or not, who launched it, pools, risk signals. | $0.002 |
All on https://apexfaucet.xyz/api/x402/<call>. A malformed input or a read that fails is refused before anything is charged; a call we fail to answer gives the charge back to your key.
What comes back
Every answer is { ok, paid, data }; the fields below are in data. A failed read is an error, never a made-up value.
arc-send-guard verdict, reasons[{ level, key, message }] (most severe first), destination{ isContract, isToken,
transactionsSent, usdcBalance, knownCounterparty }, from, to, token
arc-price usdPrice, change24h{ pct, usdPriceThen, hours, fromBlock, fromTime }, symbol, decimals,
pool{ id, fee, tickSpacing, hooks }, liquidityUsdEstimate, warnings[], block, blockTime
arc-wallet totalUsd, usdc{ balance }, tokens[{ token, symbol, balance, usdPrice, usdValue, warnings }], unpriced
arc-transfers netFlow[{ symbol, in, out, net, usdNetThen, direction }], transfers[{ txHash, time, direction,
symbol, amount, usdThen, usdNow, from, to, flags?, warnings? }], next{ before }
arc-token-info name, symbol, riskSignals[], isVerifiedUsdc, isVerifiedEurc, creator{ address, launchTime,
otherLaunches30d } or null, usdcPools, deepestPool{ usdPrice, liquidityUsdEstimate }, totalSupply
Why the send guard comes first
On 9 Oct 2026 a fake "USDC" contract wrote 64 invented transfers in one Arc transaction, pairing real wallets with lookalikes that share the first 6 and last 5 characters. Nothing moved; the trap is the next payment, when someone copies the lookalike from their history. arc-send-guard returns stop for it. The full story, fixtures and reason keys.
Agents: pay per call
No key needed: every call answers a standard x402 402 and takes USDC on Arc, Base or Solana. createApexArc({ payer }) in the package, or any x402 client. MCP tools too (arc_send_guard, arc_price, …).