Base URL
All endpoints are prefixed with /v2.
Non-Custodial Design
All write endpoints (create, buy, sell, redeem, claim-fees, resolve) return an unsigned Solana transaction as a base64 string. Your application deserializes the transaction, signs it locally with the user’s wallet, and submits it to the Solana network. The API never has access to private keys.
Custom Outcome Names
Markets define their own ticker names for the two outcomes (e.g. UP/DOWN, FLIP/NOFLIP). When calling any endpoint that takes a side parameter, you can pass either:
- The market’s custom ticker (e.g.
UP, DOWN)
- The canonical
YES / NO (where YES = first outcome, NO = second outcome)
The API resolves the ticker to the correct on-chain outcome automatically.
const { data } = await res.json();
const tx = Transaction.from(Buffer.from(data.transaction, "base64"));
tx.sign(wallet);
const sig = await connection.sendRawTransaction(tx.serialize());
Authentication
No API key required. All endpoints are open access with rate limiting.
Rate Limits
The API uses per-route rate limiting:
| Request Type | Limit |
|---|
| Read (GET, HEAD) | 600 requests/minute |
| Write (POST, PUT, DELETE) | 300 requests/minute |
Read endpoints have a higher limit since they don’t modify state. If you hit the rate limit, you’ll receive a 429 response. Implement exponential backoff and retry.
Idempotent Endpoints
Several endpoints are idempotent — calling them multiple times produces the same result without errors:
| Endpoint | Idempotent behavior |
|---|
POST /v2/markets/:id/redeem | Returns alreadyRedeemed: true if no tokens to redeem |
POST /v2/markets/:id/claim-fees | Returns noFees: true if no fees to claim |
POST /v2/markets/:id/resolve | Returns alreadyResolved: true if already resolved |
POST /v2/redeem-all | Returns empty transactions array with skipped list if nothing to redeem |
POST /v2/claim-all-fees | Returns empty transactions array with skipped list if nothing to claim |
This means you can safely retry these operations without worrying about duplicate errors.
All responses follow a consistent structure:
{
"success": true,
"data": { ... }
}
Error responses:
{
"success": false,
"error": "Market not found"
}
Status codes
| Code | Meaning |
|---|
200 | Success |
400 | Bad request — invalid parameters or constraint violation |
403 | Forbidden — wallet is not authorized for this action (e.g. not the market creator) |
404 | Not found |
409 | Conflict — action not allowed in current state (e.g. trading on a resolved market, selling on a Pool market) |
429 | Rate limited — slow down |
500 | Server error |
Endpoints
Markets (read)
| Method | Endpoint | Description |
|---|
| GET | /v2/markets | List markets — broken markets auto-filtered |
| GET | /v2/markets/:id | Get market details — includes fees, mint status |
| GET | /v2/markets/:id/quote | Get a price quote |
Market Creation (returns unsigned transactions)
| Method | Endpoint | Description |
|---|
| POST | /v2/markets/create | Create a market — validates resolution timestamp |
| GET | /v2/config | Get on-chain config (includes marketCounter — the newest market ID) |
| POST | /v2/markets/:id/init-mints | Initialize YES/NO token mints (required after create) |
| POST | /v2/markets/confirm | Persist market metadata to backend (makes it visible on the website) |
You must call /v2/markets/:id/init-mints after creating a market. Without it, the market’s token mints are uninitialized and all trades will fail. See the Full Market Lifecycle guide.
Trading (returns unsigned transactions)
| Method | Endpoint | Description |
|---|
| POST | /v2/markets/:id/buy | Buy outcome tokens |
| POST | /v2/markets/:id/sell | Sell outcome tokens |
Resolution & Redemption (returns unsigned transactions)
| Method | Endpoint | Description |
|---|
| POST | /v2/markets/:id/resolve | Resolve market — idempotent, auto-syncs Supabase |
| POST | /v2/markets/:id/redeem | Redeem winnings — idempotent |
| POST | /v2/markets/:id/claim-fees | Claim trade fees — idempotent |
Batch Operations (returns multiple unsigned transactions)
| Method | Endpoint | Description |
|---|
| POST | /v2/redeem-all | Redeem all winning positions for a wallet |
| POST | /v2/claim-all-fees | Claim all accrued fees for a creator |
The batch endpoints scan wallet token accounts directly and are much faster than calling individual redemption/claim endpoints in a loop. Use them for cleanup and portfolio management.
Positions (read)
| Method | Endpoint | Description |
|---|
| GET | /v2/positions/:wallet | Get all positions — enriched with needsRedemption, winningSide |
| GET | /v2/positions/:wallet/:marketId | Get single position |
Raw Units
All token and USDC amounts in requests and responses use raw units (6 decimal places, matching USDC/SPL token decimals):
| Human Amount | Raw Units |
|---|
| $1.00 USDC | 1,000,000 |
| $100 USDC | 100,000,000 |
| 0.10 USDC | 100,000 |
Many endpoints also include *Human fields (e.g. yesBalanceHuman, feesAccruedHuman) for convenience.