The two inputs that decide behavior
Placement behavior is determined by two things on each order:- How many bookmakers you target — one (
bookmakers: ["pinnacle"]) or many (bookmakers: ["pinnacle", "sharpbet"], or*for all allowed). acceptPartialStake(defaulttrue) — whether ABP may split your stake across multiple bets to fill more of it.
| Mode | Bookmakers | acceptPartialStake | Fill strategy |
|---|---|---|---|
| 1 | Single | false | All-or-nothing at one book. Declines immediately if orderStake exceeds the limit. |
| 2 | Single | true | Multiple bets at one book until the stake is filled or the limit/price is exhausted. |
| 3 | Multiple | false | One bet per bookmaker, placed in parallel. |
| 4 | Multiple | true | Sequential by best price — exhaust each bookmaker before moving to the next. |
You don’t select a mode explicitly — ABP infers it from your
bookmakers list and acceptPartialStake. Leaving bookmakers empty (or *) lets ABP route across every bookmaker your key is allowed to use.Price rules
First-bet rule (all modes)
The first bet of an order must always be placed at a price>= orderPrice. If no bookmaker currently offers a good enough price, ABP waits and retries (it does not place a worse first bet) until the order expires.
Weighted-average rule (modes 2, 3, 4)
After at least one bet is filled, subsequent bets may be placed beloworderPrice, as long as the running weighted-average price of the order stays >= orderPrice:
max_stake <= 0, that bookmaker is exhausted for this order. This lets ABP capture extra liquidity at slightly worse prices without ever breaching your average target.
Mode 1 exception
In Mode 1 (single book, no partial), every bet must clearorderPrice — the weighted-average relaxation does not apply.
Worked example (Mode 2)
Order:orderStake = 1000, orderPrice = 2.00, bookmakers = ["pinnacle"], acceptPartialStake = true.
| Pass | Market price | Limit | Action | Filled | Weighted avg |
|---|---|---|---|---|---|
| 1 | 2.10 | 400 | Place 400 @ 2.10 (first bet ≥ 2.00 ✓) | 400 | 2.10 |
| 2 | 1.95 | 300 | max_stake keeps avg ≥ 2.00 → place 300 @ 1.95 | 700 | 2.04 |
| 3 | 1.90 | 500 | max_stake = 280 → place 280 @ 1.90 | 980 | 2.00 |
| 4 | price moved | — | max_stake ≤ 0 → exhausted | 980 | 2.00 |
PARTIALLY_FILLED with 980 staked at an average of 2.00 — never below your target.
Exchange sweep mode
For prediction-market exchanges (betfair-ex, polymarket, polymarket.us, kalshi, predict.fun, sx.bet, novig.us, 4casters) with partial fills enabled, ABP sends a single order for the full stake with orderPrice as the minimum, and lets the exchange sweep its own order book in one shot. This is faster and more accurate than ABP’s multi-pass logic, and there are no per-pass retries — the exchange fills everything available at or above your price immediately.
Stake-limit cascade
The effective min/max stake for each placement is resolved in priority order (first non-null wins):maxStake: 500, the bookmaker default is 1000, and the live odds limit is 300, the effective max is 500 (the account override wins, even though it is lower than the bookmaker default).
You can preview the effective limits for any selection with GET /betslip before placing — it returns the resolved limit/limitMin (and their USD equivalents) per bookmaker. See Currency & Limits.
Account priority
When you target a bookmaker that has several accounts, ABP picks the highest-priority active account first. Configure priority per account via POST/PATCH /accounts.
Retries & expiry
- Retry throttle: ABP retries a failing
(order, bookmaker)pair no more than once every 2 seconds. - Fresh odds: before each retry pass, ABP re-fetches live odds so placement always uses current market prices, not stale data.
- Expiry: every order has an
expiresAt(default 5 seconds from creation, max 24 hours). When it’s reached, ABP stops trying. Whatever filled so far determines the final status.
Final order status
| Status | Meaning |
|---|---|
FILLED | Entire stake placed. |
PARTIALLY_FILLED | Some stake placed; the rest expired or ran out of price/limit. |
REJECTED | Failed validation (e.g. stake above limit in Mode 1, invalid fixture). |
EXPIRED | expiresAt reached before anything could be placed. |
CANCELLED | You cancelled it (see below). |
FAILED | Internal error during placement. |
POST /place-orders response summarizes a batch as accepted (all placed), partial-success (some declined), or declined (all declined), with per-order detail in acceptedOrders / declinedOrders.
Cancellation
POST /cancel-orders (by orderIds, requestUuids, or userRef) or POST /cancel-all-orders cancels orders that are still PENDING or PARTIALLY_FILLED. Cancellation is asynchronous and cooperative:
- The order’s status is set to
CANCELLEDand itsexpiresAtis moved to now. - A cross-request signal is set so any in-flight placement loop stops at its next pass.
- Pending bets already sent to bookmakers are cancelled where the bookmaker supports it.
Recipes
Each recipe uses the same running selection — fixture
id1000004461512432, outcome 103, player 0. Swap in your own IDs (discover them via OddsPapi v5) and your x-api-key. Base URL: https://v2.55-tech.com.Place across multiple bookmakers (best price)
List several bookmakers and let ABP route to the best price/limits. WithacceptPartialStake: true, ABP sweeps the cheapest first and moves on until the stake is filled (Mode 4 above).
- cURL
- Python
acceptedOrders and declinedOrders. An accepted order may carry multiple bets (one per bookmaker it filled against).
Allow partial fills, reject the rest
To fill only what’s available at your price and never chase, setacceptPartialStake: true on a single bookmaker. The order ends PARTIALLY_FILLED if liquidity runs out — no bets are placed above your orderPrice floor beyond the weighted-average rule.
What happens to the unfilled remainder?
What happens to the unfilled remainder?
The order’s
remainingStake stays unplaced and the order settles to PARTIALLY_FILLED once expiresAt is reached. No further bets are attempted. If you instead want all-or-nothing, set acceptPartialStake: false — the order is declined entirely if the full stake can’t clear at orderPrice.Reconnect & replay missed messages
EnablereliableDelivery so you can recover anything dropped during a disconnect. Track the last seq you processed per subscription; on reconnect, replay from there.
Reconcile settlements
Subscribe tosettlements for push updates, and periodically sweep GET /bets as a backstop. Settlement statuses are WON, LOST, VOID, HALF_WON, HALF_LOST, PUSH, CASHOUT (see Core Concepts).
Cancel orders
Cancellation is asynchronous: ABP marks the order, cancels any pending bets at the bookmaker, and the placement loop stops at its next pass (see Cancellation above). Already-confirmed bets are not recalled.- Cancel specific
- Cancel all
orders channel for the resulting CANCELLED (or PARTIALLY_FILLED) status.
Next steps
Currency & Limits
How stakes, balances, and limits are denominated and converted.
WebSocket
Track fills and settlements in real time.