LEV7 documentation

Agent API

Pay-per-request read API for agents, over x402. No account, no API key.

LEV7 exposes a small set of read endpoints that an autonomous client can call and pay for per request, using x402. There is no account to create and no API key to manage: the payment is the credential.

This tier is read only. See What this tier cannot do.

How paying works

x402 activates the HTTP 402 Payment Required status. The exchange is:

  1. Your agent requests a resource.
  2. The server answers 402 with a payment-required header describing what it accepts — amount, asset, chain, and the address to pay.
  3. Your agent retries with a signed payment payload.
  4. The server verifies and settles through a facilitator, then returns the resource.

No state is kept between steps, so a request either carries payment or gets a 402. There is no session to expire.

The 402 you will get

Decoding the payment-required header of an unpaid request looks like this:

{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "url": "https://lev7.finance/api/agent/points/stats",
    "description": "LEV7 points pipeline aggregates: epochs, points, holders"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "50000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x…",
      "maxTimeoutSeconds": 300,
      "extra": { "name": "USDC", "version": "2" }
    }
  ]
}

amount is in the asset's base units — 50000 is $0.05 of 6-decimal USDC.

Calling it

@x402/fetch wraps the native fetch and handles the retry for you:

import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const pay = wrapFetchWithPayment(fetch, account);

const res = await pay("https://lev7.finance/api/agent/points/stats");
const stats = await res.json();

Without a payment-aware client you get the 402 and can implement the handshake yourself against @x402/core.

Endpoints

All are GET, and all return the same shapes as the site's own API.

endpointpricereturns
/api/agent/points/stats$0.05Published epochs, epochs paid, total and referral points, holders
/api/agent/points/wallet/{address}$0.05One wallet's points, rank, and epoch breakdown
/api/agent/validation/{address}$0.05Validated vs unvalidated LEV7 for one wallet
/api/agent/governance/tally$0.05The latest published governance tally
/api/agent/swap/quote$0.05Indicative route and price for a buy or sell

swap/quote takes the same query parameters as the free route.

You are not charged for failures

Settlement happens only after the endpoint returns successfully. If a read fails — an unreadable database, an address that does not parse — you get the error and keep your money.

These reads are also free

Every figure here is public and unauthenticated on the site's own API. What this tier sells is machine access: a stable, priced, documented surface with the 402 handshake, rather than scraping pages. If you are building something where the free endpoints work, use them.

Over MCP

The same five reads are also an MCP server, for an agent that would rather list tools than read an OpenAPI description:

POST https://lev7.finance/api/agent/mcp

Streamable HTTP transport, stateless, JSON responses — every request is self-contained, there is no session to open. The tools are named by the operationId of the free route each one twins, so the parameters and error codes documented in /openapi.json apply unchanged:

toolpricetwin
getPointsStats$0.05/api/agent/points/stats
getWalletPoints$0.05/api/agent/points/wallet/{address}
getValidatedBalances$0.05/api/agent/validation/{address}
getGovernanceTally$0.05/api/agent/governance/tally
getSwapQuote$0.05/api/agent/swap/quote

Payment rides in the tool call's _meta rather than a header, as @x402/mcp defines it. A call without payment returns an error result whose structuredContent is the same payment-requirements object the HTTP 402 carries — accepts, payTo, the asset and its EIP-712 domain. Retry with the signed payment in _meta["x402/payment"]; the settlement receipt comes back in the result's _meta["x402/payment-response"].

@x402/mcp does that round trip for you:

import { createx402MCPClient } from "@x402/mcp";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const client = createx402MCPClient({
  name: "my-agent",
  version: "1.0.0",
  schemes: [{ network: "eip155:84532", client: new ExactEvmScheme(account) }],
  autoPayment: true,
});

await client.connect(
  new StreamableHTTPClientTransport(new URL("https://lev7.finance/api/agent/mcp")),
);
const result = await client.callTool("getWalletPoints", { address: "0x…" });
console.log(result.structuredContent);

Two properties carry over from the HTTP tier exactly. A call that fails is not charged: the tool returns the free route's own error envelope as an error result, and an error result is never settled. And the schema is checked before payment: an argument the tool's input schema rejects is refused without a payment request, so a malformed address costs nothing to discover. initialize and tools/list are free.

What this tier cannot do

It cannot buy, stake, or vote.

Those actions require accepting the Terms and Risk Disclosures, bound to the wallet that signs the transaction, and today that acceptance is a browser flow a human completes. Whether an autonomous agent can accept on its own behalf — or whether a human principal accepts and authorises an agent wallet — is an open legal question, not a technical one. Until it is settled, the endpoints that move money or record a vote are not part of this tier.

Voting has a further requirement even for humans: it runs through staking, and staking is gated on an eligibility certificate issued per wallet. See Governance.

Network and settlement

accepts is a list, and you pick. A 402 can offer more than one chain, and you settle on whichever you can pay:

"accepts": [
  { "network": "eip155:8453", "asset": "0x833589…2913", "extra": { "name": "USD Coin",     "version": "2" } },
  { "network": "eip155:4663", "asset": "0x5fc536…d168", "extra": { "name": "Global Dollar", "version": "1" } }
]

Read the network and asset from the header rather than assuming one — which chains are offered is deployment configuration and can change. A chain whose facilitator is unreachable is simply left out of the list rather than failing the request, so treat a shorter list as normal.

extra carries the EIP-712 domain you sign the transferWithAuthorization under. Use it as given — for Global Dollar on Robinhood the domain name is Global Dollar, not the USDG ticker, and signing under the wrong name produces an authorization the token rejects.

Rate limits

The underlying rate limits still apply per endpoint. Paying does not raise them. If you need a higher limit, get in touch before building against one.

On this page