Odds Documentation V1

Endpoint
https://odds.bksignal.com/{ApiKey}/odds/v1/{Discipline}/{Category}/{updateVersion?}
The last path segment updateVersion is optional.
{Discipline} allowed values
Football Football
Basketball Basketball
Tennis Tennis
Volleyball Volleyball
IceHockey Ice hockey
TableTennis Table tennis
{Category} allowed values
Live live events
Upcoming scheduled events
Endpoint for testing
https://odds.bksignal.com/{ApiKey}/odds/v1/test/{Discipline}/{Category}/{updateVersion?}
Use the test URL to get real response examples.
The test method returns up to 2 current events (if available) for all supported bookmakers. Rate limit: no more than 1 request per 30 second.
updateVersion
updateVersion is a Unix timestamp in seconds (UTC). Used for incremental updates.
If omitted treated as 0 (server may return full dataset you have access to).
If provided server returns only records where updated_at > updateVersion (UTC).
Next request take result.updateVersion from the response and use it as the next updateVersion.
Note: all times in response are UTC. updated_at is returned as ISO8601 with Z.
Response
Server returns JSON with either result or error.
Schema
{
  "result": {
    "updateVersion": 1700000000,
    "odds": {
      "{discipline}": {
        "{category}": {
          "{bookmaker}": {
            "{competition}": [
              {
                "event_id": 123456,
                "updated_at": "2026-01-23T11:34:55Z",
                "starts_at": "2026-01-23T11:34:55Z",
                "opponents": ["...","..."],
                "markets": { ... },
                "scores": { ... }
              }
            ]
          }
        }
      }
    }
  }
}
Example (JSON)
{
  "result": {
    "updateVersion": 1769177695,
    "odds": {
      "basketball": {
        "upcoming": {
          "bcgame": {
            "Indonesia IBL": [
              {
                "event_id": 987654,
                "updated_at": "2026-01-23T11:34:55Z",
                "starts_at": "2026-01-23T11:34:55Z",
                "opponents": ["Dewa United Banten", "Pacific Caesar Surabaya"],
                "markets": {
                  "p": {
                    "eo": {
                      "Dewa United Banten": { "w": { "": 1.02 } },
                      "Pacific Caesar Surabaya": { "w": { "": 8.20 } }
                    }
                  }
                },
                "scores": {
                  "Dewa United Banten": {
                    "p1": { "p": 25 },
                    "p2": { "p": 22 },
                    "p3": { "p": 19 },
                    "p4": { "p": 21 },
                    "e":  { "p": 87 },
                    "eo": { "p": 87 }
                  },
                  "Pacific Caesar Surabaya": {
                    "p1": { "p": 21 },
                    "p2": { "p": 18 },
                    "p3": { "p": 26 },
                    "p4": { "p": 17 },
                    "e":  { "p": 82 },
                    "eo": { "p": 82 }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}
Event fields
event_id — unique id of the event.
updated_at — when the event was updated according to our data (UTC).
starts_at — start time in UTC (may exist for Upcoming, may be absent).
Time zone: all timestamps are UTC.
opponents — array of opponents in the same order as on the bookmaker website.
markets — universal structure that describes supported markets (currently main markets only).
scores — live score structure (may be absent).
Rate limits
Rate limit: no more than 1 request per second.
Recommended polling: every 2–5 seconds for Live odds and every 30 seconds for Upcoming odds.
Markets
Markets are stored as JSON objects, where each “dimension” is a string key. Rate is a decimal number.
Group → Period → Target → Type → Edge = rate
Group what we measure
"p" points
Period time segment
"e" event regular time
"eo" event regular + overtime
"o" overtime
"o1" extra overtime 1
"o2" extra overtime 2
"h1" 1st half
"h2" 2nd half
"h2o" 2nd half + overtime
"p1" 1st period
"p2" 2nd period
"p3" 3rd period
"p4" 4th period
"p5" 5th period
"p6" 6th period
"p7" 7th period
"p8" 8th period
"p9" 9th period
"p4o" 4th period + overtime
Target who the market belongs to
"Dallas" opponent name
"" whole event
Type market type
"w" win
"d" draw
"h" handicap
"to" total over
"tu" total under
Edge line/threshold
"-10.5" handicap example
"35.0" integer edge rendered with .0
"" no edge needed
Examples (key format)
Format: {"Group"}{"Period"}{"Target"}{"Type"}{"Edge"} = rate
{"p"}{"m"}{"Dallas"}{"h"}{"-10.5"} = 1.85
Points, match, Dallas, handicap -10.5, rate 1.85
{"p"}{"mo"}{"Dallas"}{"w"}{""} = 2.1
Points, match + overtime, Dallas win, rate 2.10
{"p"}{"m"}{""}{"d"}{""} = 2
Points, match, whole event, draw, rate 2.00
{"p"}{"mo"}{""}{"to"}{"155.5"} = 1.85
Points, match + overtime, whole event, total over 155.5, rate 1.85
{"p"}{"q1"}{""}{"tu"}{"35.0"} = 1.75
Points, Q1, whole event, total under 35.0, rate 1.75
{"p"}{"h1"}{"Dallas"}{"to"}{"90.5"} = 1.9
Points, H1, Dallas team total over 90.5, rate 1.90
Note: {""} is a valid key meaning “not specified”.
Score
Score is stored as JSON objects where the root key is the Target (opponent name), then the Period, then the Unit.
Target → Period → Unit = value
Unit what value means
"p" Points
"s" Sets
Period keys are the same as in Markets section (e, eo, o, p1..p9, ...). Score block may be absent if bookmaker does not provide live score.
Examples (Volleyball)
{
  "scores": {
    "Тайбей Ист Пауэр": {
      "e":  { "s": 1, "p": 80 },
      "p1": { "p": 23 },
      "p2": { "p": 25 },
      "p3": { "p": 19 },
      "p4": { "p": 13 }
    },
    "Таоюань Леопардс": {
      "e":  { "s": 2, "p": 84 },
      "p1": { "p": 25 },
      "p2": { "p": 19 },
      "p3": { "p": 25 },
      "p4": { "p": 15 }
    }
  }
}
Here e.s is sets won, e.p is total points across sets, and p1..p4.p are set points.
Examples (Basketball)
{
  "scores": {
    "Team A": {
      "e":  { "p": 87 },
      "eo": { "p": 92 },
      "o":  { "p": 5 },
      "p1": { "p": 25 },
      "p2": { "p": 22 },
      "p3": { "p": 19 },
      "p4": { "p": 21 }
    },
    "Team B": {
      "e":  { "p": 82 },
      "eo": { "p": 88 },
      "o":  { "p": 6 },
      "p1": { "p": 21 },
      "p2": { "p": 18 },
      "p3": { "p": 26 },
      "p4": { "p": 17 }
    }
  }
}
Here e.p is regular time total (p1..p4), o.p is overtime total, and eo.p is full time including overtime.
Errors
If request fails, server returns JSON with error object.
Error schema
{
  "error": {
    "code": "string",
    "message": "string",
    "details": { }
  }
}
"unauthorized" API key is invalid or disabled
"invalid_category" Invalid category. Use only Live or Upcoming
"invalid_discipline" Invalid discipline
"not_paid" No paid products / subscription is inactive
"rate_limit" Too many requests. Use updateVersion and request no more than allowed
"ip_locked" Requests are allowed only from the bound IP. If you try from a new IP, wait for the cooldown 1 minute and retry.
"server_error" Unexpected server error
Note: details may be omitted or may include fields like discipline / category.