Overview
The REST API exposes Atomic's read-side state over HTTPS. It is fed from the same on-chain data the SDK reads, with caching tuned for dashboard and analytics workloads.
The REST API is in beta. Endpoint shapes may change ahead of V3 launch; pin to a specific API version (/v3/...) and watch the changelog. Auth and rate limits are subject to revision.
Base URL
https://api.atomic.green/v3
All endpoints return JSON. Responses include cache-control headers; respect them where possible to keep load on the API low.
Authentication
Public endpoints are unauthenticated and rate-limited per IP at 60 requests/minute.
For higher limits, request an API key from the team via Discord. Authenticated requests pass Authorization: Bearer <key> and get 600 requests/minute plus access to a few private endpoints (your own historical positions, lender balance).
Endpoints
Markets
GET /v3/markets
Response:
{
"markets": [
{
"symbol": "ETH-USDC.e",
"maxLeverage": 20,
"minMargin": "25",
"indexPrice": "3512.40",
"liquidity": "12450000",
"open24h": "3478.10",
"volume24h": "8240000"
},
...
]
}Position quote
GET /v3/quote?market=ETH-USDC.e&side=long&size=10000
Response:
{
"market": "ETH-USDC.e",
"side": "long",
"size": "10000",
"entryPrice": "3512.40",
"slippageBps": 12,
"feeBps": 10,
"feeUsd": "10.00"
}Quotes are live; cache for at most 1–2 seconds.
Open positions (public)
GET /v3/positions/open
Response:
{
"count": 1247,
"positions": [
{
"id": "0x...",
"trader": "0xabc...",
"market": "ETH-USDC.e",
"side": "long",
"margin": "1000",
"leverage": 10,
"entryPrice": "3478.10",
"liqPrice": "3171.79",
"openedAt": "2026-05-08T12:34:56Z"
},
...
]
}Paginated via ?limit=100&cursor=.... Trader addresses are public on-chain data.
Lending pool state
GET /v3/lending/pool
Response:
{
"tvl": "12450000",
"borrowed": "9870000",
"utilization": 0.793,
"apy": 0.184,
"depositors": 2104
}apy is a trailing 24-hour estimate; utilization is live.
My positions (authenticated)
GET /v3/me/positions Authorization: Bearer <key> Response: same shape as /v3/positions/open, scoped to the address tied to the API key.
My lender state (authenticated)
GET /v3/me/lending
Authorization: Bearer <key>
Response:
{
"principal": "5000",
"accruedYield": "47.32",
"queuePosition": null
}queuePosition is non-null only when a withdrawal is queued behind insufficient idle pool capital.
Historical PnL
GET /v3/me/pnl?from=2026-04-01&to=2026-05-01
Authorization: Bearer <key>
Response:
{
"trades": 47,
"winRate": 0.617,
"realizedPnl": "1284.50",
"fees": "92.40",
"byMarket": {
"ETH-USDC.e": { "trades": 31, "realizedPnl": "812.30" },
"BTC-USDC.e": { "trades": 16, "realizedPnl": "472.20" }
}
}Rate limits
| Tier | Rate | Notes | |---|---|---| | Public (no auth) | 60 req/min/IP | Cached responses; 429 on burst | | Authenticated | 600 req/min/key | Higher burst tolerance | | Custom | Negotiated | Reach out via Discord |
429 responses include a Retry-After header. Repeated 429s on the same key may temporarily lower the limit.
Errors
Standard HTTP semantics:
- 400 - malformed request (missing query params, bad symbol).
- 401 - invalid or missing auth.
- 404 - resource does not exist.
- 429 - rate-limited.
- 5xx - upstream issue, retry with backoff.
Error bodies are JSON: { "error": "<machine-readable code>", "message": "<human-readable>" }.
When to use REST vs the SDK vs a subgraph
- REST: server-side queries, dashboards, backtesting. Don't need to sign.
- SDK: anything that signs transactions, plus convenient typed reads.
- Subgraph: bulk historical queries, custom event filtering. See Subgraph.