Odds operations
Get the configuration for all platform interactions
The namespace is of course called odds. All methods return promises. The general design of the namespace follows this pattern unless stated otherwise:
General call:sdk.odds .someMethod() .then((response) => { // Handle response }) .catch((error) => { // Handle error });
N.BOdds are never returned for a match that has already finished. The SDK resolves the status of every match before requesting its odds and treats a finished match as a match without odds.
The responses are comprised of different objects you can find here.
Match related operations
Get odds for matches
Method: getByMatchIds(matchIds, filters?)
Model:
The method returns a Map instance where the keys are the match IDs and the values are Array instances of MatchOddsModel. Every requested match ID is present in the Map — a match without odds, including a match that has already finished, is an empty Array.
Filters object:
-
scopeType:
ScopeTypeEnum.Specifies the time period of the match for which the odds are applicable. Options include:
ScopeTypeEnum.ORDINARY_TIME: Regular match time without extra time or penaltiesScopeTypeEnum.FULL_TIME: Full time match including the extra time and penaltiesDefault value:
ScopeTypeEnum.ORDINARY_TIME -
oddFormat:
OddFormatEnum.Defines the format in which odds values are presented. Options include:
OddFormatEnum.DECIMAL: Odds displayed in decimal format (e.g., 1.50, 4.00)OddFormatEnum.FRACTIONAL: Odds displayed in fractional format (e.g., 1/2, 3/1)Default value:
OddFormatEnum.DECIMAL -
marketTypes:
MatchOddsMarketType[].An array of market types to retrieve odds for. Options include:
MatchOddsMarketEnum.FT_1X2: Full-time 1X2 odds (home win, draw, away win)MatchOddsMarketEnum.HT_1X2: Half-time 1X2 odds
MatchOddsMarketEnum.DOUBLE_CHANCE: The match will finish 1 or X, 2 or X, 1 or 2
MatchOddsMarketEnum.DRAW_NO_BET: The match winner, with the stake returned on a draw
MatchOddsMarketEnum.HT_FT: How will finish the first half (1X2) and full time (1X2)
MatchOddsMarketEnum.BOTH_TEAMS_SCORE: Both teams to score in the match
MatchOddsMarketEnum.CORRECT_SCORE: The correct score of the match
MatchOddsMarketEnum.TEAM_SCORE_FIRST_GOAL: Team to score the first goal in match
MatchOddsMarketEnum.PLAYER_SCORE_FIRST_GOAL: Player to score the first goal in match
MatchOddsMarketEnum.PLAYER_SCORE: Player to score in match
MatchOddsMarketEnum.PLAYER_RED_CARD: Player to receive red card in match
MatchOddsMarketEnum.PLAYER_YELLOW_CARD: Player to receive yellow card in match
MatchOddsMarketEnum.OVER_GOALS_0_5: There will be at least 1 goal in match
MatchOddsMarketEnum.OVER_GOALS_1_5: There will be at least 2 goals in match
MatchOddsMarketEnum.OVER_GOALS_2_5: There will be at least 3 goals in match
MatchOddsMarketEnum.OVER_GOALS_3_5: There will be at least 4 goals in match
MatchOddsMarketEnum.OVER_GOALS_4_5: There will be at least 5 goals in match
MatchOddsMarketEnum.OVER_GOALS_5_5: There will be at least 6 goals in match
MatchOddsMarketEnum.OVER_GOALS_6_5: There will be at least 7 goals in match
MatchOddsMarketEnum.OVER_CORNERS_6_5…OVER_CORNERS_13_5: There will be at least 7 … 14 corners in matchOperators publish new markets without an SDK release, so a market code the SDK does not know yet is accepted as a plain string and matched against the response as-is. Market codes are matched case-insensitively.
Default value:
[FT_1X2] -
operators:
string[].Restricts the response to specific operators, e.g.
["bookmaker-bg", "bookmaker2-bg"]. When omitted, every operator configured for your client is returned. -
affiliateId:
string.Affiliate ID substituted into every operator link that carries an
{affiliate_id}placeholder. -
affiliateIds:
Record<string, string>.Affiliate IDs per operator, e.g.
{ "bookmaker-bg": "aff-123" }. Takes precedence overaffiliateIdfor the operators it names, so a client that shows several operators can use a different affiliate arrangement with each. -
language:
string.BCP 47 language tag for the operator content, e.g.
"EN"or"BG".
ValidationsmatchIds parameter is required. filters is optional, however when invalid filter is provided for any of
scopeType,oddFormatandmarketTypes, a warning message will be logged. Example:The filter "scopeType" is NOT valid and therefore it will be set to ORDINARY_TIME. The VALID values are : ORDINARY_TIME, FULL_TIME
Example call:import { ScopeTypeEnum, OddFormatEnum, MatchOddsMarketEnum } from "fansunited-sdk-esm"; const filters = { scopeType: ScopeTypeEnum.ORDINARY_TIME, oddFormat: OddFormatEnum.DECIMAL, marketTypes: [MatchOddsMarketEnum.FT_1X2], affiliateId: "aff-123" }; const matchIds = ["id", "id2"]; sdk.odds .getByMatchIds(matchIds, filters) .then((response) => { // Handle response }) .catch((error) => { // Handle error });
Example result
{
id: [
{
bookmaker: {
id: "bookmaker-bg",
name: "Bookmaker",
url: "https://bookmaker.com",
assets: [
{
logo: "https://assets.lsdapi.com/images/76ab21dd58330c56e346d8be7f5fc5df.svg",
type: "LOGO",
transparentBackgroundUrl: "https://assets.lsdapi.com/images/76ab21dd58330c56e346d8be7f5fc5df.svg",
backgroundColor: "#0D4AB0"
}
],
links: [
{
appType: "desktop",
selectionTemplateUrl: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
eventTemplateUrl: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
homepageUrl: "https://bookmaker.com"
},
{
appType: "mobile",
selectionTemplateUrl: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
eventTemplateUrl: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
homepageUrl: "https://bookmaker.com"
}
],
branding: {
backgroundColor: "#0954b9",
textColor: "#fce34c",
hoverBackgroundColor: "#074394",
borderColor: "#0954b9"
},
eventUrls: [
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "desktop"
},
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "mobile"
}
],
betslipUrlTemplate: [
{
url: "https://bookmaker.com/sports?betType=Multiple&selectionIds={betslip_ids}&aff=aff-123",
appType: "desktop"
},
{
url: "https://bookmaker.com/sports?betType=Multiple&selectionIds={betslip_ids}&aff=aff-123",
appType: "mobile"
}
],
betslipIdSeparator: "|",
stakesDisclaimer: "18+ risk of addiction",
domainName: "bookmaker.com"
},
type: "PRE_EVENT",
startTime: "2026-09-10T18:45:00Z",
updatedAt: "2026-09-09T11:04:52Z",
markets: [
{
type: {
id: "FT_1X2",
name: "FT_1X2",
code: "FT_1X2",
entityType: "market_type"
},
scope: {
id: "ORDINARY_TIME",
type: "ordinary_time",
name: "ORDINARY TIME",
entityType: "market_scope"
},
selections: [
{
id: "1",
name: "1",
code: "1",
value: "Team A",
odds: "1.50",
urls: [
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "desktop"
},
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "mobile"
}
],
movement: "UP",
oddsOld: "1.45",
entityType: "market_selection",
additionalInfo: null,
providerInfo: {
selectionId: "sr:market:72221154:1:1",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
},
{
id: "X",
name: "X",
code: "X",
value: "Draw",
odds: "4.00",
urls: [
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "desktop"
},
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "mobile"
}
],
movement: "DOWN",
oddsOld: "4.20",
entityType: "market_selection",
additionalInfo: null,
providerInfo: {
selectionId: "sr:market:72221154:1:2",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
},
{
id: "2",
name: "2",
code: "2",
value: "Team B",
odds: "5.50",
urls: [
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "desktop"
},
{
url: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
appType: "mobile"
}
],
movement: "DOWN",
oddsOld: "5.75",
entityType: "market_selection",
additionalInfo: null,
providerInfo: {
selectionId: "sr:market:72221154:1:3",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
}
]
}
]
}
],
id2: []
}
Response notestype is
PRE_EVENTorLIVE, derived from the status of the match. It isnullonly when the status could not be resolved.market.type carries the Fans United market code in
id,nameandcode, and market.scope carries the scope inid,typeandname.odds and oddsOld are strings for decimal odds, and the fractional notation (e.g.
"5/2") whenoddFormatisFRACTIONAL.url, links and eventUrls are built from the resolved operator links. A link the API could not fully resolve is omitted rather than returned partially substituted.
Every
OVER_GOALS_*market returns both the over and the under selection, because each goal line is its own market.
Get odds for a match
Method: getByMatchId(matchId, filters?)
Model:
The method returns an EventOddsModel instance — the odds of a single match, grouped per operator. It accepts the same filters object as getByMatchIds.
ValidationsmatchId parameter is required. When there are no odds for the match, including when the match has already finished, the method rejects with a
404error and statusodds_not_found. The error is shaped by theerrorHandlingModeof your SDK configuration.
Example call:import { MatchOddsMarketEnum } from "fansunited-sdk-esm"; sdk.odds .getByMatchId("id", { marketTypes: [MatchOddsMarketEnum.FT_1X2], affiliateId: "aff-123" }) .then((response) => { // Handle response }) .catch((error) => { // Handle error });
Example result
{
eventId: "id",
startTime: "2026-09-10T18:45:00Z",
updatedAt: "2026-09-09T11:04:52Z",
odds: [
{
operator: {
id: "bookmaker-bg",
name: "Bookmaker",
domainName: "bookmaker.com",
stakesDisclaimer: "18+ risk of addiction",
branding: {
backgroundColor: "#0954b9",
textColor: "#fce34c",
hoverBackgroundColor: "#074394",
borderColor: "#0954b9"
},
assets: [
{
type: "LOGO",
logo: "https://assets.lsdapi.com/images/76ab21dd58330c56e346d8be7f5fc5df.svg",
transparentBackgroundUrl: "https://assets.lsdapi.com/images/76ab21dd58330c56e346d8be7f5fc5df.svg",
backgroundColor: "#0D4AB0"
}
],
betslipUrlTemplate: {
desktop: "https://bookmaker.com/sports?betType=Multiple&selectionIds={betslip_ids}&aff=aff-123",
mobile: "https://bookmaker.com/sports?betType=Multiple&selectionIds={betslip_ids}&aff=aff-123"
},
betslipIdSeparator: "|"
},
urls: {
desktop: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
mobile: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123"
},
markets: [
{
meta: {
market: "FT_1X2",
scope: "ORDINARY_TIME"
},
selections: [
{
code: "1",
value: "Team A",
odds: 1.5,
oddsOld: 1.45,
movement: "UP",
urls: {
desktop: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
mobile: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123"
},
additionalInfo: null,
operatorInfo: {
selectionId: "sr:market:72221154:1:1",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
},
{
code: "X",
value: "Draw",
odds: 4,
oddsOld: 4.2,
movement: "DOWN",
urls: {
desktop: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
mobile: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123"
},
additionalInfo: null,
operatorInfo: {
selectionId: "sr:market:72221154:1:2",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
},
{
code: "2",
value: "Team B",
odds: 5.5,
oddsOld: 5.75,
movement: "DOWN",
urls: {
desktop: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123",
mobile: "https://bookmaker.com/event/team-a-team-b-3094093?aff=aff-123"
},
additionalInfo: null,
operatorInfo: {
selectionId: "sr:market:72221154:1:3",
eventId: "sr:match:72221154",
marketId: "sr:market:72221154:1",
competitionId: "sr:tournament:17"
}
}
]
}
]
}
]
}
EventOddsModel vs MatchOddsModel
getByMatchIdsreturns MatchOddsModel, which keeps the shape it has always had.getByMatchIdandgetByDateRangereturn EventOddsModel, which follows the structure of the API: odds grouped per operator, the market code and scope inmeta, numeric odds, and links as{ desktop, mobile }objects.
Get odds for fixtures in a date range
Method: getByDateRange(filters)
Model:
The method returns an EventsOddsPaginationModel instance: data is an Array of EventOddsModel ordered by start time ascending, and meta carries total, limit and page.
Filters object — everything getByMatchIds accepts, plus:
-
dateFrom:
string. Required. Start of the range (inclusive), ISO 8601 datetime, e.g."2026-09-10T00:00:00Z". -
dateTo:
string. Required. End of the range (inclusive), ISO 8601 datetime. At most 7 days afterdateFrom. -
sport:
SportEnum. Options includeSportEnum.FOOTBALL,SportEnum.BASKETBALL,SportEnum.TENNIS,SportEnum.AMERICAN_FOOTBALL,SportEnum.FORMULA_1,SportEnum.HOCKEY.Default value:
SportEnum.FOOTBALL -
competitionId:
string. Restricts the result to a single competition, e.g."fb:c:1". -
limit:
number. Items per page. Defaults to 50, maximum 200. -
page:
number. Page number, 1-based.
ValidationsdateFrom and dateTo are required, must be valid ISO 8601 datetimes with
dateToafterdateFrom, and the range must not exceed 7 days. Otherwise the method rejects with a400error and statusinvalid_date_range.
Finished fixtures and pagination
meta.totalis the number of fixtures the API holds odds for in the range, and it includes fixtures that have already finished. Those are removed fromdata, so a page that covers past days can contain far fewer entries thanlimit. Query forward-looking ranges to avoid it.
Example call:import { SportEnum, MatchOddsMarketEnum } from "fansunited-sdk-esm"; const filters = { dateFrom: "2026-09-10T00:00:00Z", dateTo: "2026-09-16T23:59:59Z", sport: SportEnum.FOOTBALL, competitionId: "fb:c:1", marketTypes: [MatchOddsMarketEnum.FT_1X2], affiliateId: "aff-123", limit: 50, page: 1 }; sdk.odds .getByDateRange(filters) .then((response) => { // Handle response }) .catch((error) => { // Handle error });
Example result
{
data: [
{
eventId: "id",
startTime: "2026-09-10T18:45:00Z",
updatedAt: "2026-09-09T11:04:52Z",
odds: [
// Same structure as the getByMatchId result above
]
},
{
eventId: "id2",
startTime: "2026-09-11T16:00:00Z",
updatedAt: "2026-09-09T11:05:14Z",
odds: [
// ...
]
}
],
meta: {
total: 124,
limit: 50,
page: 1
}
}Errors
| Code | Status | When |
|---|---|---|
| 400 | invalid_match_ids | getByMatchIds called without a non-empty Array of match IDs |
| 400 | invalid_match_id | getByMatchId called without a match ID |
| 400 | invalid_date_range | getByDateRange called without dateFrom/dateTo, with an invalid range, or with a range wider than 7 days |
| 404 | match_ids_not_found | getByMatchId called with a match ID that has no mapping in the configured ID schema |
| 404 | odds_not_found | getByMatchId called for a match with no odds, or for a match that has already finished |
Updated 13 days ago
