Build on x402Pulse

Skill-ranked Polymarket data your agent or app can buy one call at a time. No API key, no account: just HTTP and a wallet with a little USDC.

Quick start

Every paid endpoint works the same way:

  1. Call it. Without a payment you get 402 Payment Required and the price. This is free.
  2. Pay. Your x402 client signs a USDC payment for that exact amount. Signing costs no gas.
  3. Get the data. The client repeats the call with the signature and receives JSON.

Check a price right now, for free:

curl -i "https://www.x402pulse.dev/v1/top-traders?period=month"

Payments are in USDC on Base (eip155:8453). You only pay for successful responses: any error is never charged.

How it works

What happens, step by step, every time your agent calls x402Pulse.

  1. Checks

    Your request arrives. Bad parameters get a free 400, and more than 60 calls a minute gets a free 429. You're never asked to pay for a request that can't succeed.

  2. Price

    With no payment attached, x402Pulse answers 402 Payment Required. The PAYMENT-REQUIRED header says how much, in which token, on which network, and to which address.

  3. Verify

    Your client signs a USDC authorization and resends the request. x402Pulse asks its facilitator (Coinbase) to confirm the signature, amount and network are valid. No money moves yet.

  4. Answer

    x402Pulse builds the answer from Polymarket's public APIs (trades, leaderboards, positions, holders, markets), scores the wallets involved, and reuses recent results from its cache.

  5. Settle

    Only if the answer succeeded, the facilitator settles the payment on the blockchain: USDC moves from your wallet to x402Pulse. If anything failed, it never settles.

  6. Receive

    You get JSON with the data, plus a PAYMENT-RESPONSE header containing the receipt and transaction hash.

What you need

Any program that can make HTTP requests, an x402 client library (or your own code), and a wallet with a little USDC on Base.

What you don't need

No API key, no account, no subscription, no sign-up, and no ETH for gas. The facilitator pays the network fee.

Your first paid call

From an empty folder to a paid answer in about ten minutes. Follow the steps in order and copy the commands exactly.

  1. Check Node.js

    You need Node.js 20 or newer. Run this; it should print v20 or higher. If not, install it from nodejs.org.

    node -v
  2. Create a project

    mkdir my-pulse-agent && cd my-pulse-agent
    npm init -y
    npm pkg set type=module
    npm install @x402/fetch @x402/evm viem
  3. Create a test wallet

    This makes a brand-new wallet just for your agent and prints its private key and address.

    node -e "import('viem/accounts').then(({generatePrivateKey,privateKeyToAccount})=>{const k=generatePrivateKey();console.log('private key:',k);console.log('address:    ',privateKeyToAccount(k).address)})"

    Save the private key somewhere safe and never share it or paste it into chats, screenshots or GitHub. Anyone with it can spend the wallet's money. Use this wallet only for your agent, with small amounts.

  4. Add a little USDC

    Send a few dollars of USDC on Base to the address from step 3. Check the network says Base before sending. You don't need any ETH.

  5. Create the agent

    Create a file named agent.mjs in the folder, paste this in, and save it.

    import { x402Client, wrapFetchWithPayment, x402HTTPClient } from "@x402/fetch";
    import { registerExactEvmScheme } from "@x402/evm/exact/client";
    import { privateKeyToAccount } from "viem/accounts";
    
    const API = "https://www.x402pulse.dev";
    const MAX_PRICE = 0.5; // never pay more than $0.50 for one call
    
    // 1. Load the wallet from the AGENT_KEY setting (never write the key in this file).
    const account = privateKeyToAccount(process.env.AGENT_KEY);
    const client = new x402Client();
    registerExactEvmScheme(client, { signer: account });
    
    // 2. A guardrail: see each price and refuse anything above MAX_PRICE.
    client.onBeforePaymentCreation(async ({ selectedRequirements }) => {
      const price = Number(selectedRequirements.amount) / 1e6;
      console.log("Price:", price, "USDC");
      if (price > MAX_PRICE) return { abort: true, reason: "Too expensive" };
    });
    
    // 3. A fetch that pays automatically when it receives a 402.
    const pay = wrapFetchWithPayment(fetch, client);
    
    // 4. Ask who the most skilled traders are this month.
    const res = await pay(API + "/v1/top-traders?period=month&limit=5");
    console.log("Status:", res.status);
    const body = await res.json();
    
    if (res.ok) {
      for (const t of body.data.traders) {
        console.log(`#${t.rank} ${t.name ?? t.wallet}  skill ${t.skill} (${t.label})  edge ${Math.round(t.edge * 100)} pts`);
      }
      const receipt = new x402HTTPClient(client).getPaymentSettleResponse((h) => res.headers.get(h));
      console.log("Paid. Transaction:", receipt?.transaction);
    } else if (res.status === 402) {
      console.log("Not charged: the payment wasn't accepted. Check the wallet has USDC on the network shown in the 402 response.");
    } else {
      console.log("Not charged. Error:", body.error);
    }
  6. Run it

    Replace the key with your private key from step 3. Putting it in front of the command keeps it out of your files.

    AGENT_KEY=0xYOUR_PRIVATE_KEY node agent.mjs
  7. Read the result

    You should see something like this. The first run can take up to 30 seconds while wallets are scored.

    Price: 0.05 USDC
    Status: 200
    #1 primm  skill 88 (Sharp)  edge 13 pts
    #2 Kch-Temp  skill 76 (Sharp)  edge 6 pts
    …
    Paid. Transaction: 0x31a8…9169

    That's a real payment: search the transaction on basescan.org to see it. Now swap the URL for any other endpoint below. If something goes wrong, see Troubleshooting.

