Skip to main content
ABP is built for production trading. Per-bookmaker circuit breakers, automatic retries, and a two-tier emergency system keep a single failing bookmaker from cascading into a wider outage. This page explains the behaviours that can affect your integration and how to respond to them.

System status

Status & uptime

Live system status is exposed at GET /status (unauthenticated). Poll it for health, or subscribe to the status and emergency WebSocket channels for push notifications.
Unauthenticated infrastructure endpoints:
EndpointPurpose
GET /healthLiveness — is the process up
GET /readyReadiness — are dependencies (DB, cache, OddsPapi) connected
GET /statusSystem status, including emergency state
GET /metricsPrometheus metrics

Rate limits

Rate limits are enforced per client (resolved from your x-api-key) using a sliding window. The default is 100 requests per second and is configurable per client via the rps field.
PropertyValue
Default limit100 requests / second (configurable per client)
Window1 second, sliding
ScopePer client (clientName)
Exceeded response429 Too Many Requests
Every throttled response includes standard headers so you can pace your client:
HeaderDescription
X-RateLimit-LimitYour configured limit (requests per window)
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetSeconds until the window resets
Retry-AfterSeconds to wait before retrying
A 429 response body:
{
  "detail": "Rate limit exceeded",
  "limit": "100",
  "retry_after": 1
}
Because the window resets every second, a short backoff — honouring retry_after — is all that’s needed. There’s no benefit to exponential backoff for rate limiting; just wait out the window.
import time
import requests

def call_with_backoff(method, url, **kwargs):
    while True:
        resp = requests.request(method, url, **kwargs)
        if resp.status_code != 429:
            return resp
        time.sleep(float(resp.headers.get("Retry-After", 1)))
To stay under the limit: batch placements (POST /place-orders accepts many orders per request), prefer the WebSocket over polling, and request a higher rps via support if your workload needs more headroom. WebSocket connection caps are listed under WebSocket → Connection limits.

Circuit breakers

ABP runs a per-bookmaker circuit breaker. If a bookmaker starts failing, its breaker opens and orders targeting it are declined (Bookmaker not available) instead of hanging.
  • Opens after consecutive failures to a bookmaker.
  • Half-opens automatically after a cooldown to test recovery.
  • Closes and resumes normal routing once the bookmaker responds successfully.
Because breakers are per-bookmaker, multi-bookmaker orders continue routing to healthy bookmakers while an unhealthy one is isolated.

Retry with backoff

Transient bookmaker failures are retried automatically with exponential backoff, and ABP fetches fresh odds before each retry pass. Retries are bounded by your order’s expiresAt, so a slow bookmaker can never block an order past its expiry.

Order expiry

Default expiresAt = now + 5 seconds   (maximum 24 hours)
If an order can’t be filled within its window, it transitions to EXPIRED (or PARTIALLY_FILLED if some stake landed). Set a longer expiresAt for less time-sensitive orders, or a shorter one for tighter price discipline.

Emergency mode (two-tier)

In rare cases — maintenance or an upstream incident — ABP can pause order processing. There are two tiers:
TierEffectRecovery
Soft pauseBlocks new orders; in-flight bets continueAuto-recovers after a set interval
EmergencyBlocks new orders and cancels pending onesManual resume by an operator
Status changes are broadcast on the emergency WebSocket channel. When emergency mode is active, POST /place-orders returns a decline rather than queuing work.

Reliable WebSocket delivery

For state you cannot afford to miss (order fills, settlements), enable reliableDelivery: true at login to get at-least-once delivery with acknowledgments and replay. A seq gap signals a missed message; recover via replay or reconcile through GET /orders / GET /bets. See WebSocket.

Your responsibilities

To stay resilient on the client side:
  • Treat declines as normal flow — handle declinedOrders and decline reasons rather than assuming every order fills.
  • Reconcile on reconnect — after a WebSocket drop, replay from your last seq or re-query the REST endpoints.
  • Honour idempotency — reuse the same requestUuid on retries so reconnect storms can’t double-stake. See Core Concepts.
  • Back off on 429 — see Rate limits above.

Support & incidents

ChannelUse for
contact@55-tech.comIntegration help, account/limit changes, higher rps
GET /status + emergency channelReal-time system state
GitHubPublic issues and references
When reporting an incident, include the affected orderId / requestUuid, the bookmaker slug, and a UTC timestamp — it dramatically speeds up diagnosis.

Next steps

WebSocket

Real-time updates with reliable delivery and replay.

Errors

Status codes and decline reasons.