A matched board
The six matched boards: each event's bookmaker back prices beside the exchanges' lay prices (dutching: back legs that cover every outcome, grouped by dutch_id; each-way and extra-place: each-way terms against win and place lays).
Checks, in this order (each refusal is free): the per-address shield, the key, the account's flood cap, a suspended account, a browser key's website, the API version; then type (404 unknown_type), region, the region in the key (403 region_not_in_scope), the product in the key (403 not_in_key_scope), the product in the region (403 product_not_in_region: a region with no exchange serves only dutching and raw); then the parameters: each one this route reads, once; format, oddsFormat and dateFormat values; on standard and dutching decimal ISO only and gzip accepted (400 add Accept-Encoding: gzip; with curl use --compressed); then the filters (400 unknown values, 403 bookmaker_not_in_region, then your account's scope: 403 sport_not_in_plan, market_not_in_plan, bookmaker_not_in_plan, exchange_not_in_plan; and your plan's bookmaker list), then quote=true, the price (402), and the board (503 while it is not ready).
Filters cut the whole board's events in order: sport and kick-off, then markets, then back offers by bookmaker and lay offers by exchange; an outcome left with no back or no lay goes, then empty markets and events. dutching keeps a dutch only when every leg is a named venue. A filtered reply is priced on its filters (/v2/pricing); the kick-off window is never priced.
Freshness: meta.processed_at and X-Processed-At are the board time; meta.last_seen is each venue and sport's last read. The API drops no row for age; a venue not read within its own window (at most two minutes) is off the board until its next read.
Conditional requests: send the ETag back as If-None-Match; an unchanged body is a 304 with no body, free. A reply with no events is free.
Request
- Base URL: https://api.oddsrelay.io
- URL: https://api.oddsrelay.io/v2/odds/{type}
- Auth: one of:
- HTTP bearer
- API key in header x-api-key
Path parameters
A matched board: standard, 2up, dutching, each-way, extra-place or bog. The aliases two-up, each_way and extra_place are accepted and served as their canonical slug. Anything else is 404 unknown_type.
Query parameters
ONE lowercase region code (/v2/regions lists yours). Missing means uk: on a data route only when your key covers uk, else 400 region_required naming a code your key has; on discovery and keyless routes always. A comma list, the parameter sent twice or an uppercase code is 400 bad_request; an unknown code, or one with no live bookmaker here, is 404 unknown_region.
envelope (default): {meta, data}. bare: the data array alone, meta moved to X-* headers.
decimal (default) or american (a signed integer; null for a price at or below 1.0). standard and dutching serve decimal only: anything else is 400.
iso (default, ISO-8601 UTC) or unix (integer epoch seconds) for commence_time, processed_at and last_update. standard and dutching serve iso only: anything else is 400.
true (also 1, yes, on): price this exact request instead of serving it. 200 {cost, remaining, rate_card}, free, every check before the price still applies; any other value is an ordinary request.
Comma-separated, at most 20: a sport key or a prefix of one as /v2/sports lists them (horse_racing, soccer), lowercased. A competition key (an event's competition_key, listed on /v2/sports) returns every event of that competition, whatever its venues call it. Any other key returns what it returned before, plus every event a venue files under a key it begins (each venue names its league its own way), and, when every event that key has ever named belongs to ONE competition, the rest of that competition. Unknown is 400 unknown_sport with valid (the sport key bases). A known value with nothing on the board is an empty 200, free. A value is inside your account's scope when it starts with a scope sport (every soccer_… key under soccer); outside, 403 sport_not_in_plan with valid; left out, trimmed to the scope.
Comma-separated, at most 40: bookmaker keys as /v2/bookmakers lists them (a listed name is accepted too). Unknown is 400 unknown_bookmaker with valid; an exchange here is that 400 naming exchanges (on dutching both lists take venues of either kind); a venue outside the region is 403 bookmaker_not_in_region; one outside your plan's bookmaker list or your account's scope is 403 bookmaker_not_in_plan with valid (on dutching, an exchange outside the scope is 403 exchange_not_in_plan). A plan with a bookmaker list, or an account scope, trims a call naming none to that list.
Comma-separated, at most 4: exchange keys as /v2/bookmakers lists them. Unknown is 400 unknown_exchange with valid; a bookmaker here is that 400 naming bookmakers. Outside your account's scope for this product: 403 exchange_not_in_plan with valid; left out, trimmed to the scope.
Comma-separated, at most 20: market keys (h2h, totals, …; /v2/sports rows list the keys seen under each competition). Each product's keys: keyless /v2/coverage's markets. Unknown is 400 unknown_market with valid (this product's keys) and, when another product carries it, products; another product's key may instead be accepted and match nothing. Outside your account's scope for this product: 403 market_not_in_plan with valid; left out, trimmed to the scope.
Events kicking off at or after this ISO-8601 instant (no offset = UTC; a fraction of a second rounds up). Not ISO-8601 is 400; on the matched boards a From after To is 400.
Events kicking off at or before this ISO-8601 instant (no offset = UTC).
Headers
Send gzip; with curl, --compressed sends it and decompresses the reply. standard and dutching answer a request that refuses gzip (identity alone, as Python's urllib sends by default, or gzip;q=0 or *;q=0) with 400 bad_request, message add Accept-Encoding: gzip; with curl use --compressed; the other four boards answer it plain.
Response
The board (envelope, or the data array under format=bare), or under quote=true the price. Gzip unless refused.
Changes
No recorded changes to this operation across all 1 revision of this API.