Endpoints

All endpoints are GET, return JSON shaped as { data, cached }, and live under https://www.x402pulse.dev.

EndpointParametersReturnsPrice
/v1/whales
min
Minimum trade size in USD (default 1000)
limit
Number of trades, 1 to 50 (default 20)
Recent large Polymarket trades, with 5- and 15-minute markets filtered out.$0.02
/v1/wallet
address
Polymarket wallet address (0x…)
A wallet's track record: skill score, edge over the odds paid, win rate, return, specialty and largest open positions.$0.05
/v1/top-traders
period
day, week, month or all (default month)
category
Optional: sports, politics, crypto, economy or other
limit
Number of traders, 1 to 25 (default 10)
Top Polymarket traders re-ranked by skill (edge over the odds paid, return, consistency), not just total profit. Optionally within one category.$0.05
/v1/smart-money
market
Market link, market slug or condition ID
Which way skilled traders lean in a Polymarket market compared with its odds: the biggest holders, each scored for skill.$0.20
/v1/skilled-whales
min
Minimum trade size in USD (default 1000)
limit
Number of trades, 1 to 50 (default 20)
Recent large Polymarket trades by Solid or Sharp traders only, each tagged with the trader's skill score.$0.05
/v1/disagreements
category
Optional: sports, politics, crypto, economy or other
limit
Number of markets, 1 to 20 (default 5)
Busy open Polymarket markets where skilled traders' money disagrees most with the market's odds, with a confidence rating.$0.35

market accepts a full polymarket.com link, a market slug, or a condition ID. If a link covers an event with several markets, you get a free 400 with choices[] to pick from.

Response fields

What every number means, so your agent can explain its answers.

/v1/whales

FieldTypeMeaning
trades[]listLargest recent trades, biggest first.
wallet, nametextTrader's Polymarket wallet and display name (null if none).
side, outcome, pricetext, text, 0–1BUY or SELL, which outcome, and the price paid (0.62 = 62¢).
usd, sharesUSD, numberTrade size in dollars and shares.
market, slug, time, txtextMarket question, its slug, trade time (ISO) and on-chain transaction.

/v1/wallet

FieldTypeMeaning
address, nametextThe wallet and its display name (null if none).
scoreobjectThe scorecard. See score fields below.
openPositions[]listLargest live positions: market, outcome, shares, avgPrice, currentPrice, valueUsd, unrealizedPnlUsd.

/v1/top-traders

FieldTypeMeaning
traders[]listTraders ranked by skill. Each has the main score fields plus the ones below.
profitRankintegerWhere they sat on Polymarket's profit leaderboard for the period.
periodPnlUsd, periodVolumeUsdUSDProfit and volume for the chosen period, from Polymarket.
candidatesintegerHow many leaderboard traders were scored to build the ranking.
categorytext or nullWhen set, scores use only each trader's bets in that category.

/v1/smart-money

