📊 Bet Exchange API

Developer Documentation & Integration Guide

v1.0

🚀 Getting Started

Overview

The Bet Exchange API provides real-time betting exchange data for multiple sports:

Base URL

https://bf.softo.io

Features

⚡ Real-time Data

Live odds for all sports and markets

🔒 Secure

API key authentication for all endpoints

📺 Live Scorecards

Real-time scorecard widgets for regular sports

📱 CORS Enabled

Works from any domain or application

💻 Easy Integration

Simple REST API with JSON responses

🔐 Authentication

All API endpoints require a valid API key for authentication. You will receive your API key from your account manager.

How to Use Your API Key

📌 Two Methods to Send Your API Key:

Method 1: HTTP Header (Recommended)

X-API-Key: your_api_key_here

Example:

fetch('https://bf.softo.io/api/sports', { headers: { 'X-API-Key': 'your_api_key_here' } })

Method 2: Query Parameter

https://bf.softo.io/api/sports?apiKey=your_api_key_here
⚠️ Keep Your API Key Secure:
  • Never share your API key publicly
  • Don't commit API keys to public repositories
  • Store keys securely in environment variables
  • Contact support if your key is compromised

Testing Your API Key

// JavaScript Example async function testApiKey() { const response = await fetch('https://bf.softo.io/api/sports', { headers: { 'X-API-Key': 'your_api_key_here' } }); if (response.ok) { console.log('✅ API key is valid!'); const data = await response.json(); console.log(data); } else { console.log('❌ Invalid API key'); } }
# cURL Example curl -H "X-API-Key: your_api_key_here" \ https://bf.softo.io/api/sports

📡 API Endpoints

GET /api/sports

Description: Retrieves list of all available sports.

Request

GET https://bf.softo.io/api/sports X-API-Key: your_api_key_here

Response

{ "data": [ { "name": "Cricket", "sportCode": "4" }, { "name": "Football", "sportCode": "1" }, { "name": "Horse Racing", "sportCode": "HORSE_RACING" }, { "name": "Greyhound Racing", "sportCode": "GREYHOUND_RACING" } ] }
GET /api/matches?sportId={sportId}

Description: Retrieves all matches/events for a specific sport.

Query Parameters

Parameter Type Required Description
sportId String Required Sport code from /api/sports (e.g., "4" for Cricket)

Request

GET https://bf.softo.io/api/matches?sportId=4 X-API-Key: your_api_key_here

Response

{ "data": { "sportData": [ { "sportName": "Cricket", "leagues": [ { "name": "T20 Championship", "events": [ { "id": "35125278", "name": "Team A v Team B" } ] } ] } ] } }
GET /api/horse-events

Description: Retrieves all horse racing events with venues and race times.

Response Structure

{ "data": { "countries": [ { "name": "GB", "Venues": [ { "_id": "689b3b35ea46df8ea51a4893", "name": "Lingfield", "events": [ { "_id": "696b5651ea46dfe08a6025a6", "markets": [ { "marketStartTime": "2026-01-17T13:55:00.000Z", "type": "WIN" } ] } ] } ] } ] } }
GET /api/horse-event/{eventId}?venue={venueId}&time={time}

Description: Retrieves detailed markets for a specific horse race.

Parameters

Parameter Type Required Description
eventId String Required Event _id from /api/horse-events
venue String Required Venue _id from /api/horse-events
time String Required Market start time (ISO format, URL encoded)

Request Example

GET https://bf.softo.io/api/horse-event/696b5651ea46dfe08a6025a6?venue=689b3b35ea46df8ea51a4893&time=2026-01-17T13:55:00.000Z X-API-Key: your_api_key_here
GET /api/greyhound-events

Description: Retrieves all greyhound racing events.

Response structure is identical to /api/horse-events

GET /api/greyhound-event/{eventId}?venue={venueId}&time={time}

Description: Retrieves detailed markets for a specific greyhound race.

Parameters and response structure identical to /api/horse-event

GET /api/event?sport={sport}&eventCode={eventCode}

Description: Retrieves detailed information for a regular sport event.

Query Parameters

Parameter Type Required Description
sport String Required Sport name (e.g., "Cricket")
eventCode String Required Event ID from /api/matches
POST /api/exchange

Description: Retrieves live exchange odds (back/lay prices) for regular sports.

Request Body

Array of market IDs (strings)

["1.123456789", "1.987654321"]

Request Example

POST https://bf.softo.io/api/exchange Content-Type: application/json X-API-Key: your_api_key_here ["1.123456789"]

Response

