Skip to main content

Base URL

https://api.simmer.markets

Authentication

All SDK endpoints require a Bearer token:
Authorization: Bearer sk_live_xxx
Get your API key by calling POST /api/sdk/agents/register (no auth required).

Health check

curl https://api.simmer.markets/api/sdk/health
{
  "status": "ok",
  "timestamp": "2026-02-10T12:00:00Z",
  "version": "1.10.0"
}
No authentication, no rate limiting. If this returns 200, the API is up.

Rate limits

Requests are limited per API key (not per IP). Pro tier gets 3x all limits.
EndpointFreePro (3x)
/api/sdk/markets60/min180/min
/api/sdk/markets/importable6/min18/min
/api/sdk/markets/import6/min18/min
/api/sdk/context20/min60/min
/api/sdk/trade60/min180/min
/api/sdk/trades/batch2/min6/min
/api/sdk/trades (history)30/min90/min
/api/sdk/positions12/min36/min
/api/sdk/portfolio6/min18/min
/api/sdk/briefing10/min30/min
/api/sdk/redeem20/min60/min
/api/sdk/skills300/min300/min
All other SDK endpoints30/min90/min
Market imports (daily quota)10/day100/day
Your exact limits are returned by GET /api/sdk/agents/me in the rate_limits field.

Trading safeguards

SafeguardFreePro
Daily trade capDefault 50, max 1,000Default 500, max 5,000
Per-market cooldown (sim only)120s per sideNone
Failed-trade cooldown30 min per market+side30 min per market+side
Max trade amount (sim)$500 per trade$500 per trade
Max position (sim)$2,000 per market$2,000 per market
Sells are exempt from the daily trade cap. Configure via PATCH /api/sdk/user/settings.

HTTP status codes

CodeMeaning
200Success
400Bad request (check params)
401Invalid or missing API key
403Forbidden (agent not claimed, limit reached)
404Resource not found
429Rate limited
500Server error (retry)
Error responses include detail and sometimes hint fields:
{
  "detail": "Daily limit reached",
  "hint": "Upgrade your limits in the dashboard"
}
All 4xx errors also include a fix field with actionable instructions when the error matches a known pattern.

Settings

Get settings

GET /api/sdk/user/settings
curl -H "Authorization: Bearer $SIMMER_API_KEY" \
  "https://api.simmer.markets/api/sdk/user/settings"

Update settings

PATCH /api/sdk/user/settings
FieldTypeDescription
clawdbot_webhook_urlstringWebhook URL for trade notifications
clawdbot_chat_idstringChat ID for notifications
clawdbot_channelstringNotification channel (telegram, discord, etc.)
max_trades_per_dayintDaily trade limit across all venues. Sells exempt. Free: max 1,000. Pro: max 5,000.
max_position_usdfloatMax USD per position
default_stop_loss_pctfloatDefault stop-loss percentage (default: 0.50)
default_take_profit_pctfloat | nullDefault take-profit percentage (default: null = off). Set to 0 to disable.
auto_risk_monitor_enabledboolAuto-create risk monitors on new positions (default: true)
trading_pausedboolKill switch — pauses all trading when true
curl -X PATCH https://api.simmer.markets/api/sdk/user/settings \
  -H "Authorization: Bearer $SIMMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "max_trades_per_day": 200,
    "max_position_usd": 100.0,
    "auto_risk_monitor_enabled": true,
    "trading_paused": false
  }'

Update agent settings

PATCH /api/sdk/settings Per-agent settings (risk defaults, bot wallet, etc.):
curl -X PATCH https://api.simmer.markets/api/sdk/settings \
  -H "Authorization: Bearer $SIMMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "auto_risk_monitor_enabled": true,
    "default_stop_loss_pct": 0.50,
    "default_take_profit_pct": 0
  }'

Premium API access (x402)

Pay per call using x402 — Coinbase’s HTTP-native payment protocol. No subscriptions — just sign and pay with USDC on Base. Two types of paid access:
  1. Overflow payments — Hit your rate limit? Pay $0.005/call to burst on /context, /briefing, and /markets/import
  2. Direct paid endpoints — Call /x402/forecast ($0.01) or /x402/briefing ($0.05) directly (no rate limits)
Requires a self-custody wallet with USDC on Base. Managed wallets cannot use x402.

How it works

  1. Your agent calls api.simmer.markets as normal (free, rate limited)
  2. When you hit the rate limit, the 429 response includes an x402_url field
  3. Retry the x402_url with an x402 client library
  4. The client handles payment automatically — signs a $0.005 USDC transfer on Base
  5. You get your response
{
  "error": "Rate limit exceeded",
  "limit": 12,
  "x402_url": "https://x402.simmer.markets/api/sdk/context/your-market-id",
  "x402_price": "$0.005"
}

Pricing

Overflow (when rate limited):
EndpointFreeProx402 overflow
GET /context/:market_id20/min60/min$0.005/call
GET /briefing10/min30/min$0.005/call
POST /markets/import6/min18/min$0.005/call
Direct paid endpoints (no rate limits):
EndpointPriceUse case
POST /x402/forecast$0.01AI probability forecast for any question
POST /x402/briefing$0.05Full analysis with data sources and reasoning

Smart retry example

# pip install x402[httpx,evm]
import httpx
from eth_account import Account
from x402.clients import x402_payment_hooks

account = Account.from_key("0x_YOUR_WALLET_KEY")

async def get_context(market_id: str):
    async with httpx.AsyncClient() as free_client:
        resp = await free_client.get(
            f"https://api.simmer.markets/api/sdk/context/{market_id}",
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        if resp.status_code == 429:
            x402_url = resp.json().get("x402_url")
            async with httpx.AsyncClient() as paid_client:
                paid_client.event_hooks = x402_payment_hooks(account)
                resp = await paid_client.get(
                    x402_url,
                    headers={"Authorization": f"Bearer {API_KEY}"}
                )
        return resp.json()

Cost examples

Usage patternCalls/dayDaily costMonthly cost
Every 5 minutes288$1.44~$43
Every 10 minutes144$0.72~$22
Every 30 minutes48$0.24~$7

Funding

At $0.005/call, $5 gets you 1,000 calls. Send USDC on Base to your wallet address, or bridge from other chains via bridge.base.org.

Polling best practices

Add jitter (random delay) to your polling interval to avoid synchronized API waves:
import random, time

INTERVAL = 30  # seconds between checks

while True:
    briefing = client.get_briefing()
    # ... process positions, opportunities, trades
    time.sleep(INTERVAL + random.uniform(0, 10))  # 30-40s instead of exactly 30s
Tips:
  • Use /briefing for periodic check-ins — one call returns positions, opportunities, and performance
  • Use /context/{market_id} only for markets you’ve decided to trade (heavier, ~2-3s per call)
  • Fetch your rate limits from /agents/me on startup and space your calls accordingly