Skip to main content

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, averageOdds labeled "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.