REST API Endpoints#
This page documents the public read endpoints. For the complete REST reference — authentication, authenticated endpoints (orders, stats, achievements), and error semantics — see Full REST Reference.
Unless marked as an operational root endpoint, prepend /api/v1 to each path
(e.g. GET /api/v1/markets). Legacy root aliases for /v2/...,
/tx/..., /orders?tx=..., /config, /trades, /orderbook/top,
/status, and /admin/... remain served for compatibility but return
Deprecation: true plus canonical-link headers. New integrations should use
the /api/v1 forms shown here.
Complete Endpoint Inventory#
This inventory is checked against openapi.yaml by make docs-check. It is
intentionally compact; detailed request and response examples live in the
sections below and in Full REST Reference.
| Method | Path | Auth | operationId |
|---|---|---|---|
GET | /exchange/symbols | Public | getExchangeSymbols |
GET | /exchange/symbols/{symbol} | Public | getExchangeSymbol |
GET | /exchange/markets | Public | getExchangeMarkets |
GET | /exchange/markets/{symbol} | Public | getExchangeMarket |
GET | /exchange/orderbook/{symbol} | Public | getExchangeOrderbook |
GET | /exchange/quality | Public | getExchangeQuality |
GET | /exchange/quality/{symbol} | Public | getExchangeQualityBySymbol |
GET | /exchange/reconcile/{symbol} | Public | getExchangeReconcile |
GET | /exchange/account | Wallet | getExchangeAccount |
GET | /exchange/trades/{symbol} | Public | getExchangeTrades |
GET | /exchange/candles/{symbol} | Public | getExchangeCandles |
GET | /exchange/ticker/{symbol} | Public | getExchangeTicker |
GET | /markets | Public | getMarkets |
GET | /markets/current | Public | getMarketsCurrent |
GET | /markets/{marketId} | Public | getMarketsByMarketId |
GET | /markets/{marketId}/creator-fee-claims | Public | getMarketsByMarketIdCreatorFeeClaims |
GET | /markets/{marketId}/trades | Public | getMarketsByMarketIdTrades |
GET | /markets/{marketId}/candles | Public | getMarketsByMarketIdCandles |
GET | /positions | Wallet | getPositions |
GET | /responsible-trading | Wallet | getResponsibleTrading |
PUT | /responsible-trading | Wallet | putResponsibleTrading |
GET | /orders | Wallet | getOrders |
DELETE | /orders/{orderId} | Wallet | deleteOrdersByOrderId |
POST | /orders/{orderId}/cancel | Wallet | postOrdersByOrderIdCancel |
GET | /user/profile | Wallet | getUserProfile |
PUT | /user/profile | Wallet | putUserProfile |
GET | /user/streak | Wallet | getUserStreak |
GET | /user/balance | Wallet | getUserBalance |
GET | /user/orders | Wallet | getUserOrders |
GET | /user/positions | Wallet | getUserPositions |
GET | /stats | Wallet | getStats |
GET | /stats/platform | Public | getStatsPlatform |
GET | /stats/history | Wallet | getStatsHistory |
GET | /stats/{wallet}/pnl-history | Wallet | getStatsByWalletPnlHistory |
GET | /stats/trades | Wallet | getStatsTrades |
GET | /alerts | Wallet | getAlerts |
POST | /alerts | Wallet | postAlerts |
DELETE | /alerts/{alertId} | Wallet | deleteAlertsByAlertId |
GET | /watchlist/markets | Public | getWatchlistMarkets |
GET | /watchlist | Wallet | getWatchlist |
POST | /watchlist | Wallet | postWatchlist |
DELETE | /watchlist/{marketId} | Wallet | deleteWatchlistByMarketId |
GET | /leaderboard | Public | getLeaderboard |
GET | /leaderboard/{period} | Public | getLeaderboardByPeriod |
GET | /achievements | Wallet | getAchievements |
GET | /achievements/all | Public | getAchievementsAll |
GET | /challenges/today | Public | getChallengesToday |
GET | /challenges/progress | Wallet | getChallengesProgress |
GET | /challenges/history | Wallet | getChallengesHistory |
POST | /notifications/register | Wallet | postNotificationsRegister |
POST | /notifications/unregister | Wallet | postNotificationsUnregister |
GET | /notifications/tokens | Wallet | getNotificationsTokens |
GET | /notifications/prefs | Wallet | getNotificationsPrefs |
PUT | /notifications/prefs | Wallet | putNotificationsPrefs |
GET | /config | Public | getConfig |
GET | /v2/fee-config | Public | getV2FeeConfig |
GET | /v2/referral/{address} | Public | getV2ReferralByAddress |
GET | /v2/referrer/{address}/earnings | Public | getV2ReferrerByAddressEarnings |
GET | /v2/referrals/diagnostics | Wallet | getV2ReferralsDiagnostics |
GET | /v2/referrals/leaderboard | Public | getV2ReferralsLeaderboard |
GET | /v2/wallet/{address}/analytics | Public | getV2WalletByAddressAnalytics |
POST | /v2/handles | Wallet | postV2Handles |
GET | /v2/handles/{query} | Public | getV2HandlesByQuery |
POST | /v2/share | Wallet | postV2Share |
GET | /v2/share/{id} | Public | getV2ShareById |
POST | /tx/create-market | Wallet | postTxCreateMarket |
POST | /tx/create-market-pull | Wallet | postTxCreateMarketPull |
POST | /tx/place-order | Wallet | postTxPlaceOrder |
POST | /tx/cancel-order | Wallet | postTxCancelOrder |
POST | /tx/redeem | Wallet | postTxRedeem |
POST | /tx/claim-creator-fees | Wallet | postTxClaimCreatorFees |
POST | /tx/set-referrer | Wallet | postTxSetReferrer |
POST | /tx/claim-referrer-earnings | Wallet | postTxClaimReferrerEarnings |
GET | /creators | Public | getCreators |
GET | /creators/{address} | Public | getCreatorsByAddress |
POST | /compliance/verify-integrity | Wallet | postComplianceVerifyIntegrity |
POST | /compliance/confirm-jurisdiction | Wallet | postComplianceConfirmJurisdiction |
GET | /compliance/jurisdiction-attestation | Wallet | getComplianceJurisdictionAttestation |
POST | /attestation/challenge | Wallet | postAttestationChallenge |
POST | /attestation/verify | Wallet | postAttestationVerify |
GET | /status | Public | getStatus |
GET | /trades | Public | getTrades |
GET | /orderbook/top | Public | getOrderbookTop |
GET | /admin/events | Wallet | getAdminEvents |
GET | /admin/fee-totals | Wallet | getAdminFeeTotals |
GET | /admin/alerts | Wallet | getAdminAlerts |
GET | /admin/referrer-treasury/{shard} | Wallet | getAdminReferrerTreasuryByShard |
Exchange Facade#
The exchange facade is a read-only, terminal-friendly view of Seesaw markets. It gives bots and third-party terminals canonical symbols, current market metadata, book snapshots, trades, candles, and ticker values without adding a new custody, signing, webhook, or order-entry trust boundary.
Canonical symbols use this format:
SEESAW:<BASE>-<QUOTE>:<YYYYMMDDTHHMM>:<DURATION>:<YES|NO>
Example:
SEESAW:SOL-USD:20260708T1200:15M:YES
Use these routes when an integration wants exchange-style identifiers and normalized read models:
| Path | Description |
|---|---|
/exchange/symbols | Lists canonical YES and NO instruments for indexed markets |
/exchange/symbols/{symbol} | Resolves one canonical symbol |
/exchange/markets | Lists exchange-style market summaries |
/exchange/markets/{symbol} | Returns one exchange-style market summary |
/exchange/orderbook/{symbol} | Returns current depth with snapshot sequence and checksum |
/exchange/quality | Returns global exchange facade freshness and quality |
/exchange/quality/{symbol} | Returns symbol-level freshness and quality |
/exchange/reconcile/{symbol} | Returns market, book, latest trade, and recovery metadata |
/exchange/account | Returns signed-wallet positions, collateral, and risk summary |
/exchange/trades/{symbol} | Returns the recent trade tape for the symbol's market |
/exchange/candles/{symbol} | Returns maintained candle buckets for the symbol's market |
/exchange/ticker/{symbol} | Returns best bid, best ask, last price, and 24h volume |
For live or replayable activity streams, use a user-owned Solana RPC or stream provider with the Trustless Stream Consumer Recipes. The hosted exchange facade is a convenience read surface, not the source of custody or signing truth.
/exchange/account includes a risk object for terminal dashboards:
current position value, max loss, max payout, authoritative claimable amount
when available, concentration warning, asset exposures, and per-market
loss/payout breakdowns. Historical settled payouts remain in
balances[].settledPayouts and are not counted as live account value. Amounts
are settlement-mint base-unit decimal strings.
Markets#
List Markets#
GET /markets
Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
state | integer | - | Filter by state (0=Pending, 1=Created…5=Closed) |
pair | string | - | Filter by mapped Pyth pair, e.g. SOL/USD; unknown pairs return no matches |
duration | number | - | Filter by duration_seconds |
resolved | number | - | Use resolved=1 for terminal resolved/closed markets with an outcome |
limit | number | 50 | Items per page (max 100) |
offset | number | 0 | Pagination offset (max 1,000,000) |
chain | string | solana | solana; non-Solana values are not supported for open beta |
Response (wrapped in data envelope):
{
"data": {
"markets": [
{
"id": 1,
"address": "ABcd...1234",
"marketId": "1937600",
"pythFeed": "0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
"state": 2,
"outcome": null,
"tStart": "2026-02-12T00:00:00.000Z",
"tEnd": "2026-02-12T00:15:00.000Z",
"startPrice": "68523400000",
"startPriceExpo": -8,
"totalVolume": "15000000",
"totalTrades": 42,
"totalPositions": 18
}
],
"total": 96,
"limit": 50,
"offset": 0
}
}
Get Current Market#
Returns the active trading market (state=2) or the next upcoming market.
GET /markets/current
Response (wrapped in data envelope):
{
"data": {
"market": {
"id": 1,
"address": "ABcd...1234",
"marketId": "1937600",
"pythFeed": "0xff61...",
"settlementMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
"tStart": "2026-02-12T00:00:00.000Z",
"tEnd": "2026-02-12T00:15:00.000Z",
"startPrice": "68543210000",
"startPriceConf": "12345000",
"startPriceExpo": -8,
"endPrice": null,
"outcome": null,
"totalYesShares": "150000000000",
"totalNoShares": "120000000000",
"totalVolume": "500000000000",
"state": 2
},
"status": "trading"
}
}
state is an integer (0=Pending, 1=Created, 2=Trading, 3=Settling, 4=Resolved,
5=Closed). status is "trading" or "upcoming". Returns 404 if no current or
upcoming market exists.
Note: totalCollateral is a deprecated field frozen at the create-time value
since protocol upgrade F-020. Do not rely on it.
Get Market by ID#
GET /markets/:marketId
Parameters:
| Name | Type | Description |
|---|---|---|
marketId | string | Market address (base58) or numeric market ID |
Response (wrapped in data envelope):
{
"data": {
"market": {
"...": "all market list fields",
"accumulatedCreatorFees": "12000",
"tickSizeBps": 100,
"feeConfig": {
"feeCapBps": 200,
"decayRateBps": 600
}
},
"orderbook": {
"bids": [{ "price": 6500, "quantity": "10000000", "orders": 3 }],
"asks": [{ "price": 7000, "quantity": "8000000", "orders": 2 }]
}
}
}
tickSizeBps carries the live order-book tick size used for canonical YES-price
rounding previews. feeConfig carries the live fee-curve parameters:
feeCapBps (ceiling) and decayRateBps (slope). These are the inputs consumed
by the slippage estimator in @seesaw/core — see
Trustless SDK for how fee estimation works without
trusting the indexer. Defaults are 100 for tick size and 200/600 for fee config
when no config event has been indexed.
The market also exposes per-market creator-fee claims at:
GET /markets/:marketId/creator-fee-claims
Returns an array of claim events: { marketAddress, creatorTokenAccount, caller, amount, slot, signature, claimedAt }.
Fee Config#
Get Current Fee Config#
Returns the current and historical fee-curve parameters plus the three-way
split. The deprecated root alias GET /v2/fee-config remains available for
older clients.
GET /api/v1/v2/fee-config
Response (unwrapped):
{
"current": {
"changed_at": "2026-02-01T00:00:00.000Z",
"fee_cap_bps": 200,
"decay_rate_bps": 600,
"protocol_share_bps": 5000,
"creator_share_bps": 1000,
"referral_share_bps": 4000,
"tx_signature": "5wHu..."
},
"history": [
{
"changed_at": "2026-01-01T00:00:00.000Z",
"fee_cap_bps": 300,
"decay_rate_bps": 700,
"protocol_share_bps": 5000,
"creator_share_bps": 1000,
"referral_share_bps": 4000,
"tx_signature": "3xKp..."
}
],
"invariants": {
"feeSplitValid": true,
"invalidFeeSplitRows": 0
}
}
History returns up to 25 rows in reverse-chronological order. Fields use
snake_case. The client SDK (@seesaw/core) maps these to feeCapBps /
decayRateBps in the camelCase FeeConfig type.
The fee formula is:
fee_bps(price) = min(fee_cap_bps, decay_rate_bps × (10000 − price) / 10000)
At the default cap of 200 bps and decay of 600 bps, fees are highest near 0 bps (pure NO-side orders) and lowest near 10000 bps (pure YES-side orders).
Order Book#
Get Top of Book#
Returns the best bid and ask for a market. The deprecated root alias
GET /orderbook/top remains available for older clients.
GET /api/v1/orderbook/top
Query Parameters:
| Name | Type | Description |
|---|---|---|
market | string | Market address (optional; uses most recent if omitted) |
Response (unwrapped, no data envelope):
{
"best_bid": 5800,
"best_ask": 6000,
"market": "ABcd...1234"
}
market is absent from the response when no markets exist. best_bid and
best_ask are null if there are no resting orders on that side.
Orders#
List Orders#
Returns authenticated wallet orders with optional status and market filters.
GET /orders
Query Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
status | string | No | One of open, filled, cancelled, expired, pending_cancel, cancel_failed. |
market | string | No | Market address filter. |
cursor | string | No | Opaque keyset cursor returned as nextCursor from the previous page. Cannot be combined with offset. |
limit | number | No | Number of orders (default: 50, max: 100). The server fetches limit + 1. |
offset | number | No | Legacy offset pagination parameter. Cannot be combined with cursor. |
Response (data envelope):
{
"data": {
"orders": [
{
"id": "4f63464b-8d2f-4f2a-aa0c-c278c8a77698",
"orderId": "7",
"marketAddress": "ABcd...1234",
"marketId": "12345",
"settlementMint": "Mint...Address",
"side": "yes",
"sideCode": 0,
"sideLabel": "buy_yes",
"priceBps": 5800,
"quantity": "5000000",
"filledQuantity": "0",
"status": "open",
"createdAt": "2026-02-12T00:05:00.000Z"
}
],
"total": 1,
"limit": 50,
"offset": 0,
"nextCursor": null
}
}
Order quantity fields are decimal strings. nextCursor is null when there
is no next page.
Trades#
Get Trades#
Returns recent trades or looks up trades by transaction signature. Root-level
path — also accessible at /api/v1/trades.
For a market-scoped tape, use GET /markets/{marketId}/trades; it injects
the same market filter and supports the same cursor and limit parameters.
GET /trades
GET /markets/{marketId}/trades
Query Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
tx | string | No | On-chain transaction signature. Cannot be combined with cursor. |
market | string | No | Market address filter for recent-trade pages. |
cursor | string | No | Opaque keyset cursor returned as nextCursor from the previous page. |
limit | number | No | Number of trades (default: 100, max: 500). The server fetches limit + 1. |
Response (unwrapped, no data envelope):
{
"trades": [
{
"id": 42,
"market_address": "ABcd...1234",
"maker_order_id": "7",
"taker_order_id": "8",
"maker": "Maker...Address",
"taker": "Taker...Address",
"price_bps": 5800,
"quantity": "5000000",
"maker_side": 1,
"taker_fee": "17400",
"fee_protocol": "8700",
"fee_creator": "1740",
"fee_referral": "6960",
"protocol_treasury_index": 0,
"tx_signature": "5wHu...",
"slot": 312456789,
"executed_at": "2026-02-12T00:05:00.000Z"
}
],
"nextCursor": "eyJzbG90IjoiMzEyNDU2Nzg5IiwiZmlsbF9pbmRleCI6MX0"
}
Trade fields use snake_case. protocol_treasury_index (also aliased as
treasury_index for back-compat) identifies which of the 8 protocol treasury
shards received the protocol fee. tx_signature is also aliased as signature.
Token amounts and fees are decimal strings. nextCursor is null when there
is no next page.
CSV export: send Accept: text/csv or format=csv to receive the same page as
comma-separated rows. CSV export honors market, cursor, and limit; clients
that need the next page should keep using the JSON response to read nextCursor.
Get Market Candles#
Returns OHLCV buckets for a market from the incrementally maintained
market_trade_candles table. Candle volume is the sum of filled share quantity
in the bucket and is returned as a decimal string.
GET /markets/{marketId}/candles?interval=300&limit=500
Query Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
interval | number | No | Candle interval in seconds: 60, 300, 900, 3600, or 86400. |
limit | number | No | Number of candles (default: 500, max: 1000). |
Response:
{
"data": {
"market": "ABcd...1234",
"interval": 300,
"candles": [
{
"bucketStart": "2026-02-12T00:05:00.000Z",
"openPriceBps": 5800,
"highPriceBps": 5900,
"lowPriceBps": 5700,
"closePriceBps": 5850,
"volume": "5000000",
"tradeCount": 3
}
]
}
}
Indexer Status#
Get Indexer Status#
Returns freshness and connectivity status for the indexer.
GET /status
Response (wrapped in data envelope):
{
"data": {
"status": "healthy",
"synced": true,
"slotLag": 2,
"lastProcessedSlot": "250000000",
"lastActivityAt": "2026-02-12T00:05:00.000Z",
"indexerRunning": true,
"pullLifecycle": {
"ready": true,
"stale": false,
"updatedAt": "2026-02-12T00:05:00.000Z",
"counts": {
"tradingPastEnd": 0,
"withoutEndPriceNearExpiry": 0,
"unresolvedPastExpiry": 0,
"deferredCreatorFees": 0,
"terminalMissingEndSnapshot": 0
}
},
"head": {
"lagSlots": 2,
"lagSeconds": 0.8
},
"rpc": {
"healthy": true,
"connected": true,
"wsConnected": true,
"connectedDurationSeconds": 300,
"disconnectedDurationSeconds": null
},
"oracleFreshness": {
"status": "green",
"updatedAt": "2026-02-12T00:05:00.000Z",
"feeds": [
{
"feedId": "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
"sourceAccount": "PythPushFeed111111111111111111111111111",
"oracleMode": "push",
"status": "green",
"freshness": "fresh",
"ageSeconds": 4,
"lastUpdateAt": "2026-02-12T00:04:56.000Z",
"activeMarkets": 2,
"source": "market_microstructure"
}
]
},
"incidentFree24h": {
"value": null,
"status": "unknown",
"scope": "process-local",
"since": null,
"reason": "No durable incident log is available for this process"
},
"subsystems": {
"database": "green",
"rpc": "green",
"websocket": "green",
"indexer": "green",
"pullLifecycle": "green",
"oracleFreshness": "green"
}
}
}
status is one of "healthy", "degraded", or "unhealthy". synced is
true when the indexer has processed at least one slot, the database and RPC
are connected, slot lag is within the healthy read threshold, lifecycle pulls are
ready, and no failed transaction work is pending. Use synced to distinguish
"genuinely no data" from "not yet indexed".
Public status signals use "green", "amber", "red", or "unknown".
incidentFree24h.scope is currently "process-local" because the public status
route does not read a durable incident log.
Positions#
List Authenticated Wallet Positions#
Returns positions for the authenticated wallet. Requires authentication headers (see Full REST Reference).
GET /positions
Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
settled | string | - | Filter: true or false |
limit | number | 50 | Items per page (max 100) |
offset | number | 0 | Pagination offset |
Response (wrapped in data envelope):
{
"data": {
"positions": [
{
"id": 7,
"address": "Pos...Address",
"marketAddress": "ABcd...1234",
"owner": "Wallet...Address",
"market": {
"pythFeed": "0xff61...",
"state": 4,
"outcome": 1
},
"yesShares": "1000000",
"noShares": "0",
"collateralDeposited": "650000",
"totalBought": "1000000",
"totalSold": "0",
"settled": false,
"payout": "0",
"currentYesPrice": 6500
}
],
"balance": "5000000",
"total": 3,
"limit": 50,
"offset": 0
}
}
Responsible Trading#
Read Server-Backed Controls#
Returns the authenticated wallet's account-wide responsible-trading controls. These controls are stored server-side so web and mobile clients see the same cool-off and daily deposit-limit state.
GET /responsible-trading
Response (wrapped in data envelope):
{
"data": {
"walletAddress": "Wallet...Address",
"coolOffUntil": "2026-07-05T16:00:00.000Z",
"blocked": true,
"dailyDepositLimit": "50000000",
"updatedAt": "2026-07-04T16:00:00.000Z"
}
}
Update Server-Backed Controls#
Extends the authenticated wallet's account-wide cool-off and/or sets a daily
deposit limit. Cool-off updates are monotonic: submitting a shorter duration
cannot shorten an active server-side cool-off. The hosted POST /tx/place-order
builder rejects authenticated quote-locking orders when today's indexed
quote-locking order collateral plus the requested order collateral would exceed
dailyDepositLimit.
PUT /responsible-trading
Request body:
{
"coolOffHours": 24,
"dailyDepositLimit": "50000000"
}
Authenticated User#
These endpoints use the wallet-authenticated request headers described in Full REST Reference. They always operate on the signed wallet; callers cannot override the subject wallet in the body.
Profile#
GET /user/profile
PUT /user/profile
GET /user/profile returns the signed wallet's display profile, including the
wallet address, optional handle/display fields, and timestamps. PUT /user/profile updates mutable display metadata only; it does not change
referral locks, settlement accounts, or any on-chain state.
Streak, Balance, Orders, And Positions#
GET /user/streak
GET /user/balance
GET /user/orders
GET /user/positions
GET /user/streak returns the current authenticated trading streak and daily
activity metadata. GET /user/balance returns indexed settlement-token balance
information for the signed wallet. GET /user/orders and
GET /user/positions are authenticated wallet aliases for order and position
summaries; prefer GET /orders and GET /positions when you need filters or
pagination.
Authenticated Stats#
Wallet Stats#
GET /stats
GET /stats/history
GET /stats/:wallet/pnl-history
GET /stats/trades
GET /stats returns the signed wallet's aggregate trading metrics. GET /stats/history returns the authenticated wallet's time-series stats. GET /stats/:wallet/pnl-history returns PnL history for the path wallet, but still
requires wallet authentication to prevent unauthenticated scraping. GET /stats/trades returns the authenticated wallet's trade history. Use
GET /stats/platform for public platform-wide aggregates.
Alerts#
Price Alerts#
GET /alerts
POST /alerts
DELETE /alerts/:alertId
Alerts are wallet-scoped. GET /alerts lists the signed wallet's configured
alerts. POST /alerts creates a new alert for a market/feed threshold and
returns the stored alert row. DELETE /alerts/:alertId deletes only an alert
owned by the signed wallet; missing or foreign alert ids return the same
not-found shape to avoid account enumeration.
Watchlist#
Wallet Watchlist#
GET /watchlist
POST /watchlist
DELETE /watchlist/:marketId
GET /watchlist returns the signed wallet's saved markets. POST /watchlist
adds a market to that wallet's list and is idempotent for an already-saved
market. DELETE /watchlist/:marketId removes the market for the signed wallet
only. Public discovery remains available at GET /watchlist/markets.
Achievements And Challenges#
Achievements#
GET /achievements
GET /achievements/all
GET /achievements returns the signed wallet's unlocked achievements and
progress. GET /achievements/all returns the public achievement catalog.
Daily Challenges#
GET /challenges/today
GET /challenges/progress
GET /challenges/history
GET /challenges/today returns the public challenge set. GET /challenges/progress and GET /challenges/history require wallet
authentication and return the signed wallet's current progress and historical
completion records.
Notifications#
Device Token Registration#
POST /notifications/register
POST /notifications/unregister
GET /notifications/tokens
Notification tokens are wallet-scoped. Registering associates a device token
with the signed wallet; unregistering removes that token for the same wallet.
GET /notifications/tokens is an authenticated debugging/readback endpoint for
the signed wallet's registered tokens and should not be exposed as a public
directory.
Handles And Share Cards#
Handles#
POST /api/v1/v2/handles claims or updates the signed wallet's vanity handle.
Handle ownership is bound to the authenticated wallet. GET /api/v1/v2/handles/:query resolves a public handle or wallet query for display.
Share Cards#
POST /api/v1/v2/share creates a wallet-authenticated share-card record from
server-side indexed stats; clients must not submit arbitrary PnL or ranking
figures. Identical live share payloads are deduplicated and return the existing
id instead of creating unbounded duplicate rows. GET /api/v1/v2/share/:id
returns the public immutable share payload by id until the 30-day share-link
lifetime expires; expired ids return 404.
Hosted Transaction Builders#
Hosted transaction builders return unsigned Solana transaction payloads for the signed wallet to review and sign. They are convenience builders only: the on-chain program remains authoritative for market timing, account ownership, fee conservation, referral precedence, confidence guards, and settlement invariants. Clients must not treat a successful builder response as execution.
POST /tx/create-market
POST /tx/create-market-pull
POST /tx/place-order
POST /tx/cancel-order
POST /tx/redeem
POST /tx/claim-creator-fees
POST /tx/set-referrer
POST /tx/claim-referrer-earnings
create-market builds the legacy-compatible push-feed create flow.
create-market-pull builds the launch-default Pull flow and requires a
Receiver-owned PriceUpdateV2 account for the create snapshot. place-order
applies server-side responsible-trading checks before returning a quote-locking
order transaction. The remaining builders prepare cancellation, redemption,
creator-fee claim, referrer setup, and referrer-earnings claim transactions for
the authenticated wallet.
Compliance And Attestation#
Integrity And Jurisdiction#
POST /compliance/verify-integrity
POST /compliance/confirm-jurisdiction
GET /compliance/jurisdiction-attestation
POST /compliance/verify-integrity records client integrity evidence for the
signed wallet and current app context. POST /compliance/confirm-jurisdiction
records the wallet's current jurisdiction attestation. GET /compliance/jurisdiction-attestation returns the latest attestation state for
the signed wallet.
Wallet Attestation#
POST /attestation/challenge
POST /attestation/verify
POST /attestation/challenge creates a short-lived challenge for the wallet to
sign. POST /attestation/verify verifies the signed challenge and returns the
server's attestation result. These endpoints complement, but do not replace,
the normal wallet-authenticated API headers.
Admin Read Endpoints#
Admin endpoints require wallet authentication and server-side authorization. Unauthorized callers receive the same API error envelope as other protected routes; authenticated admin responses are read-only operational views.
GET /admin/events
GET /admin/fee-totals
GET /admin/alerts
GET /admin/referrer-treasury/:shard
GET /admin/events returns indexed administrative program events. GET /admin/fee-totals returns aggregate protocol, creator, and referral fee
accounting. GET /admin/alerts returns operational alerts from the indexer.
GET /admin/referrer-treasury/:shard returns accounting for one referrer
treasury shard.
Referral#
Get Referral for a Wallet (Referee Lookup)#
Returns the active referral lock for a wallet, if one exists. The deprecated
root alias GET /v2/referral/:wallet remains available for older clients.
GET /api/v1/v2/referral/:wallet
Parameters:
| Name | Type | Description |
|---|---|---|
wallet | string | Referee wallet address |
Response (unwrapped):
{
"success": true,
"data": {
"wallet": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"referrer": "8yLYtg3CW87d97TXJSDpbD5jBkheTqA83TZRuJosgBsV",
"expiresAt": 4070908800000,
"isLocked": true,
"createdAt": "2026-01-01T00:00:00Z"
}
}
Returns data: null when no referral lock exists for the wallet. The
resolveReferrer function in @seesaw/core calls this endpoint as its
first-priority data source. See the
Referral and creator fees guide for the
full precedence rules.
Get Referrer Earnings#
Returns the accumulated and claimed earnings for a referrer wallet.
The deprecated root alias GET /v2/referrer/:wallet/earnings remains available
for older clients.
GET /api/v1/v2/referrer/:wallet/earnings
Parameters:
| Name | Type | Description |
|---|---|---|
wallet | string | Referrer wallet address |
Response (unwrapped):
{
"success": true,
"data": {
"wallet": "8yLYtg3CW87d97TXJSDpbD5jBkheTqA83TZRuJosgBsV",
"accumulated": "4500000",
"totalClaimed": "1000000",
"refereesCount": 12,
"lastCreditAt": 1704067500000,
"settlementMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
}
}
accumulated is the claimable balance in settlement-mint base units. Claim via
ClaimReferrerEarnings (0x24) or seesaw fee claim-referral.
Referral Leaderboard#
Returns top referrers by accumulated earnings. The deprecated root alias
GET /v2/referrals/leaderboard remains available for older clients.
GET /api/v1/v2/referrals/leaderboard?limit=<n>
Default limit is 25, max is 100.
Referral Diagnostics#
Returns referral accounting health data. The deprecated root alias
GET /v2/referrals/diagnostics remains available for older clients.
GET /api/v1/v2/referrals/diagnostics
Wallet Analytics#
Returns a unified public earnings profile: trading PnL, creation, and referral.
The deprecated root alias GET /v2/wallet/:address/analytics remains available
for older clients.
GET /api/v1/v2/wallet/:address/analytics
Creators#
Get Creator Detail#
Returns markets created by a wallet with per-market accumulated creator fees.
Valid wallet addresses that have not created any markets return 200 with
zeroed totals and empty markets / deferredFees arrays, so dashboards can
use this endpoint as an empty-state data source without treating non-creators
as failed requests.
GET /creators/:wallet
Parameters:
| Name | Type | Description |
|---|---|---|
wallet | string | Creator wallet address |
Response (wrapped in data envelope):
{
"data": {
"walletAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"totalFeesEarned": "1500",
"marketsCreated": 3,
"totalVolume": "5000000",
"markets": [
{
"address": "ABcd...1234",
"pair": "0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
"state": 3,
"volume": "3000000",
"trades": 42,
"feesEarned": "1000",
"createdAt": "2026-01-01T00:00:00Z"
}
],
"deferredFees": [
{
"marketAddress": "ABcd...1234",
"accumulatedCreatorFees": "1000",
"settlementMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
"outcome": 1,
"pair": null,
"pythFeedId": null
}
]
}
}
deferredFees lists markets where ClaimCreatorFees can be called now (market
is in Resolved or Closed state with non-zero accumulated fees). Pass this
response directly to listCreatorMarkets in @seesaw/core to get a typed
CreatorMarketEntry list. See the
Referral and creator fees guide for full
examples.
Note: The
pairfield contains the raw Pyth feed ID (32-byte hex string), not a human-readable symbol. Map to a display name using your own feed-ID lookup.
See Also#
- Full REST Reference — authentication and authenticated endpoints
- WebSockets — real-time updates
- SDK Guide — client integration
- Trustless SDK — fee estimation and account reads without indexer trust
- Referral and creator fees guide