For builders & agents

Public API

Read live market state as JSON. No auth required.

PNL exposes a public, unauthenticated REST API for reading live market state. This is the recommended way for agents, dashboards, and integrators to consume PNL data — much cheaper than scraping the realtime client-side /browse UI.

Endpoints

MethodPathDescription
GET/api/markets/list?status=<status>&page=<n>&limit=<n>List markets filtered by status
GET/api/markets/<id>Single market by id
GET/sitemap.xmlFull crawl index, includes every market URL
GET/llms.txtAI-readable summary of the protocol

Base URL: https://pnl.market

Status filter values

statusMeaning
activeLiving markets accepting votes (default)
yesWinsBloomed — YES won, token launched
noWinsWithered — NO won, critics paid out
expiredClosed — window ended without meeting threshold
refundReturned — refunded due to tie or threshold
allEvery market regardless of state

Rate limits

The read endpoints are IP-rate-limited at 60 requests per minute per IP. Cache hits (Redis) don't count against external API quotas; cache misses fall back to paid providers (Birdeye for token stats, Helius DAS for token metadata) which is why we bound the surface.

Example: fetch all active markets

curl 'https://pnl.market/api/markets/list?status=active&page=1&limit=25'
const r = await fetch('https://pnl.market/api/markets/list?status=active&page=1&limit=25');
const { data } = await r.json();
for (const market of data.markets) {
  console.log(market.name, market.tokenSymbol, `${market.poolBalance / 1e9} SOL pooled`);
}
import requests
r = requests.get('https://pnl.market/api/markets/list', params={'status': 'active', 'limit': 25})
for m in r.json()['data']['markets']:
    print(m['name'], m['tokenSymbol'], f"{int(m['poolBalance'])/1e9} SOL pooled")

Response shape

{
  "success": true,
  "data": {
    "markets": [
      {
        "id": "...",
        "marketAddress": "<solana account>",
        "name": "Nakshatra",
        "tokenSymbol": "NAKSHATRA",
        "description": "...",
        "category": "ai",
        "stage": "prototype",
        "poolBalance": "9850000",
        "targetPool": "15 SOL",
        "poolProgressPercentage": 0,
        "totalParticipants": 1,
        "expiryTime": "2026-11-07T09:33:42.000Z",
        "resolution": "Unresolved",
        "displayStatus": "✅ Active",
        "pumpFunTokenAddress": null,
        "lastSyncedAt": "2026-05-12T00:12:45.343Z"
      }
    ],
    "totalCount": 3,
    "pagination": {
      "page": 1,
      "limit": 25,
      "totalPages": 1,
      "hasMore": false
    }
  }
}

Common questions

"What markets are live right now?"GET /api/markets/list?status=active

"What ideas have launched as tokens?"GET /api/markets/list?status=yesWins

"What got rejected?"GET /api/markets/list?status=noWins

"I want a specific market"GET /api/markets/<id> (the id from the list response)

What's NOT in this API (yet)

  • Vote history / position lookup by wallet — coming with the agent integration release
  • Real-time push (use the existing socket.io WebSocket if you need live updates)
  • Write actions (create market, vote) — see On-chain Program for the permissionless path

On this page