API Documentation
Programmatic access to iComBot BTC direction signals for Polymarket. Available on the Pro plan. REST + WebSocket.
Quickstart
Once you have a Pro subscription, generate an API key from your account page. Pass it in the Authorization header as a Bearer token.
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://icombot.com/api/v1/signal
Authentication
All REST endpoints require an API key passed as a Bearer token:
Authorization: Bearer <api_key>
WebSocket connections use a query-string parameter instead:
wss://icombot.com/api/v1/ws?key=<api_key>
Keep your API key secret. You can rotate it from the account page at any time.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/signal | Latest round signal (aggregated across 9 bots) |
| GET | /api/v1/signal/history | Signal history (paginated) |
| GET | /api/v1/stats | Performance stats + signal latency metrics |
| GET | /api/v1/status | Real-time service status and round info |
| WSS | /api/v1/ws | Pro real-time signal push over WebSocket |
GET /api/v1/signal
Returns the latest round signal, aggregated from 9 independent trading algorithms.
{
"roundId": "btc-updown-5m-1775875200",
"timestamp": 1775875200,
"entered": true,
"direction": "DOWN",
"result": "WIN",
"botsEntered": 7,
"botsTotal": 9,
"signalDelay": {
"botEnteredAt": 1775875267000,
"signalPushedAt": 1775875268200,
"delayMs": 1200
}
}
| Field | Type | Description |
|---|---|---|
roundId | string | Polymarket 5-minute round identifier |
timestamp | number | Round start time (epoch seconds) |
entered | boolean | Whether any bot entered this round |
direction | string|null | UP or DOWN (majority vote). Null if not entered. |
result | string|null | WIN, LOSE, or PENDING. Null if not entered. |
botsEntered | number | Number of bots that entered (0-9) |
botsTotal | number | Total bots in fleet (9) |
signalDelay | object|null | Signal latency measurement (null if not available) |
GET /api/v1/signal/history
Returns paginated signal history. Each entry is one 5-minute round aggregated across all bots.
Query parameters:
limit— Max results (default 50, max 1000)offset— Pagination offset (default 0)since— Start time (epoch seconds)until— End time (epoch seconds)entered_only=true— Only return rounds where bots entered
{
"signals": [ ... ],
"pagination": { "limit": 50, "offset": 0, "total": 1234 }
}
GET /api/v1/stats
Performance statistics over rolling time windows, plus signal latency metrics.
{
"stats": {
"3h": { "wins": 5, "losses": 2, "skipped": 29, "winRate": 0.714, "entryRate": 0.194 },
"1d": { "wins": 45, "losses": 18, "skipped": 225, "winRate": 0.714, "entryRate": 0.219 },
"7d": { "wins": 280, "losses": 120, "skipped": 1616, "winRate": 0.700, "entryRate": 0.198 },
"30d": { "wins": 1100, "losses": 500, "skipped": 7120, "winRate": 0.688, "entryRate": 0.184 }
},
"signalLatency": {
"avg": 1850,
"p50": 1400,
"p95": 3200,
"p99": 5100,
"sampleSize": 500,
"period": "7d"
}
}
signalLatency measures the delay from bot trade execution to API signal push, in milliseconds. Null if insufficient data.
WebSocket
The WebSocket feed pushes real-time state updates. Connect with your API key:
const ws = new WebSocket(
"wss://icombot.com/api/v1/ws?key=YOUR_API_KEY"
);
ws.onmessage = (ev) => {
const msg = JSON.parse(ev.data);
// msg.type: "hello", "signal:new", "signal:settled"
console.log(msg.type, msg.data);
};
For lowest latency, use the WebSocket feed instead of polling the REST API.
Pro WebSocket connections are limited to 2 per API key. Protocol pings every 3 seconds keep the connection alive.
Rate Limits
| Plan | REST limit | WebSocket |
|---|---|---|
| Free | — | — |
| Basic | — | 1 connection (/ws/basic) |
| Pro | 60 req/min + 10/s burst | 2 connections (/api/v1/ws) |
Exceeding the rate limit returns HTTP 429 with a Retry-After header.
Error Codes
| HTTP | Error | Meaning |
|---|---|---|
| 400 | bad_request | Malformed query or body |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Your plan does not include this endpoint |
| 429 | rate_limited | Exceeded request quota |
| 500 | internal | Server error — please retry |