x402-native, pay-per-call. Two HTTP tools an agent pays for inline — no accounts, no keys held. Quotes on Base, Polygon & Arbitrum — pay in USDC from any of them or Solana.
x402-nativemultichaindecision-grade
the gap
A wallet guard like Blockaid tells an agent whether a transaction is malicious — can I sign this? It can't tell the agent should I trade this? — what price actually fills under size, and whether the token is an economic trap. Plexa answers the economic question.
two endpoints, one engine
POST /v1/quote$0.02
Executable liquidity under a given size: real fill price (not mid/spot), price impact (bps), realizable depth, per-leg route, worst-case slippage, confidence. Priced from canonical on-chain quoters, on Base, Polygon & Arbitrum.
POST /v1/pretrade/check$0.05
avoid — only when a trap is proven at that block: nowhere to sell, less than 5% of your size sitting in the pool as the counter asset, or trading switched off by the contract itself. Otherwise clear — no proven traps, which is not “safe”. Plus risk_profile: age, concentration, depth, the amount a sale would be paid from — as numbers; the call is yours. Analysis runs on Base today; you can pay from any of the four rails. Same endpoint, same price, also at /v1/token-safety and /v1/rug-check.
The first call from a new wallet is free — the full response, every field, same engine as a paid one. One free call per wallet, on either endpoint; nothing is settled on-chain for it.
A real capture, trimmed to the fields explained here — nothing invented. executablePrice is how much token 1 USDC buys at the requested size: the real fill, not a mid. validUntil says until when asking again returns this same answer; coverage says how many of the five axes reported. liquidityCoverage is the exit check showing its work: conclusive: true means it reached a verdict-grade conclusion; 45 pools were found across 13 factories with none left unread. In Uniswap v4, 10 pools of this pair were seen and the sale was simulated in each — 1 accepted it, 8 refused (a refusal is a measurement about that pool, not a gap in our data), 7 run a hook inside the swap, and singletonScanTruncated admits the scan hit its work cap. The two block numbers are the start and end of those reads: one apart here, so no single block describes the answer exactly, and that gap is the uncertainty. In concentration, ageSec: 140 with stale: false means the holder numbers were measured 140 seconds earlier and served from cache. Absent numbers come back null with a reason, never as 0. Trimmed away here but present in every response: reasons (why this verdict, in plain language), flags (the five raw signals behind the axes), ts (when we computed it, epoch ms) and disclaimer.
what else comes back
// live capture, WETH, 2026-08-20 14:46:29Z, Base block 50223921 — the six context blocks, verbatim; the notes each block carries are long and are cut here{"identity": {"name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, "totalSupply": 239296.58651918 },
"valuation": {"fdvExecutableUsd": 543916397.6557496, "basis": "totalSupply(this chain) x executablePrice(at sizeUSD)" },
"ownership": {"ownerAddress": null, "ownerRenounced": null, "isMintable": false, "creatorSharePct": 1.2e-07 },
"dormancy": {"topHolderIdleDays": null, "lastTopHolderMoveBlock": null },
"market": {"priceUsdSpot": 2277.76, "volume24hUsd": 551324354.8699999, "marketCapUsd": 542587444, "holderCount": 5223863 },
"sources": {"*": "measured",
"risk_profile.concentration": "unavailable:holder-axis-produced-nothing",
"flags.F_CONC": "unavailable:holder-axis-produced-nothing",
"valuation": "derived:identity.totalSupply*quote.executablePrice",
"dormancy": "unavailable:holder-axis-produced-no-block",
"ownership.creatorAddress": "derived:sender-of-first-transfer",
"ownership.isMintable": "derived:mint-selector-in-bytecode",
"market": "vendor:dexscreener+goplus",
"market.priceUsdSpot": "vendor:dexscreener",
"market.volume24hUsd": "vendor:dexscreener",
"market.marketCapUsd": "vendor:dexscreener",
"market.holderCount": "vendor:goplus"
}}
A second live capture, not the first one edited — the token above was measured on 10.08, before these blocks existed, and re-taking it today would have cost the fifth axis. Both are real; neither is patched. valuation.fdvExecutableUsd is fully-diluted value at the price your size executes at — deliberately a different number from market.marketCapUsd, which is the vendor's global figure: for a bridged token ours is legitimately smaller, and the gap is bridged supply plus the spot-vs-executable spread. ownerRenounced: null means no owner() answered — unknown is not renounced. dormancy is null here and says why: it rests on the holder axis, and that axis produced no block for this token. And sources is the part no market-data endpoint ships: every field signed with who produced it — derived, measured, unavailable, vendor. unavailable:<reason> names the hole instead of hiding it, which is how «we could not check» stays distinguishable from «we checked and it is fine».
connect & configure
As an MCP tool
Add the Plexa MCP server to any agent (Claude Code / Claude Desktop / any MCP host). It exposes plexa_quote and plexa_pretrade_check. Payment is handled automatically via x402 from a wallet you configure — Plexa never sees the key.
As an agent skill
An Agent Skill, pretrade-exit-check, teaches an agent when the pre-trade check is worth its $0.05 and how to read the answer — the verdict vocabulary, what liquidityCoverage proves, and which fields are allowed to be null. Install: npx skills add plexa-xyz/skills.
Direct HTTP (x402)
Any x402 client works (e.g. @x402/fetch). Call the endpoint; on 402 the client signs a USDC payment (EIP-3009) and retries — the response is served only after on-chain settle. Pass chain: base / polygon / arbitrum.
Use a dedicated, low-balance wallet. This key signs payments; it is not an API key. Keep it in your environment and let the host expand ${AGENT_WALLET_KEY} — if your MCP host does not support expansion, put the literal value in a file with restrictive permissions and never commit it. Plexa never sees the key: it stays in your client.
Live on npm: @getplexa/mcp — run with npx -y @getplexa/mcp. The public API is live at api.getplexa.com.
for agents
Everything below is machine-readable and free — no payment, no key. Start at
llms.txt: it carries the endpoints,
the payment handshake and the full response envelope, so an agent knows what it gets
before it pays.
// machine entry points — all on the API host, all GET, all free
GET https://api.getplexa.com/llms.txt // text/plain — the manifest
GET https://api.getplexa.com/openapi.json // OpenAPI 3.1, both endpoints + the 402 flow
GET https://api.getplexa.com/.well-known/x402 // x402 service discovery pointer
GET https://api.getplexa.com/contact // who runs this, how to reach them// the paid endpoints themselves — POST only; an unpaid POST answers 402 with the terms
POST https://api.getplexa.com/v1/quote // $0.02
POST https://api.getplexa.com/v1/pretrade/check // $0.05 (also /v1/token-safety, /v1/rug-check)
The docs live on api.getplexa.com, not on this domain —
this one serves the page you are reading. A GET on a paid path answers
405 with instructions rather than a bare error, and an unpaid
POST answers 402 with the payment terms in the
PAYMENT-REQUIRED header — both are legitimate first moves for an agent
that has never seen this API.
open-source reference agent
See Plexa in action
A complete, MIT-licensed reference agent — a dust consolidator that discovers small token balances, checks each through Plexa, and swaps the safe ones. Client-only: it uses nothing but the public API, so it doubles as a working integration pattern you can fork.