Skip to content

Reference

API reference

The Mirror backend API (engine and relayer) used by the app and the stats page.

On this page

The app and the public stats page talk only to this API and to Monad RPC, never to Perpl's API directly, so everything works from the US and the UK (Perpl's own API geo-blocks both). The engine runs in an EU region.

The API is being built. Paths and fields below are the contract the app is written against; the base URL is published here once it is live.

Base URL: API_BASE (to be announced). All amounts are strings in raw units unless the field name ends in Usd or Display. Addresses are checksummed. Team-run accounts (demo leader, demo follower) are flagged teamRun: true everywhere and are excluded from every user and traction count.

Read

Method Path Returns
GET /v1/health {ok, chainId, block, keeper:{address, balanceWei}, relayer:{…}, perpl:{wsConnected, lastMarkAt}, indexer:{lagBlocks}}
GET /v1/config Chain, contract addresses, markets (perpId, symbol, decimals, mark, min order size), deposit cap, Perpl minimum account open, team-run addresses.
GET /v1/markets Per market: mark, oracle, funding, open interest, best bid and ask.
GET /v1/leaders?window=7d|30d|90d&sort=score|pnl|drawdown&market=BTC Ranked leaders: {accountId, address, score, pnlUsd, pnlPct, maxDrawdownPct, winRate, avgLeverage, trades, markets[], followers, nansen:{labels[], …}, teamRun}
GET /v1/leaders/:accountId Profile and due-diligence card: equity curve, stats, open positions, recent trades, Nansen labels and cross-venue notes, risk flags.
GET /v1/owners/:owner/accounts The owner's MirrorAccounts (predicted and deployed), each with balance, equity, policy, positions, PnL attributed per leader, paused, expiry.
GET /v1/accounts/:account One MirrorAccount in full.
GET /v1/accounts/:account/feed?cursor= Mirrored, Blocked, Deposited, Withdrawn, PolicyUpdated, Paused and ClosedAll events, each with txHash, block, commitState (proposed, voted, finalized), latencyMs (leader fill to copy tx) and the decoded block reason with limit and actual.
GET /v1/stats Public stats: accounts created, funded accounts, net AUSD deposited, copies executed, copies blocked per rule, median latency, active followers in the last 7 days, and every executed copy with its tx (paginated). Excludes team-run.
GET /v1/demo Demo leader and demo follower state, and recent demo cycles.
GET /v1/stream?account=… Server-Sent Events: feed events for an account (or demo) as they happen, including commit-state updates.

Quotes

Method Path Body Returns
POST /v1/quote/follow {owner, leaderAccountId, policy} Per allowed market where the leader holds a position: {perpId, orderType, lotLNS, sizeDisplay, markPNS, pricePNS (slippage bound), expectedFillPNS (from Perpl's book), notionalCNS, marginCNS, leverageHdths, wouldBlock: null | {reason, limit, actual}}, plus the encoded MirrorOrder[] for match now.

Relay (gasless)

The relayer pays gas; the user only signs.

Method Path Body
POST /v1/relay/create {owner, salt} deploys the MirrorAccount clone.
POST /v1/relay/deposit {account, mode: "permit"|"auth", amount, deadline | validAfter+validBefore+nonce, v, r, s}
POST /v1/relay/execute {account, action:{kind, data, nonce, deadline}, signature}: follow, match now, set policy, pause, close all, withdraw, sweep.
POST /v1/relay/transfer ERC-3009 transferWithAuthorization for sending AUSD from the user's address.

Every relay call simulates first (eth_call), submits with an explicit gas limit (estimate × 1.2, because Monad charges the gas limit), and returns {txHash, status, block, gasUsed} after eth_sendRawTransactionSync. Relay calls are rate-limited per owner and per IP.

Demo (team-run, rate-limited)

Method Path Effect
POST /v1/demo/trade The demo leader opens 1 lot of BTC on Perpl mainnet; the engine copies it into the demo follower; after about 20 s the leader closes and the copy close follows. Returns a cycle id; progress streams on /v1/stream?account=demo.
POST /v1/demo/blocked The demo leader opens 1 lot at a leverage above the demo follower's max; the copy is blocked onchain (a Blocked event in its own tx); the leader position is closed again.

One cycle runs at a time globally, with a per-IP hourly limit and a global daily cap.

Push

Method Path Body
POST /v1/push/register {owner, expoPushToken, notifyPublicKey}. Payloads are encrypted to notifyPublicKey, derived on the device from a separate Mera PRF namespace, so the server only relays ciphertext.