FieldTypeMeaning
question, slug, outcomes[]text, listThe market, and each outcome with its current price (0.41 = 41% implied chance).
leanobject or nulloutcome, share of skill-weighted money, marketPrice, vsMarket (share − price) and stance: in line with, more confident than, or less confident than the market.
summarytextOne-sentence answer, ready to show a user.
sides[]listPer outcome: price, sharpHolders, skillWeightedUsd and holders[] (wallet, name, valueUsd, skill, label, edge, winRate, roi).

/v1/skilled-whales

FieldTypeMeaning
trades[]listLarge recent trades by Solid or Sharp traders only, biggest first. Same trade fields as /v1/whales.
skill, label, edge, roi, specialtyscoreThe trader's skill score and its main parts. See score fields below.
tradersScoredintegerHow many distinct traders were scored (up to 25 of the biggest).

/v1/disagreements

FieldTypeMeaning
markets[]listOpen yes/no markets, sorted by how far tempered skilled money is from the price, weighted by confidence.
priceYes0–1The market's price for the first outcome (usually Yes).
skilledYesShare0–1What skilled money implies for the first outcome, tempered toward the price so thin readings can't look extreme.
rawSkilledYesShare0–1The untempered share of skill-weighted money on the first outcome.
gap−1 to 1skilledYesShare − priceYes. Positive: skilled money more bullish on Yes than the market; negative: more bullish on No.
confidencetexthigh (5+ skilled holders, $150K+ skill-weighted), medium (3+, $50K+) or low.
skilledHolders, skilledUsdinteger, USDHow many Solid+ holders and how much skill-weighted money the reading rests on.
scannedAt, marketsScannedtime, integerWhen the busiest open markets were last scanned (every 15 minutes) and how many.

Score fields

Used in wallet scorecards, top traders and smart-money holders.

FieldTypeMeaning
skill0–100Overall skill score from edge, return, history size and consistency.
labeltextSharp (70+), Solid (45+), Mixed (25+), Weak, or Too few bets (under 10 finished bets).
edgenumberWin rate minus the win rate the prices paid implied. 0.08 = won 8 points more often than the odds said.
winRate0–1Share of finished bets that made money.
expectedWinRate0–1Average price paid, i.e. the win rate the odds implied.
roinumberRealized profit divided by money invested. 0.25 = +25%.
betsintegerFinished bets scored (latest 200, losses included).
realizedPnlUsdUSDProfit or loss across the scored bets.
biggestWinShare0–1Share of all winnings from the single best bet. High means one lucky hit.
shortTermShare0–1Share of bets on 5- and 15-minute crypto markets, which lowers the score.
specialtytextCategory with the most profit: sports, politics, crypto, economy, other, or null.

How scores are calculated

Total profit mostly rewards whoever bets the most. The skill score asks a different question: did this trader beat the odds they paid?

  1. Which bets count. A wallet's latest 200 finished bets, wins and losses. Losing bets that were never redeemed are included, so records aren't flattered.
  2. Edge. Win rate minus the average price paid. Buying at 50¢ implies a 50% chance; winning 65% of those bets is a +15 point edge. Buying at 96¢ and winning 96% is zero edge.
  3. Return. Realized profit divided by money invested.
  4. Base score. 60% from edge (−2 points scores 0, +10 points or more scores full marks) and 40% from return (0% scores 0, +30% or more scores full marks).
  5. Adjustments. Multiplied by history size (about 100 bets earns full credit), by consistency (halved if one bet made all the winnings), and by focus (halved for wallets that only play 5- and 15-minute coin-flip markets).
  6. Safety cap. No edge or no profit caps the score at 35, however high the win rate.

Labels: Sharp 70+, Solid 45+, Mixed 25+, Weak below 25, and Too few bets under 10 finished bets.

Smart money

For each outcome, x402Pulse takes the biggest holders (10 per side when paid, 3 in free samples) and scores each one. Only Solid or better holders count as skilled. Each skilled position is weighted by its dollar value times its skill score, and the outcome with the most skill-weighted money is the lean. The lean's share is then compared with that outcome's price: within 10 points is "in line with" the market, above is "more confident than," below is "less confident than."

In your own app

The same pattern in TypeScript. One wrapped fetch handles the whole exchange, and a spending cap means your agent can never overpay.

