Heartbeats — Dead-Man’s-Switch
If your trading bot crashes between placing orders and the next intended cancel, those orders sit on the book exposed to adverse selection until you notice and intervene. The heartbeat dead-man’s-switch protects unattended bots by auto-cancelling all of your resting orders if the server stops receiving heartbeats for longer than a deadline you choose. This mirrors Polymarket’sPOST /heartbeats dead-man’s-switch
behaviour — the same path, the same interval_ms-style cadence, and the
same “miss a heartbeat → all your resting orders are auto-cancelled”
guarantee. A PM SDK’s heartbeat loop keeps your orders protected when
pointed at PolySimulator.
Endpoints
PolySimulator exposes two paths that route through the same handler:
Both accept the same body and emit the same response.
Request
Response — 200 OK
The
expires_at_ms value is last_heartbeat_at_ms + interval_ms + grace, where:
grace = max(1000ms, 0.25 × interval_ms)— absorbs network jitter and the ~1-second evaluation cadence so bots pinging at exact intervals don’t trigger spurious cancels.
How to use it (the heartbeat loop)
The expected pattern is to ping at half yourinterval_ms so you
stay comfortably ahead of expiry even with one missed beat.
What happens when a heartbeat is missed?
Once your deadline lapses without a fresh heartbeat — typically within about a second of theexpires_at_ms you were given — the server:
- Retires the lapsed registration.
- Cancels all pending limit orders for the API key’s account (same
logic as
POST /v1/cancel-all— refunds BUY notional, returns SELL shares to position).
POST /v1/heartbeats again — a new
registration is created from scratch.
Bounds and error responses
The
[1000, 60000] bound is deliberate:
- Below 1000ms would burn rate-limit quota (2 RPS per registration just for heartbeats) with no safety benefit beyond what 1-second sweeps already provide.
- Above 60000ms defeats the point — a crashed bot would stay exposed for a full minute before its orders cancel.
Durability guarantee
Heartbeat registrations are persisted, not held only in process memory:- Server restarts don’t drop your protection. A deploy or graceful reload preserves every active heartbeat. Your bot’s next refresh after the restart simply bumps the expiry forward — no need to re-register from scratch.
- Refreshes and the expiry sweep never race. A heartbeat that lands at the same instant the deadline is being evaluated keeps your orders alive — the switch never fires spuriously from a timing race. It fires only on a genuine, sustained absence of heartbeats past your deadline.
Related
- Cancel All Orders (
POST /v1/cancel-all) — Manual cancel-all that the dead-man’s-switch delegates to internally. - Polymarket Raw HTTP — Other PM-shape compat endpoints.
- Error Handling — Bot resilience patterns including heartbeat-failure recovery.