Bifrost (BFST) — Cricket API Integration
What is Bifrost?
Bifrost is a B2B aggregator API for cricket betting. It routes to both upstream exchanges and bookmakers through a unified API. The API supports:
- Exchange markets — back+lay, partial matching, order book (fields like
sizeMatched,sizeRemaining,averageOddslabeled "Applicable for Exchange markets" in docs) - Bookmaker markets — back only, fixed odds with liability limits (
maxStake,maxMarket)
Forsyt's scope: Bookmaker markets only. We are integrating Bifrost's bookmaker markets for cricket. Exchange market integration may follow later.
API Architecture
- Data delivery: RabbitMQ queues (Protocol Buffers) — push-based, version-deduplicated
- Bet placement: REST
POST /api/v1/bets/place— returns PENDING, result via queue - Bet status: RabbitMQ
bets.snapshot.queue— push-based - Settlement: RabbitMQ
bets.outcomes.queue— push-based
Order Confirmation Contract
Forsyt's current 9.x/14.x integration is confirmation-gated and all-or-nothing. The local order
and its netting contribution remain unmatched until an authoritative queue PLACED snapshot passes
identity, version, odds, and requested-size validation. PLACED confirms the full size; the
exchange-only Size Vector is not required for that transition. Missing sizeMatched is telemetry,
while contradictory partial evidence is dead-lettered and alerted. Future 1.x exchange execution
is partial-fill capable, remains disabled, and requires a complete on-wire absolute exchange Size
Vector rather than treating omitted financial buckets as zero. See ADR-0016.
For an unmatched 9.x/14.x order, FAILED, full LAPSED, and full CANCELLED are authoritative
zero-match terminal outcomes: the unmatched contribution and its intent-recovery schedule are closed
atomically. PENDING/CANCEL_PENDING do not close recovery, and VOIDED remains a post-match
settlement event rather than a placement rejection.
A post-send HTTP timeout is an ambiguous placement outcome, not a decline. The order remains
unmatched with its accepted liability reserved while same-requestId recovery seeks the provider's
authoritative snapshot. New placements freeze an exact provider-native ProviderPlacementIntent
atomically with the reserve; post-submission code must use that record rather than current MarketBook
or betslip state. Snapshot recovery is automatic and durably backed off per intent. Placement
resubmission remains disabled until Bifrost formally documents same-request, byte-identical-payload
idempotency. Legacy orders without an intent are snapshot-recovery-only and require audited operator
price evidence for replay; no intent is inferred or backfilled.
The recovery API only acknowledges an asynchronous re-emit request and has no documented negative
existence result, so silence after recovery cannot release the reservation. Operations must escalate
the unresolved order until Bifrost supplies authoritative positive or negative evidence.
Market-family prefixes do not determine price encoding. Both HAAR_JEET and DECIMAL have been
observed on 14.x; the authoritative placement-time MarketBook.oddsType is frozen in the intent.
Directory Structure
bifrost/
├── README.md ← You are here
├── BIFROST_API_REFERENCE.md ← Consolidated API reference + Hannibal integration notes
├── comms/ ← Bifrost team correspondence (historical record)
└── api/ ← Bifrost API reference (from official PDF)
├── sports-identifiers.md ← Sport ID mapping (Cricket = 2)
├── outbound-category.md ← Category queue + model + proto
├── outbound-event.md ← Event queue, EventMapping, Competitor/Team
├── outbound-market-catalogue.md ← MarketCatalogue, RunnerCatalogue, MarketMetadata
├── outbound-market-book.md ← MarketBook, Runner, RunnerPriceLadder, RunnerPriceSize
├── betting-api-rest.md ← REST POST /api/v1/bets/place
├── betting-queues.md ← RabbitMQ Bets + BetOutcomes queues
└── betting-data-structures.md ← BetSnapshot, BetOutcomeSnapshot + protos
Event Model (corrected 2026-07-06)
Bifrost events are flat and first-class — there is no event hierarchy, and the earlier
linkage framing is retired. Every market is owned by the event named in its
MarketCatalogue.eventId, and a market is servable only while that owner event is cached and
non-terminal. See BIFROST_API_REFERENCE.md → §6 Event Model — corrected 2026-07-06 (which
explains why the old terminology is dead) and the implementation plan
plans/bifrost-event-lifecycle-rebuild.md.