npm install @x402/fetch @x402/evm viem
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const client = new x402Client();
registerExactEvmScheme(client, {
  signer: privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`),
});

// Spending guardrail: refuse any single payment above $0.50.
client.onBeforePaymentCreation(async ({ selectedRequirements }) => {
  if (Number(selectedRequirements.amount) / 1e6 > 0.5) {
    return { abort: true, reason: "Over my per-call limit" };
  }
});

const pay = wrapFetchWithPayment(fetch, client);

// Which way does skilled money lean on this market?
const market = "https://polymarket.com/event/…";
const res = await pay(
  "https://www.x402pulse.dev/v1/smart-money?market=" + encodeURIComponent(market),
);
const { data } = await res.json();
console.log(data.summary);
// e.g. "Skilled holders lean Yes (72% of skill-weighted money, from 4 skilled
//       holders), more confident than the market's 41%."

Any language

x402 is plain HTTP, so any language works. Libraries exist for several, and the protocol is short enough to implement yourself:

  1. Send the request. A 402 response carries a PAYMENT-REQUIRED header: base64-encoded JSON listing the accepted payment (scheme, network, amount in USDC base units, asset, payTo).
  2. Sign the payment as the exact scheme describes (an EIP-3009 USDC transfer authorization on Base).
  3. Repeat the request with the signed payment, base64-encoded, in a PAYMENT-SIGNATURE header.
  4. On success you get 200 plus a PAYMENT-RESPONSE header with the settlement receipt and transaction hash.

The full specification is at docs.x402.org.

Testing for free

This service runs on Base mainnet with real USDC. Keep a small budget and a per-call cap in your client while you build.

Or try it by hand first: the Try page gives free samples in your browser.

Discovery

Agents can find and understand x402Pulse without reading this page:

  • /catalog and /.well-known/x402-listing: every endpoint, price and parameter as JSON.
  • /llms.txt: this documentation as plain text, written for AI models to read.
  • Every 402 response includes a bazaar section with an example input, input schema and example output, which x402 directories such as the Coinbase Bazaar use for search.

Errors and limits

Every error is free: payment only settles when the response succeeds.

StatusCostMeaning
400freeMissing or invalid parameter. An ambiguous market link includes choices[] to pick from.
402freePayment required: read the PAYMENT-REQUIRED header, pay, and retry.
404freeWallet or market not found.
429freeToo many requests from you (60 per minute by default).
502 / 503freePolymarket didn't respond or is busy. Retry after a short wait.

How fresh is the data?

Troubleshooting

The problems people actually run into, and the fix for each.

What you seeCauseFix
Status 402 after payingWalletThe wallet has no USDC on the right network. Check its USDC balance on the network shown in the 402 response (Base Sepolia while testing) and top it up.
fetch failed / ECONNREFUSEDAddressThe URL is wrong or the service is unreachable. Copy the address from this page exactly, including https://.
invalid private keyKeyA private key starts with 0x followed by 64 characters, 66 in total, with no spaces or quotes inside.
Over my per-call limitYour capYour own spending guardrail refused the price. Raise the cap in your code if you meant to pay it.
400 with choices[]FreeYour market link covers several markets. Call again with one of the slugs in choices[].
404 market not foundFreeCheck the link or slug for typos. Open it on polymarket.com to confirm it exists.
429 rate limitFreeMore than 60 calls a minute. Slow down, or reuse answers: most data refreshes every few minutes anyway.
Slow first answerNormalTop traders and smart money score many wallets the first time (up to ~30 seconds). Later calls come from the cache in milliseconds.

What to build

A few ideas for products and agents on top of x402Pulse.

Research assistants

Before answering "will X happen?", check whether skilled money agrees with the market's odds and say so.

Market dashboards

Show each market's odds next to its skilled lean, and highlight where they disagree.

Chat and Discord bots

Answer "is this wallet any good?" or "who's sharp this week?" in a group chat, paying a few cents per question.

Whale watchers

Poll /v1/whales and enrich each big trade with the trader's skill score from /v1/wallet.

News and newsletters

Turn weekly top traders and notable smart-money leans into a digest for readers.

Research and backtests

Track how skilled-money leans compare with how markets actually resolve.

Using the data

x402Pulse provides data and analytics built from public Polymarket activity. It is not financial or betting advice, and past performance doesn't predict future results. If you show x402Pulse data to people, say where it comes from and present it as information, not recommendations.

Wallets are identified by address and their public Polymarket display names only. Don't use the data to identify or contact the real people behind wallets.

x402Pulse is an independent service, not affiliated with Polymarket or the x402 Foundation. The API is versioned under /v1; breaking changes would ship as /v2. Network: eip155:8453.