Skip to main content
Beta. This API is in beta while we onboard the first external customers. The shape of the request/response bodies is stable, but we may add optional fields. Non-breaking changes only. Email josh@polynode.dev if you’re building something and want direct support.

What this is

An HTTP + webhook service that does the hard parts of copy trading for you:
  • You register your followers’ wallets and the leaders they want to copy.
  • We watch the Polymarket V2 CLOB for leader fills.
  • The instant a leader fills, we size + price a matching order for each follower, build the unsigned V2 CLOB order and EIP-712 typed data, and POST it to your webhook URL.
  • Your backend has your user sign the order (via Privy, MetaMask, whatever you use for signing) and submit it to Polymarket.
  • Optional: you can turn on a per-trade platform fee that gets pulled into our on-chain FeeEscrow and shared with affiliates.
You never run a polynode node, never subscribe to a WebSocket, never decode a fill on-chain. You just handle signing and UI.

Who this is for

You’re the right fit if:
  • You’re building a Polymarket-facing trading product (terminal, wallet, copy-trading UI, mobile app).
  • Your users already exist and you already hold or sign for their Polymarket wallets — Safe proxies or deposit wallets (typically via Privy embedded wallets).
  • You want to ship copy trading in days, not months, and you don’t want to maintain the settlement-detection / order-building stack.
If you’re a single retail trader looking to copy a whale, this API is not for you — use one of the consumer products built on top of it.

How it maps to Polymarket

Copy trading on Polymarket V2 is the same order flow as any other trade: your user’s wallet (Safe proxy or deposit wallet) is the maker of a V2 CLOB Order, signed with EIP-712, submitted to clob-v2.polymarket.com/order. The only thing we do is generate the order body and typed data on the exact same block a leader fills, so the order’s timestamp + builder fields are correct and sizing/pricing matches the leader. For deposit wallet users (sig_type: 3), the typed data uses the TypedDataSign wrapper automatically. Your signing code should use signV2Order() from the polynode SDK, which handles both Safe and deposit wallet signatures transparently. If you’re new to V2, read V2 Order Details first — this guide assumes you already know what an Order struct looks like.

Base URL

All endpoints are HTTPS. Every request must carry your polynode API key.

Authentication

Include your polynode API key as a Bearer token on every request:
The SHA-256 of your bearer is your tenant ID — a 64-char hex string that scopes everything you create. Two different keys = two different tenants. Data is fully isolated at the SQL level: you cannot read or modify anything registered under another tenant’s key.
  • Free-tier keys are rejected with 402 Payment Required. You need a paid key (Starter tier or above).
  • Rate limits follow your paid tier’s limits. The standard x-ratelimit-{limit,remaining,reset} response headers are always returned.

Quick start (5 minutes)

From now on, every time 0xLeaderWalletAddress... fills an order on V2 CLOB, your webhook endpoint receives a signed POST with an unsigned V2 order ready for your user to sign.

Concepts

REST endpoints

All paths below are under https://api.polynode.dev/copytrade.

Config — the tenant-level settings

Followers — your end users

Leaders — who each follower copies

Deliveries — observability

Status

Follower settings

The settings JSON on a follower controls how we size, price, and filter copies.
size_mode:
  • percentage — size the copy at size_pct% of the leader’s order size.
  • fixed_pusd — always copy at size_pusd pUSD regardless of leader size.
  • match_leader — exactly match the leader’s size (subject to follower collateral).
slippage_bps: the copy’s price is set at the leader’s fill price ± your slippage tolerance. Lower slippage = more protection but more skipped copies when the book moves.

Webhook contract

Whenever your tenant has a copy to execute, we POST to your webhook_url.

Headers

Always verify X-PolyNode-Signature before processing. During a secret rotation, your code must accept HMACs computed with either your current or your previous secret for up to 1 hour. Example verification (Node.js):
Python:

Body

What your backend does with this

  1. Verify the HMAC. If it doesn’t match, drop the event and 200 OK (don’t leak that verification failed).
  2. Look up the follower in your system by follower_payload.follower_wallet.
  3. Ask the user to sign v2_typed_data. This is standard EIP-712 via Privy / ethers / viem / your wallet of choice. The user’s signer EOA signs.
  4. Submit to Polymarket. If fee_auth is absent, POST to clob-v2.polymarket.com/order. If fee_auth is present, also have the user sign the fee_auth.typed_data, then POST the bundled signed payload to submit_url.
  5. Return 2xx within 5 seconds. We mark the delivery successful. If we don’t see 2xx in that window, we retry.

Delivery semantics

  • Up to 5 attempts with backoff 1s / 5s / 15s / 30s / 60s.
  • 2xx within 5s → success, dropped from the retry queue.
  • After 5 failures → the event goes to your DLQ (GET /deliveries/failed). You can fix your endpoint and POST /deliveries/{event_id}/replay.
  • The same event_id is used on every retry — dedupe on it.
  • sequence_number is monotonic per follower — buffer and process in order. Gaps mean you missed a delivery.

Fee escrow (optional)

This is your platform’s fee, not Polymarket’s. Polymarket may also charge its own protocol fee or builder rev share — those are separate and always take effect regardless of this setting. Read Fee Escrow for the full explanation.
If you want to monetize with a per-trade fee — optionally split with affiliates — enable fee escrow:
When a fee would be charged for an event, the webhook gets an extra block:
Matrix: When fee_auth is present, your user signs two typed-data objects (the V2 order AND the fee auth), you bundle them, and POST to submit_url. The cosigner pulls the fee into escrow, forwards the signed order to Polymarket, and on fill/cancel handles the split or refund automatically.

Errors

Standard HTTP status codes apply. Common ones:

Non-goals / what we don’t do

  • We don’t custody anything. We never hold your users’ keys, funds, or signed orders. Every signature happens on your side.
  • We don’t submit orders for you (unless fee escrow is on, in which case we cosign + submit via our cosigner — still, we never see the user’s signer key).
  • We don’t guarantee fills. We generate an order with a sensible price + size; whether it fills depends on the V2 CLOB book. If the book moves past your slippage_bps, the order won’t fill; that’s intended.
  • No V1 support. This API is V2-only, aligned with Polymarket’s 2026-04-28 V2 launch.

Roadmap

  • max_trades_per_hour enforcement (currently accepted as config, not yet enforced)
  • systemd + graceful shutdown (currently a dev process, small retry loss possible on restart)
  • Additional webhook event types (pending cancellations, resync notifications)
  • Self-serve dashboard for inspecting followers / leaders / deliveries

Questions

Email josh@polynode.dev or book a slot at cal.com/bosh-jerns-vozdcd/15min. We’re actively supporting beta integrations.