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 root-level, prepend /api/v1 to each path (e.g.
GET /api/v1/markets). The legacy prefix /api/ also works but sends
Deprecation: true response headers — migrate to /api/v1/.
Markets#
List Markets#
GET /markets
Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
state | integer | - | Filter by state (0=Pending, 1=Created…5=Closed) |
limit | number | 50 | Items per page (max 100) |
offset | number | 0 | Pagination offset (max 1,000,000) |
chain | string | solana | solana or tempo |
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": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"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",
"feeConfig": {
"feeCapBps": 200,
"decayRateBps": 600
}
},
"orderbook": {
"bids": [{ "price": 6500, "quantity": "10000000", "orders": 3 }],
"asks": [{ "price": 7000, "quantity": "8000000", "orders": 2 }]
}
}
}
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 200 and 600 when no
fee-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. Root-level path — do not add /api/v1/ prefix.
GET /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. Root-level path — also accessible
at /api/v1/orderbook/top.
GET /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.
Trades#
Get Trades#
Returns recent trades or looks up trades by transaction signature. Root-level
path — also accessible at /api/v1/trades.
GET /trades
Query Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
tx | string | No | On-chain transaction signature |
limit | number | No | Number of trades (default: 100, max: 500) |
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"
}
]
}
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.
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
}
}
status is one of "healthy", "degraded", or "unhealthy". synced is
true when indexerRunning && dbConnected && rpcConnected && slotLag <= 100.
Use synced to distinguish "genuinely no data" from "not yet indexed".
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
}
}
Referral#
Get Referral for a Wallet (Referee Lookup)#
Returns the active referral lock for a wallet, if one exists. Root-level path.
GET /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. Root-level path.
GET /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": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
}
}
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. Root-level path.
GET /v2/referrals/leaderboard?limit=<n>
Default limit is 25, max is 100.
Referral Diagnostics#
Returns referral accounting health data. Root-level path.
GET /v2/referrals/diagnostics
Wallet Analytics#
Returns a unified public earnings profile: trading PnL, creation, and referral. Root-level path.
GET /v2/wallet/:address/analytics
Creators#
Get Creator Detail#
Returns markets created by a wallet with per-market accumulated creator fees.
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": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"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