{ "data": [ { "marketId": "1.123456789", "runners": [ { "selectionId": "12345", "runnerName": "Team A", "ex": { "availableToBack": [ { "price": 1.95, "size": 1500 }, // [0] = Best back (rightmost) { "price": 1.94, "size": 800 } // [1] = Middle ], "availableToLay": [ { "price": 1.96, "size": 2000 }, // [0] = Best lay (leftmost) { "price": 1.97, "size": 1200 } // [1] = Middle ] } } ] } ] }
📌 Important - Price Array Ordering:
  • availableToBack[0]: Best back price (displayed on the rightmost position, closest to lay prices)
  • availableToLay[0]: Best lay price (displayed on the leftmost position, closest to back prices)
  • Both [0] indices represent the best prices and are highlighted with a blue outline in the UI
  • Always display up to 3 prices for each side (back and lay)
POST /api/exchange-horse

Description: Retrieves live exchange odds for horse/greyhound racing.

⚠️ Important: For horse/greyhound racing, send only ONE market ID at a time.

Request Body

["1.252767771"] // Single market only

Request Example

POST https://bf.softo.io/api/exchange-horse Content-Type: application/json X-API-Key: your_api_key_here ["1.252767771"]

Response structure is identical to /api/exchange

🎨 UI Implementation Guide

Integration Flow

Regular Sports Flow

1. List Sports
GET https://bf.softo.io/api/sports → Display all sports
2. Select Sport
GET https://bf.softo.io/api/matches?sportId={id} → Display matches
3. Select Match
GET https://bf.softo.io/api/event?sport={sport}&eventCode={code} → Display markets
4. Load Live Odds
POST https://bf.softo.io/api/exchange → Display live odds + scorecard widget

Horse/Greyhound Racing Flow

1. List Events
GET https://bf.softo.io/api/horse-events → Display venues and race times
2. Select Race
GET https://bf.softo.io/api/horse-event/{id} → Display available markets
3. Select Market
Display market with runners
4. Load Live Odds
POST https://bf.softo.io/api/exchange-horse with single market ID → Display live odds

Direct API Usage Examples

Loading Sports

const API_KEY = 'your_api_key_here'; async function loadSports() { try { const response = await fetch('https://bf.softo.io/api/sports', { headers: { 'X-API-Key': API_KEY } }); const data = await response.json(); data.data.forEach(sport => { const element = document.createElement('div'); element.textContent = sport.name; element.onclick = () => { if (sport.sportCode === 'HORSE_RACING') { loadHorseRacing(); } else if (sport.sportCode === 'GREYHOUND_RACING') { loadGreyhoundRacing(); } else { loadMatches(sport.sportCode); } }; container.appendChild(element); }); } catch (error) { console.error('Error loading sports:', error); } }

Loading Exchange Odds

async function loadOdds(marketId) { try { const response = await fetch('https://bf.softo.io/api/exchange', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY }, body: JSON.stringify([marketId]) }); const data = await response.json(); // Display odds in your UI displayOdds(data); } catch (error) { console.error('Error loading odds:', error); } }

📊 Display Guidelines

How to Display Odds

When you receive odds data from the API, display them to your users following these guidelines:

Color Coding

📌 Use these colors:
  • Back Prices: Light blue background (#cfe9f8)
  • Lay Prices: Light pink background (#f6c1c1)
  • Best Prices: Blue outline (#1976ff) around the best price

Layout Structure

Each runner (team/player/horse) should display:

Price Ordering - VERY IMPORTANT

⚠️ Critical: Back Prices Must Be Reversed!

The API returns prices in an array, but you must display them differently:

Example: Team A
← BACK PRICES (Blue)
1.93
[2]
1.94
[1]
1.95
[0]
BEST
LAY PRICES (Pink) →
1.96
[0]
BEST
1.97
[1]
1.98
[2]
↑ Notice: Both [0] prices meet in the middle with blue outline

Understanding the Array Order

✅ The Rule:
BACK PRICES - Display in REVERSE:
API gives you: [1.95, 1.94, 1.93]
You display: [1.93] [1.94] [1.95] (reversed)
Result: Best price [0]=1.95 appears on the RIGHT
LAY PRICES - Display NORMAL:
API gives you: [1.96, 1.97, 1.98]
You display: [1.96] [1.97] [1.98] (as-is)
Result: Best price [0]=1.96 appears on the LEFT

Why This Matters

The best back price and best lay price should meet in the middle. This is the standard betting exchange layout that users expect. Both best prices (index [0] from each array) should be highlighted with a blue outline.

Each Price Box Shows

📺 Live Scorecard Widgets

Overview

For regular sports (Cricket, Football, Tennis, etc.), you can display live scorecards using iframe widgets. There are two methods available:

Method 1: Market ID Based (Default)

https://bf3.widgets.softo.io/Common/LiveScoreCard?id={marketId}
Usage:
  • Replace {marketId} with the actual market ID from the API
  • Use the first market ID from the event's markets array
  • Embed in an iframe with recommended dimensions: width 100%, height 260px

Example

<iframe src="https://bf3.widgets.softo.io/Common/LiveScoreCard?id=1.123456789" width="100%" height="260px" frameborder="0"> </iframe>

Method 2: Event Code Based

https://bf2.widgets.softo.io/sport-radar-ui?event_id={eventCode}
Usage:
  • Replace {eventCode} with the event ID from the API
  • This method uses a different scorecard provider
  • Same iframe dimensions recommended

Example

<iframe src="https://bf2.widgets.softo.io/sport-radar-ui?event_id=35125278" width="100%" height="260px" frameborder="0"> </iframe>

Switching Between Methods

You can implement a toggle button to switch between both scorecard methods for better reliability. If one fails to load, users can try the alternative method.

⚠️ Important Notes:
  • Scorecards are only for regular sports (Cricket, Football, Tennis, etc.)
  • Do NOT use scorecards for Horse Racing or Greyhound Racing
  • Both widgets are live and update in real-time

When to Display Scorecards

❓ Need Help?

📧 Technical Support

For API issues, integration questions, or technical support, contact your technical account manager.

🔑 API Key Issues

If you need a new API key or your key is not working, contact your account manager.