{"openapi":"3.1.0","info":{"title":"AU Odds API","description":"Australian sports and racing odds from 12 sources (11 bookmakers plus the Betfair exchange) in one API. Sports and racing are SEPARATE endpoint families: sports odds live under /v1/sports/{sport_key}/odds, and racing under /v1/racing/next-to-go and /v1/racing/events — there is no 'horse-racing' sport_key. \n\n**Two client settings worth more than any server tuning.** Send `Accept-Encoding: gzip` — responses are JSON and compress about 9x, and a caller that omits the header downloads roughly 55KB where 6KB would do. And reuse the connection (`requests.Session()` or `httpx.Client()`) — measured against this API, a cold TLS handshake costs 137ms versus 40.5ms on a reused connection, so connection reuse alone is a ~70% cut in observed latency. Neither can be fixed from our side.\n\n**Try every endpoint before you write code.** [The Postman collection](https://api.puntersedge.online/postman.json) ships 36 ready-to-run requests, grouped into folders, with query parameters pre-listed and switched off — paste that URL into Postman's Import → Link. Set the `apiKey` collection variable once and every authenticated request picks it up in the `X-API-Key` header; the Sandbox folder needs no key at all.\n\nCovering AFL, NRL, NBA, Tennis, Cricket, Rugby + AU horse racing, greyhounds, and harness.","termsOfService":"https://puntersedge.online/terms","contact":{"name":"PuntersEdge","url":"https://puntersedge.online/api-platform","email":"hello@puntersedge.online"},"license":{"name":"Proprietary — see Terms of Service","url":"https://puntersedge.online/terms"},"version":"1.0.0"},"paths":{"/v1/sports":{"get":{"tags":["Sports"],"summary":"List available sports","description":"Cost: 1 credit. Returns the active sports catalogue as an array of objects containing key, title, group and active fields.\n\nRacing is not in this catalogue. Horse, harness and greyhound racing have their own\nendpoints: GET /v1/racing/next-to-go and GET /v1/racing/events.","operationId":"list_sports_v1_sports_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SportOut"},"title":"Response List Sports V1 Sports Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sports/{sport_key}/odds":{"get":{"tags":["Sports"],"summary":"Get odds by sport","description":"Cost: 1 credit per requested market. Parameters: sport_key selects the sport (for example afl or nrl); markets is a comma-separated list such as h2h,spreads,totals; bookmakers optionally filters bookmaker keys; oddsFormat accepts decimal or american.\n\n`markets` is deduplicated and validated before billing, so a repeated market is charged\nonce and an unknown one is a free 422 rather than a paid empty list.\n\nThere is no racing sport_key. For horse, harness or greyhound racing use\nGET /v1/racing/next-to-go (2 credits) or GET /v1/racing/events instead — passing\n'horse-racing' here returns 404, because racing is a separate endpoint family.","operationId":"get_sport_odds_v1_sports__sport_key__odds_get","parameters":[{"name":"sport_key","in":"path","required":true,"schema":{"type":"string","title":"Sport Key"}},{"name":"markets","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated: h2h,spreads,totals","default":"h2h","title":"Markets"},"description":"Comma-separated: h2h,spreads,totals"},{"name":"bookmakers","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated bookmaker keys, or omit for all","title":"Bookmakers"},"description":"Comma-separated bookmaker keys, or omit for all"},{"name":"competition","in":"query","required":false,"schema":{"type":"string","description":"Filter to one competition, case-insensitive exact match (e.g. NRLW). A value this sport has never carried is a 422 listing the ones it has, not an empty 200 — see `include_unknown_competition` for why that distinction matters. See the `competition` field on each event.","title":"Competition"},"description":"Filter to one competition, case-insensitive exact match (e.g. NRLW). A value this sport has never carried is a 422 listing the ones it has, not an empty 200 — see `include_unknown_competition` for why that distinction matters. See the `competition` field on each event."},{"name":"include_unknown_competition","in":"query","required":false,"schema":{"type":"boolean","description":"When filtering by `competition`, ALSO return events whose competition is null — not every bookmaker supplies one, and on some sports most of the card is unlabelled (ncaaf 40 of 47 upcoming events, tennis_atp 21 of 72). Because of this the filter is 'this competition OR unlabelled', so a result set is not proof that the competition matched anything: an unrecognised value is rejected with 422 rather than answering with the unlabelled events alone. Set false for a strict exact match that returns only events explicitly labelled with this competition.","default":true,"title":"Include Unknown Competition"},"description":"When filtering by `competition`, ALSO return events whose competition is null — not every bookmaker supplies one, and on some sports most of the card is unlabelled (ncaaf 40 of 47 upcoming events, tennis_atp 21 of 72). Because of this the filter is 'this competition OR unlabelled', so a result set is not proof that the competition matched anything: an unrecognised value is rejected with 422 rather than answering with the unlabelled events alone. Set false for a strict exact match that returns only events explicitly labelled with this competition."},{"name":"oddsFormat","in":"query","required":false,"schema":{"type":"string","description":"decimal or american","default":"decimal","title":"Oddsformat"},"description":"decimal or american"},{"name":"maxAgeMinutes","in":"query","required":false,"schema":{"type":"integer","maximum":1440,"minimum":5,"description":"Exclude bookmaker markets older than this many minutes; default 360 allows 3-hour supplemental feeds while hiding multi-day stale prices.","default":360,"title":"Maxageminutes"},"description":"Exclude bookmaker markets older than this many minutes; default 360 allows 3-hour supplemental feeds while hiding multi-day stale prices."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SportOddsEventOut"},"title":"Response Get Sport Odds V1 Sports  Sport Key  Odds Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/racing/next-to-go":{"get":{"tags":["Racing"],"summary":"Next races to run","description":"Cost: 2 credits. Returns the next races to run with runners and prices; categories can filter horse, greyhound and harness racing.\n\n**Freshness is reported worst-first.** `data_age_seconds` is the age of the OLDEST bookmaker\nquote in the race and `stale` is true when that exceeds 120s, so the flag describes the\nstaleness you are exposed to rather than the best leg in the payload. `stale_bookmakers`\nnames the affected books, `freshest_age_seconds` is the best-case age, and every entry in\n`bookmakers` carries its own `age_seconds`, `last_update` and `stale`. A stale book does not\ninvalidate the race — drop that leg.\n\nScratched runners are returned in `scratchings` only. They are never in `runners`, even\nwhile a book is still publishing a price for them.\n\n**A foreign race is quoted by a single bookmaker.** Every non-Australian or unlabelled race\nin the feed carries exactly one book's price — median 1, maximum 1, no exceptions — so a\ncross-book comparison on them compares nothing. Pass `country=AU` for the meetings the\nbookmaker panel actually covers.\n\n**An Australian race gathers books as it approaches the jump**, so depth depends on how far\nout you look rather than sitting at one number. Measured 2026-08-17: a median of 10\nbookmakers inside 30 minutes of the jump, 9 at 30-60 minutes, 5 at one to two hours, and 2\nbeyond that. Since this endpoint returns the NEXT races, expect the near-jump end of that\nrange. A window-wide average is not meaningful here — it just tracks whichever mix of\nstart times happens to be loaded.\n\nHow much of the card is foreign is NOT a fixed ratio: `race_events` holds roughly the next\nsix hours, and the foreign share of that window runs near zero through the Australian\nafternoon and reaches 100% overnight. Filter on `country` rather than assuming a mix.\n\n**Form fields are patchy on both, and not in the direction you would guess.** Measured per\ndistinct runner on 2026-08-17, `trainer` and `form` were present on 38% of AU runners but\n100% of foreign ones, `barrier` 26% against 65%, `jockey` 20% against 35%. `weight` is the\nonly field that favours AU (18% against 0%). Race conditions — `distance_m`,\n`track_condition`, `weather` — are populated on both. Treat every form field as optional and\ncheck it, rather than inferring its presence from `country`.","operationId":"next_to_go_v1_racing_next_to_go_get","parameters":[{"name":"num_races","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Num Races"}},{"name":"categories","in":"query","required":false,"schema":{"type":"string","description":"horse,greyhound,harness or omit for all","title":"Categories"},"description":"horse,greyhound,harness or omit for all"},{"name":"bookmakers","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated bookmaker keys","title":"Bookmakers"},"description":"Comma-separated bookmaker keys"},{"name":"country","in":"query","required":false,"schema":{"type":"string","description":"ISO country codes, comma-separated (e.g. AU or AU,NZ). Omit for every country. A foreign or unlabelled race is quoted by a SINGLE bookmaker (median 1, maximum 1) at any range, while an Australian race gathers books toward the jump (median 10 inside 30 minutes, 2 at 2-4 hours), so a cross-book comparison on foreign races compares nothing; pass country=AU for the Australian meetings the bookmaker panel actually covers.","title":"Country"},"description":"ISO country codes, comma-separated (e.g. AU or AU,NZ). Omit for every country. A foreign or unlabelled race is quoted by a SINGLE bookmaker (median 1, maximum 1) at any range, while an Australian race gathers books toward the jump (median 10 inside 30 minutes, 2 at 2-4 hours), so a cross-book comparison on foreign races compares nothing; pass country=AU for the Australian meetings the bookmaker panel actually covers."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NextRaceOut"},"title":"Response Next To Go V1 Racing Next To Go Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/racing/events":{"get":{"tags":["Racing"],"summary":"Upcoming race list","description":"Cost: 1 credit. Returns upcoming race events within the requested time window, optionally filtered by racing category.","operationId":"race_events_v1_racing_events_get","parameters":[{"name":"hours_ahead","in":"query","required":false,"schema":{"type":"integer","maximum":24,"minimum":1,"default":4,"title":"Hours Ahead"}},{"name":"categories","in":"query","required":false,"schema":{"type":"string","title":"Categories"}},{"name":"country","in":"query","required":false,"schema":{"type":"string","description":"ISO country codes, comma-separated (e.g. AU). Omit for every country.","title":"Country"},"description":"ISO country codes, comma-separated (e.g. AU). Omit for every country."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RaceEventOut"},"title":"Response Race Events V1 Racing Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/racing/results":{"get":{"tags":["Racing"],"summary":"Settled race results","description":"Cost: 2 credits. Settled AU/NZ race results — finishing order with the bookmaker's own\nsettled fixed prices, plus scratchings and their deductions.\n\n`status` is `interim` until the placings have been stable for 30 minutes, then `final`.\nSettle only against `final`: an interim placing can still change on protest.\n\n`race_id` joins a result to /v1/racing/price-history, and to /v1/racing/next-to-go while the\nrace was still open — use it rather than matching on venue + race number + start time.\n\n`dividends` carries the declared win/place dividends per placegetter per product and the\nexotic dividends (quinella, exacta, trifecta, first four), each as a return on a $1 stake.\nExotics are declared a few minutes after the placings, so they land on a later poll than the\nresult itself — see the field description for the full shape.\n\n**Coverage:** results collection began 2026-08-15, so `hours_back` cannot reach further than\nthat no matter what you pass. Every row carries `coverage_from`, the earliest result\ncurrently retained, so an empty window is distinguishable from an unsupported one.","operationId":"race_results_v1_racing_results_get","parameters":[{"name":"hours_back","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"description":"How far back to look, in hours (max 7 days)","default":24,"title":"Hours Back"},"description":"How far back to look, in hours (max 7 days)"},{"name":"categories","in":"query","required":false,"schema":{"type":"string","description":"horse,greyhound,harness or omit for all","title":"Categories"},"description":"horse,greyhound,harness or omit for all"},{"name":"venue","in":"query","required":false,"schema":{"type":"string","description":"Case-insensitive venue match, e.g. 'Rosehill'","title":"Venue"},"description":"Case-insensitive venue match, e.g. 'Rosehill'"},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Filter to 'final' or 'interim'","title":"Status"},"description":"Filter to 'final' or 'interim'"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RaceResultOut"},"title":"Response Race Results V1 Racing Results Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/racing/price-history":{"get":{"tags":["Racing"],"summary":"Racing price history / closing line","description":"Cost: 5 credits. Every price move for a race, per runner per bookmaker, with the opening\nand closing line.\n\nIdentify the race either by `race_id`, or by `venue` + `race_number` + `date` — use the latter\nfor past races, because race ids are only resolvable from the live feed, which holds the next\n~6 hours.\n\n**The series is change-only.** Each point is a price MOVE, not a sample: a gap means the price\nheld steady. `move_pct` is open→close, positive meaning the price drifted out.\n\n**`open_price` and `close_price` are the first and last CAPTURED prices for that book, not\nguaranteed market open and close.** Capture starts when a race enters the 60-minute window,\nand a book that does not quote that early gets its first price whenever it starts quoting:\nmeasured over 30,448 series on 2026-08-15, 44% of series began at the 60-minute baseline and\n56% began later. At the other end 63% of series have a final point inside 120s of the jump\nand 81% inside 300s, so the rest are not closing lines either. Read `open_secs_to_jump`,\n`close_secs_to_jump` and `open_is_baseline` on each bookmaker before using a series for\nclosing-line value, and drop the ones that do not reach the jump.\n\nHistory goes back to `history_from` on the response. The retention target is 45 days but\ncapture began 2026-08-04, so the store is younger than that and grows daily.","operationId":"price_history_v1_racing_price_history_get","parameters":[{"name":"race_id","in":"query","required":false,"schema":{"type":"string","description":"Race id. If omitted, give venue + race_number + date.","title":"Race Id"},"description":"Race id. If omitted, give venue + race_number + date."},{"name":"venue","in":"query","required":false,"schema":{"type":"string","description":"Venue name, case-insensitive (with race_number + date)","title":"Venue"},"description":"Venue name, case-insensitive (with race_number + date)"},{"name":"race_number","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"title":"Race Number"}},{"name":"date","in":"query","required":false,"schema":{"type":"string","description":"Race date, YYYY-MM-DD (UTC)","title":"Date"},"description":"Race date, YYYY-MM-DD (UTC)"},{"name":"bookmakers","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated bookmaker keys","title":"Bookmakers"},"description":"Comma-separated bookmaker keys"},{"name":"include_points","in":"query","required":false,"schema":{"type":"boolean","description":"False returns open/close/high/low only","default":true,"title":"Include Points"},"description":"False returns open/close/high/low only"},{"name":"max_points","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":100,"description":"Cap on returned points; response flags truncation","default":5000,"title":"Max Points"},"description":"Cap on returned points; response flags truncation"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceHistoryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"x-curl-query":"race_id=YOUR_RACE_ID"}},"/v1/racing/movers":{"get":{"tags":["Racing"],"summary":"Racing steamers and drifters","description":"Cost: 3 credits. Runners whose price has moved materially since the market opened,\nacross upcoming races.\n\n`move_pct` is **negative for a firming runner** (the price shortened — money has arrived)\nand positive for a drifter.\n\n`open_price` is the FIRST PRICE CAPTURED inside the 60-minute pre-race window, not a market\nopen. Capture begins when the race enters that window, so a book that does not quote 60\nminutes out (palmerbet, pointsbetau, tabtouch, playup, ladbrokes_au, neds) starts wherever it\nstarted quoting — `open_secs_to_jump` on each bookmaker row says how far out that was.\n\nA move is reported at the RUNNER level and only when at least `min_books` bookmakers have\n**two or more captured prices**, because a book seen only once has evidenced nothing: its\nopen equals its current by construction. Those books are still listed, with `points: 1` and\n`counted_in_consensus: false`, and still counted in `books_quoting` — but they do not enter\nthe consensus or the gate. Use `books_with_history` as the confirmation count.","operationId":"racing_movers_v1_racing_movers_get","parameters":[{"name":"direction","in":"query","required":false,"schema":{"type":"string","description":"firming, drifting, or omit for both","title":"Direction"},"description":"firming, drifting, or omit for both"},{"name":"min_move_pct","in":"query","required":false,"schema":{"type":"number","maximum":90.0,"minimum":1.0,"description":"Minimum consensus move, percent","default":10.0,"title":"Min Move Pct"},"description":"Minimum consensus move, percent"},{"name":"min_books","in":"query","required":false,"schema":{"type":"integer","maximum":12,"minimum":1,"description":"Only report a move confirmed by at least this many books","default":3,"title":"Min Books"},"description":"Only report a move confirmed by at least this many books"},{"name":"categories","in":"query","required":false,"schema":{"type":"string","description":"horse,greyhound,harness or omit for all","title":"Categories"},"description":"horse,greyhound,harness or omit for all"},{"name":"country","in":"query","required":false,"schema":{"type":"string","description":"ISO country codes, comma-separated (e.g. AU). Omit for every country.","title":"Country"},"description":"ISO country codes, comma-separated (e.g. AU). Omit for every country."},{"name":"max_mins_to_jump","in":"query","required":false,"schema":{"type":"integer","maximum":360,"minimum":5,"default":360,"title":"Max Mins To Jump"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MoverOut"},"title":"Response Racing Movers V1 Racing Movers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/racing/best-odds":{"get":{"tags":["Racing"],"summary":"Best racing price per runner across books","description":"Cost: 3 credits. The best win, place and tote price for every runner in the next races,\nwith the bookmaker offering it and a deep link to their race page.\n\n`market_percentage` is the sum of implied probabilities at the best available price. **Under\n100 means the best prices across books beat the field** — a cross-book arbitrage. Any single\nbook's market is always over 100.\n\n`price_spread_pct` per runner is how much better the best price is than the worst currently\nquoted: how much a punter loses by not shopping around.\n\n⚠️ `best_tote` is **not comparable to `best_win`**. A pre-race tote dividend is an estimate\nthat moves as the pool fills, and taking the highest across books and products is upward\nbiased by construction — the noisiest estimate wins. Greyhound pools are thinnest and swing\nhardest: measured 2026-08-15, greyhound tote-to-fixed ratios reached 8.8x on betright and\n9.9x on tabtouch, against averages near 1.0 for horse and harness. A tote figure far above\nthe fixed price is usually a thin pool, not an edge. Settle against a FINAL dividend, and\nread the `product` code — `PROV` is indicative, `SP`/`MIDDIV`/`RD+`/`BT+SP` are named\nproducts.\n\nThe comparison covers the Australian fixed-odds bookmakers. Betfair Exchange prices are\nwithheld pending a Betfair Exchange data licence, and non-AU reference books are excluded\nbecause an Australian punter cannot bet them — so `betfair_ex_au` never appears as a\n`best_win` bookmaker, and `market_percentage` is the fixed-odds market rather than an\nexchange-inclusive one.\n\n**Scratched runners are never priced here.** They appear in `scratchings` only, and are left\nout of `market_percentage`.\n\n**Every published price carries its own age.** `best_win`, `best_place` and `best_tote` each\ninclude `last_update`, `age_seconds` and `stale`, because the book with the best price is not\nalways the book that answered most recently. Race level, `data_age_seconds` is the oldest of\nthose winning quotes and `stale_bookmakers` names any past 120s. Responses are cached for 20s\nand say so via `cached` / `cache_age_seconds`; ages are recomputed at serve time, so a cached\npayload reports its real age rather than the age it had when it was stored.","operationId":"racing_best_odds_v1_racing_best_odds_get","parameters":[{"name":"num_races","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Num Races"}},{"name":"categories","in":"query","required":false,"schema":{"type":"string","description":"horse,greyhound,harness or omit for all","title":"Categories"},"description":"horse,greyhound,harness or omit for all"},{"name":"bookmakers","in":"query","required":false,"schema":{"type":"string","description":"Restrict the comparison to these bookmaker keys","title":"Bookmakers"},"description":"Restrict the comparison to these bookmaker keys"},{"name":"country","in":"query","required":false,"schema":{"type":"string","description":"ISO country codes, comma-separated (e.g. AU). Omit for every country. Foreign races are quoted by a median of one book, so a cross-book comparison on them compares nothing.","title":"Country"},"description":"ISO country codes, comma-separated (e.g. AU). Omit for every country. Foreign races are quoted by a median of one book, so a cross-book comparison on them compares nothing."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RacingBestOddsOut"},"title":"Response Racing Best Odds V1 Racing Best Odds Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/best-odds/{sport_key}":{"get":{"tags":["Best Odds"],"summary":"Best price per selection","description":"Cost: 3 credits. Returns the best available price per selection for upcoming events, including arb_exists and arb_profit_pct when the best prices create an arbitrage margin.\n\nAn unknown `sport_key` returns 404 and costs nothing.","operationId":"best_odds_v1_best_odds__sport_key__get","parameters":[{"name":"sport_key","in":"path","required":true,"schema":{"type":"string","title":"Sport Key"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BestOddsEventOut"},"title":"Response Best Odds V1 Best Odds  Sport Key  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/usage":{"get":{"tags":["Account"],"summary":"Check API usage","description":"Free — 0 credits deducted. Returns credit usage, endpoint breakdown and recent activity.","operationId":"usage_v1_usage_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/billing/portal":{"get":{"tags":["Account"],"summary":"Self-service billing portal link","description":"Cost: 0 credits. Returns a short-lived Stripe billing portal URL for this key's\nsubscription: update the card, download invoices, see what the next charge will be.\n\nTHE API KEY IS THE IDENTITY. The website has its own portal at /account, but it needs a\nwebsite login and reads a stripe_customer_id out of the website's own subscriptions table.\nA customer who subscribed through this API has neither — they never registered on the\nwebsite, and their customer id lives on their api_keys row. Before this endpoint the only\nway for them to change a failing card was to email us, which is how a subscription is lost\nto an expired card rather than a decision.\n\nThe returned URL is a BEARER link: anyone holding it can manage the subscription until it\nexpires. It is deliberately never logged, and callers should not paste it anywhere.","operationId":"billing_portal_v1_billing_portal_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/health":{"get":{"tags":["Account"],"summary":"Connector health status","description":"Requires auth. Shows last_ok, status, records_written per connector.","operationId":"connector_health_v1_health_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConnectorHealthOut"},"title":"Response Connector Health V1 Health Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/uptime":{"get":{"tags":["Account"],"summary":"Public uptime stats","description":"Public uptime stats — no auth required.","operationId":"uptime_stats_v1_uptime_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/keys":{"post":{"tags":["Account"],"summary":"Create a new API key (admin only)","description":"Create a new API key. Admin only.","operationId":"create_key_v1_keys_post","parameters":[{"name":"label","in":"query","required":false,"schema":{"type":"string","default":"My Key","title":"Label"}},{"name":"plan","in":"query","required":false,"schema":{"type":"string","default":"free","title":"Plan"}},{"name":"email","in":"query","required":false,"schema":{"type":"string","title":"Email"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/keys/rotate":{"post":{"tags":["Account"],"summary":"Rotate your API key","description":"Issue a new API key. The old key keeps working for a short grace window so a\nmulti-process caller can roll over without an outage; pass immediate=true to kill it now.\nCost: 0 credits.","operationId":"rotate_key_v1_keys_rotate_post","parameters":[{"name":"immediate","in":"query","required":false,"schema":{"type":"boolean","description":"Revoke the old key NOW instead of after the grace window. Use this when rotating because the key leaked — a grace window keeps a compromised credential alive and is the wrong default for that case.","default":false,"title":"Immediate"},"description":"Revoke the old key NOW instead of after the grace window. Use this when rotating because the key leaked — a grace window keeps a compromised credential alive and is the wrong default for that case."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/keys/info":{"get":{"tags":["Account"],"summary":"API key metadata","description":"Returns metadata about the authenticated key including plan, credits, org, and last-used info.","operationId":"key_info_v1_keys_info_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/keys/ip-whitelist":{"post":{"tags":["Account"],"summary":"Set IP whitelist for your key","description":"Cost: 0 credits. Restrict this key to specific IPs or CIDR ranges. Available on Pro,\nEnterprise and Unlimited; other plans get 403. Pass an empty list to remove restrictions.","operationId":"set_ip_whitelist_v1_keys_ip_whitelist_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"description":"IPv4/IPv6 addresses or CIDR ranges. A bare address is stored as a /32 (or /128). Send an empty list to remove all restrictions.","examples":[["203.0.113.7/32","198.51.100.0/24"]],"title":"Cidrs"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"403":{"description":"IP whitelisting requires a Pro, Enterprise or Unlimited plan."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/usage/analytics":{"get":{"tags":["Account"],"summary":"Usage breakdown by endpoint","description":"Cost: 0 credits. Returns credit usage grouped by endpoint over the last N days.","operationId":"usage_analytics_v1_usage_analytics_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/signup":{"post":{"tags":["Signup"],"summary":"Create API key or start paid checkout","description":"Sign up for an API key.\n- free: returns key immediately\n- paid: returns Stripe checkout URL, key created on webhook","operationId":"signup_v1_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/arb/sports":{"get":{"tags":["Arb & Value"],"summary":"Sports arb scanner","description":"Cost: 3 credits. Scans upcoming sports markets for true arbitrage and best-odds overlay opportunities, returning arb_pct, optimal stakes and per-selection price comparisons.","operationId":"sports_arb_v1_arb_sports_get","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"type":"string","description":"Filter by sport e.g. afl, nrl","title":"Sport Key"},"description":"Filter by sport e.g. afl, nrl"},{"name":"min_profit_pct","in":"query","required":false,"schema":{"type":"number","description":"Min guaranteed profit % (0 = show all value)","default":0.0,"title":"Min Profit Pct"},"description":"Min guaranteed profit % (0 = show all value)"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SportsArbOut"},"title":"Response Sports Arb V1 Arb Sports Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/arb/best-prices":{"get":{"tags":["Arb & Value"],"summary":"Best prices comparison","description":"Cost: 2 credits. Returns the best available price per selection plus full bookmaker comparison, worst price, average price, spread and overlay percentage.","operationId":"best_prices_v1_arb_best_prices_get","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"type":"string","default":"nrl","title":"Sport Key"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BestPricesOut"},"title":"Response Best Prices V1 Arb Best Prices Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/arb/lines":{"get":{"tags":["Arb & Value"],"summary":"Spreads/totals line arb","description":"Cost: 3 credits. Line-matched arbitrage on spreads and totals: backs the two opposing sides\nat complementary lines across books. Returns the best complementary pair per event/market with a\nguaranteed-profit (is_arb) flag; is_middle marks overlapping lines where both sides can win.","operationId":"lines_arb_v1_arb_lines_get","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"type":"string","description":"Filter by sport e.g. afl, nrl","title":"Sport Key"},"description":"Filter by sport e.g. afl, nrl"},{"name":"min_profit_pct","in":"query","required":false,"schema":{"type":"number","description":"Min guaranteed profit % (0 = also show the best line comparison when not an arb)","default":0.0,"title":"Min Profit Pct"},"description":"Min guaranteed profit % (0 = also show the best line comparison when not an arb)"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LinesArbOut"},"title":"Response Lines Arb V1 Arb Lines Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ingest/{bookmaker_key}":{"post":{"tags":["ingest"],"summary":"Ingest Prices","description":"Push race+price data from an external source (e.g. Mac-side browser scraper).\nOverwrites existing data for this bookmaker_key. Trusted/admin keys only —\nthis writes to the price feed and must not be open to ordinary keys.","operationId":"ingest_prices_v1_ingest__bookmaker_key__post","parameters":[{"name":"bookmaker_key","in":"path","required":true,"schema":{"type":"string","title":"Bookmaker Key"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestPayload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ingest/sports/{bookmaker_key}":{"post":{"tags":["ingest"],"summary":"Ingest Sport Prices","description":"Push sports H2H (and spreads/totals) prices from an external source — e.g. the\nMac-side Sportsbet feed, since Sportsbet IP-blocks the VPS. Trusted/admin keys only.\nRuns through the same canonical matching + data-quality pipeline as direct connectors.","operationId":"ingest_sport_prices_v1_ingest_sports__bookmaker_key__post","parameters":[{"name":"bookmaker_key","in":"path","required":true,"schema":{"type":"string","title":"Bookmaker Key"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SportIngestPayload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks":{"post":{"tags":["Webhooks"],"summary":"Create Webhook","operationId":"create_webhook_v1_webhooks_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"403":{"description":"Webhooks require a Pro or higher plan."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["Webhooks"],"summary":"List Webhooks","operationId":"list_webhooks_v1_webhooks_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookResponse"},"title":"Response List Webhooks V1 Webhooks Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{webhook_id}":{"delete":{"tags":["Webhooks"],"summary":"Delete Webhook","operationId":"delete_webhook_v1_webhooks__webhook_id__delete","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{webhook_id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"List Webhook Deliveries","operationId":"list_webhook_deliveries_v1_webhooks__webhook_id__deliveries_get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryResponse"},"title":"Response List Webhook Deliveries V1 Webhooks  Webhook Id  Deliveries Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{webhook_id}/test":{"post":{"tags":["Webhooks"],"summary":"Test Webhook","operationId":"test_webhook_v1_webhooks__webhook_id__test_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sports/{sport_key}/odds/history":{"get":{"tags":["Sports"],"summary":"Historical odds snapshots","description":"Cost: 5 credits. Pro/Pro Plus/Growth/Enterprise/Unlimited only.\n\nAn unknown `sport_key`, or a date range that runs backwards, returns an error and costs\nnothing.","operationId":"get_odds_history_v1_sports__sport_key__odds_history_get","parameters":[{"name":"sport_key","in":"path","required":true,"schema":{"type":"string","title":"Sport Key"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date/time; defaults to 7 days ago","title":"From"},"description":"ISO date/time; defaults to 7 days ago"},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date/time; defaults to now","title":"To"},"description":"ISO date/time; defaults to now"},{"name":"bookmakers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated bookmaker keys","title":"Bookmakers"},"description":"Comma-separated bookmaker keys"},{"name":"market","in":"query","required":false,"schema":{"type":"string","description":"Market type, default h2h","default":"h2h","title":"Market"},"description":"Market type, default h2h"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sports/{sport_key}/odds/movements":{"get":{"tags":["Sports"],"summary":"Price movement feed","description":"Cost: 5 credits. Returns detected home/draw/away price movements from historical snapshots.\n\nAn unknown `sport_key` returns 404 and costs nothing.","operationId":"get_odds_movements_v1_sports__sport_key__odds_movements_get","parameters":[{"name":"sport_key","in":"path","required":true,"schema":{"type":"string","title":"Sport Key"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date/time; defaults to 24 hours ago","title":"Since"},"description":"ISO date/time; defaults to 24 hours ago"},{"name":"bookmakers","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated bookmaker keys","title":"Bookmakers"},"description":"Comma-separated bookmaker keys"},{"name":"market","in":"query","required":false,"schema":{"type":"string","default":"h2h","title":"Market"}},{"name":"min_delta","in":"query","required":false,"schema":{"type":"number","minimum":0.0,"default":0.01,"title":"Min Delta"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/markets/popular":{"get":{"tags":["Markets"],"summary":"Popular recreational markets","description":"Cost: 1 credit. Upcoming h2h selections priced in [min_odds, max_odds] at an\nAU-bettable book — recreational markets for camouflage betting (not value).\n\nAn unknown `sport_key` returns 404 and costs nothing.","operationId":"popular_markets_v1_markets_popular_get","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to one sport","title":"Sport Key"},"description":"filter to one sport"},{"name":"min_odds","in":"query","required":false,"schema":{"type":"number","minimum":1.01,"default":1.5,"title":"Min Odds"}},{"name":"max_odds","in":"query","required":false,"schema":{"type":"number","minimum":1.01,"default":4.0,"title":"Max Odds"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":40,"title":"Limit"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PopularMarketOut"},"title":"Response Popular Markets V1 Markets Popular Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/health/connectors":{"get":{"tags":["Health"],"summary":"Per-connector freshness","description":"Cost: 1 credit. Per-scraper last-success age + a stale flag, so a silently\nstalled feed (the root cause of phantom arbs) is visible.","operationId":"connectors_v1_health_connectors_get","parameters":[{"name":"stale_after_s","in":"query","required":false,"schema":{"type":"number","description":"age (s) past which a connector is 'stale'","default":180.0,"title":"Stale After S"},"description":"age (s) past which a connector is 'stale'"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Connectors V1 Health Connectors Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/demo/racing/next-to-go":{"get":{"tags":["Sandbox (no key)"],"summary":"Sample next-to-go races (no key required)","description":"Public teaser: next 3 races, up to 5 runners each, best 3 bookmaker prices. No API key. Cached 30s, 30 req/min per IP.","operationId":"demo_racing_v1_demo_racing_next_to_go_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/demo/best-odds":{"get":{"tags":["Sandbox (no key)"],"summary":"Sample best-odds + arb detection (no key required)","description":"Public teaser: best price per selection + arb flag for up to 3 upcoming events. No API key. Cached 45s, 30 req/min per IP.","operationId":"demo_best_odds_v1_demo_best_odds_get","parameters":[{"name":"sport","in":"query","required":false,"schema":{"type":"string","description":"Optional sport_key; auto-picks a live sport if omitted","title":"Sport"},"description":"Optional sport_key; auto-picks a live sport if omitted"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/demo/book-sport":{"get":{"tags":["Sandbox (no key)"],"summary":"Live book+sport snapshot (no key; powers SEO page differentiation)","description":"Public, book-specific live odds for one sport. Truncated to a few events/races. Cached 90s.","operationId":"demo_book_sport_v1_demo_book_sport_get","parameters":[{"name":"book","in":"query","required":true,"schema":{"type":"string","description":"bookmaker slug e.g. sportsbet","title":"Book"},"description":"bookmaker slug e.g. sportsbet"},{"name":"sport","in":"query","required":true,"schema":{"type":"string","description":"sport slug e.g. afl or horse-racing","title":"Sport"},"description":"sport slug e.g. afl or horse-racing"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/data-quality/summary":{"get":{"tags":["Data Quality"],"summary":"Data quality summary","description":"Cost: 1 credit. Summary of connector freshness, canonical mappings and recent audit status.","operationId":"data_quality_summary_v1_data_quality_summary_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/data-quality/audit/run":{"post":{"tags":["Data Quality"],"summary":"Run bookmaker audit","description":"Admin/enterprise only. Runs source-vs-API audit now.","operationId":"run_audit_endpoint_v1_data_quality_audit_run_post","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"type":"string","default":"nrl","title":"Sport Key"}},{"name":"market","in":"query","required":false,"schema":{"type":"string","default":"h2h","title":"Market"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/data-quality/audit/latest":{"get":{"tags":["Data Quality"],"summary":"Latest bookmaker audits","operationId":"latest_audits_v1_data_quality_audit_latest_get","parameters":[{"name":"sport_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sport Key"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/data-quality/audit/{run_id}/results":{"get":{"tags":["Data Quality"],"summary":"Audit result detail","operationId":"audit_results_v1_data_quality_audit__run_id__results_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/value/promos":{"get":{"tags":["Promo & Value"],"summary":"Daily promo value board","description":"Cost: 2 credits. Ranked daily promo plays per book with EV per $1 (gubbing-penalised).\nPromos flagged is_template are representative seeds — verify live terms before staking.\nRacing promos are value/tips only; the engine never auto-stakes them.","operationId":"promos_board_v1_value_promos_get","parameters":[{"name":"book","in":"query","required":false,"schema":{"type":"string","description":"Filter by bookmaker key","title":"Book"},"description":"Filter by bookmaker key"},{"name":"type","in":"query","required":false,"schema":{"type":"string","description":"Filter by promo type","title":"Type"},"description":"Filter by promo type"},{"name":"min_ev","in":"query","required":false,"schema":{"type":"number","description":"Min EV uplift per $1","title":"Min Ev"},"description":"Min EV uplift per $1"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string","title":"X-Api-Key"}},{"name":"X-RapidAPI-Proxy-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Rapidapi-Proxy-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PromoOut"},"title":"Response Promos Board V1 Value Promos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Unexpected server error. Safe to retry with backoff.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"BestOddsEventOut":{"properties":{"id":{"type":"string","title":"Id"},"sport_key":{"type":"string","title":"Sport Key"},"home_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Team"},"away_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Away Team"},"commence_time":{"type":"string","title":"Commence Time"},"selections":{"items":{"type":"object"},"type":"array","title":"Selections"},"arb_exists":{"type":"boolean","title":"Arb Exists"},"arb_profit_pct":{"type":"number","title":"Arb Profit Pct"},"data_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Age Seconds"},"freshest_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freshest Age Seconds"},"stale":{"type":"boolean","title":"Stale","default":false},"stale_bookmakers":{"items":{"type":"string"},"type":"array","title":"Stale Bookmakers","default":[]}},"type":"object","required":["id","sport_key","home_team","away_team","commence_time","selections","arb_exists","arb_profit_pct"],"title":"BestOddsEventOut","example":{"arb_exists":false,"arb_profit_pct":0.0,"away_team":"Storm","commence_time":"2026-06-07T09:30:00Z","home_team":"Broncos","id":"event_123","selections":[{"best_bookmaker":"sportsbet","best_price":2.1,"name":"Broncos"}],"sport_key":"nrl"}},"BestPricesOut":{"properties":{"id":{"type":"string","title":"Id"},"sport_key":{"type":"string","title":"Sport Key"},"home_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Team"},"away_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Away Team"},"commence_time":{"type":"string","title":"Commence Time"},"selections":{"items":{"type":"object"},"type":"array","title":"Selections"}},"type":"object","required":["id","sport_key","home_team","away_team","commence_time","selections"],"title":"BestPricesOut","example":{"away_team":"Storm","commence_time":"2026-06-07T09:30:00Z","home_team":"Broncos","id":"event_123","selections":[{"best_price":2.1,"name":"Broncos","price_spread":0.12}],"sport_key":"nrl"}},"ConnectorHealthOut":{"properties":{"connector":{"type":"string","title":"Connector"},"last_ok":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Ok"},"last_poll":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Poll"},"status":{"type":"string","title":"Status"},"records_written":{"type":"integer","title":"Records Written"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["connector","last_ok","status","records_written"],"title":"ConnectorHealthOut","example":{"connector":"sportsbet","last_ok":"2026-06-07T02:20:00","records_written":128,"status":"ok"}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IngestPayload":{"properties":{"bookmaker_key":{"type":"string","title":"Bookmaker Key"},"races":{"items":{"$ref":"#/components/schemas/RaceIn"},"type":"array","title":"Races"}},"type":"object","required":["bookmaker_key","races"],"title":"IngestPayload"},"LinesArbOut":{"properties":{"event_id":{"type":"string","title":"Event Id"},"sport_key":{"type":"string","title":"Sport Key"},"home_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Team"},"away_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Away Team"},"commence_time":{"type":"string","title":"Commence Time"},"market_type":{"type":"string","title":"Market Type"},"opportunities":{"items":{"type":"object"},"type":"array","title":"Opportunities"}},"type":"object","required":["event_id","sport_key","home_team","away_team","commence_time","market_type","opportunities"],"title":"LinesArbOut","example":{"away_team":"Magpies","commence_time":"2026-06-07T09:30:00Z","event_id":"event_123","home_team":"Lions","market_type":"totals","opportunities":[{"arb_pct":1.3,"is_arb":true,"is_middle":true,"optimal_stakes":[],"side_a":{"bookmaker":"sportsbet","name":"Over","point":38.5,"price":1.95},"side_b":{"bookmaker":"tab","name":"Under","point":39.5,"price":1.98}}],"sport_key":"afl"}},"MarketIn":{"properties":{"market_type":{"type":"string","title":"Market Type","default":"h2h"},"selections":{"items":{"$ref":"#/components/schemas/SelectionIn"},"type":"array","title":"Selections"}},"type":"object","required":["selections"],"title":"MarketIn"},"MoverOut":{"properties":{"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"start_time":{"type":"string","title":"Start Time"},"mins_to_jump":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mins To Jump"},"runner":{"type":"string","title":"Runner"},"number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number"},"direction":{"type":"string","title":"Direction"},"open_price":{"type":"number","title":"Open Price"},"current_price":{"type":"number","title":"Current Price"},"move_pct":{"type":"number","title":"Move Pct"},"books_quoting":{"type":"integer","title":"Books Quoting","description":"Books with a price for this runner, including ones we have never observed move."},"books_with_history":{"type":"integer","title":"Books With History","description":"Books with two or more captured prices — the only ones that can evidence a move. The consensus and the `min_books` gate use THIS count, not `books_quoting`."},"books_firming":{"type":"integer","title":"Books Firming"},"books_drifting":{"type":"integer","title":"Books Drifting"},"books_unchanged":{"type":"integer","title":"Books Unchanged","description":"Books whose captured price has not moved, including books seen only once. books_firming + books_drifting + books_unchanged == books_quoting."},"bookmakers":{"items":{"type":"object"},"type":"array","title":"Bookmakers"}},"type":"object","required":["venue","race_number","category","country","start_time","runner","direction","open_price","current_price","move_pct","books_quoting","books_with_history","books_firming","books_drifting","books_unchanged","bookmakers"],"title":"MoverOut","example":{"bookmakers":[{"counted_in_consensus":true,"current_price":9.0,"key":"betright","move_pct":-18.18,"open_price":11.0,"open_secs_to_jump":3597,"points":4}],"books_drifting":0,"books_firming":9,"books_quoting":10,"books_unchanged":1,"books_with_history":9,"category":"horse","country":"AU","current_price":9.17,"direction":"firming","mins_to_jump":3,"move_pct":-18.3,"number":10,"open_price":11.22,"race_number":8,"runner":"Magnaburma","start_time":"2026-08-15T08:52:00Z","venue":"Broome"}},"NextRaceOut":{"properties":{"race_id":{"type":"string","title":"Race Id"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"start_time":{"type":"string","title":"Start Time"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"race_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Race Name"},"distance_m":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Distance M"},"track_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Track Condition"},"weather":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Weather"},"places_paid":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Places Paid"},"scratchings":{"items":{"type":"object"},"type":"array","title":"Scratchings","default":[]},"runners":{"items":{"type":"object"},"type":"array","title":"Runners"},"data_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Age Seconds","description":"Age in seconds of the OLDEST bookmaker quote in this race — the staleness you are exposed to if you act on any price here. Since 2026-08-15 this is the worst leg, not the freshest; `freshest_age_seconds` carries the best-case figure."},"freshest_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freshest Age Seconds","description":"Age in seconds of the freshest bookmaker quote in this race."},"stale":{"type":"boolean","title":"Stale","description":"True when the oldest contributing bookmaker is older than 120s (racing polls every 8-20s per book, so 120s means a book has stopped). It does NOT mean the whole race is dead — read `stale_bookmakers` and each bookmaker's own `stale`/`age_seconds`.","default":false},"stale_bookmakers":{"items":{"type":"string"},"type":"array","title":"Stale Bookmakers","description":"Bookmaker keys in this race whose quote is older than 120s."},"cached":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cached"},"cache_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Age Seconds"}},"type":"object","required":["race_id","source_id","venue","race_number","category","start_time","country","runners"],"title":"NextRaceOut","example":{"category":"horse","country":"AU","race_id":"race_123","race_number":4,"runners":[{"bookmakers":[{"key":"sportsbet","win_price":3.2}],"name":"Example Runner","number":1}],"source_id":"src_a1b2c3d4e5","start_time":"2026-06-07T04:10:00Z","venue":"Eagle Farm"}},"PopularMarketOut":{"properties":{"event":{"type":"string","title":"Event"},"selection":{"type":"string","title":"Selection"},"odds":{"type":"number","title":"Odds"},"book":{"type":"string","title":"Book"},"sport":{"type":"string","title":"Sport"},"commence_time":{"type":"string","title":"Commence Time"}},"type":"object","required":["event","selection","odds","book","sport","commence_time"],"title":"PopularMarketOut","example":{"book":"sportsbet","commence_time":"2026-06-20T09:30:00Z","event":"Broncos v Storm","odds":1.85,"selection":"Broncos","sport":"nrl"}},"PriceHistoryOut":{"properties":{"race_id":{"type":"string","title":"Race Id"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"start_time":{"type":"string","title":"Start Time"},"points_returned":{"type":"integer","title":"Points Returned"},"truncated":{"type":"boolean","title":"Truncated"},"history_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"History From","description":"Start time of the earliest race in the price-history store. The retained window grows toward 45 days as capture accumulates; this is the floor as of right now."},"runners":{"items":{"type":"object"},"type":"array","title":"Runners"}},"type":"object","required":["race_id","venue","race_number","category","country","start_time","points_returned","truncated","runners"],"title":"PriceHistoryOut","example":{"category":"horse","country":"AU","history_from":"2026-08-04T09:22:00Z","points_returned":2481,"race_id":"race_123","race_number":2,"runners":[{"bookmakers":[{"close_price":7.0,"close_secs_to_jump":41,"high":7.0,"key":"sportsbet","low":6.0,"move_pct":7.69,"open_is_baseline":true,"open_price":6.5,"open_secs_to_jump":3595,"points":[{"captured_at":"2026-08-15T02:00:04Z","secs_to_jump":3595,"win_price":6.5}],"points_count":10}],"name":"Aeolian","number":4}],"start_time":"2026-08-15T03:00:00Z","truncated":false,"venue":"Caulfield"}},"PromoOut":{"properties":{"promo_id":{"type":"string","title":"Promo Id"},"book":{"type":"string","title":"Book"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"type":{"type":"string","title":"Type"},"market_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Market Scope"},"automatable":{"type":"boolean","title":"Automatable"},"gubbing_weight":{"type":"number","title":"Gubbing Weight"},"is_template":{"type":"boolean","title":"Is Template"},"ev_uplift_per_dollar":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ev Uplift Per Dollar"},"rank_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rank Score"},"confidence":{"type":"string","title":"Confidence"},"ev_components":{"type":"object","title":"Ev Components"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["promo_id","book","title","type","market_scope","automatable","gubbing_weight","is_template","ev_uplift_per_dollar","rank_score","confidence","ev_components","notes"],"title":"PromoOut","example":{"automatable":false,"book":"sportsbet","confidence":"med","ev_components":{},"ev_uplift_per_dollar":0.14,"gubbing_weight":0.4,"is_template":true,"market_scope":"horse racing metro","notes":"representative seed","promo_id":"sb_money_back_2nd_3rd","rank_score":0.124,"title":"Money back 2nd/3rd","type":"money_back"}},"RaceEventOut":{"properties":{"race_id":{"type":"string","title":"Race Id"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"start_time":{"type":"string","title":"Start Time"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","required":["race_id","venue","race_number","category","start_time","country","status"],"title":"RaceEventOut","example":{"category":"horse","country":"AU","race_id":"race_123","race_number":4,"start_time":"2026-06-07T04:10:00Z","status":"open","venue":"Eagle Farm"}},"RaceIn":{"properties":{"source_id":{"type":"string","title":"Source Id"},"venue":{"type":"string","title":"Venue"},"race_number":{"type":"integer","title":"Race Number"},"category":{"type":"string","title":"Category"},"start_time":{"type":"string","title":"Start Time"},"country":{"type":"string","title":"Country","default":"AU"},"runners":{"items":{"$ref":"#/components/schemas/RunnerIn"},"type":"array","title":"Runners"}},"type":"object","required":["source_id","venue","race_number","category","start_time","runners"],"title":"RaceIn"},"RaceResultOut":{"properties":{"race_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Race Id","description":"Race id, joinable to /v1/racing/price-history and (while the race is still open) /v1/racing/next-to-go. Null if the race cannot be resolved in the price-history store."},"coverage_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Coverage From","description":"Start time of the earliest result currently retained."},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"start_time":{"type":"string","title":"Start Time"},"race_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Race Name"},"distance_m":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Distance M"},"track_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Track Condition"},"weather":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Weather"},"status":{"type":"string","title":"Status"},"placings":{"items":{"type":"object"},"type":"array","title":"Placings"},"deductions":{"items":{"type":"object"},"type":"array","title":"Deductions","description":"Scratched runners and the deduction applied to bets already struck. `win` and `place` are fractions of the dollar in the range 0-1 (0.34 = 34 cents in the dollar), as published by the settling bookmaker."},"dividends":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Dividends","description":"Dividends declared for the race. `straight` holds one row per placegetter per product: {position, number, name, market ('WIN' or 'PLC'), product, amount}. `exotics` holds one row per exotic product: {type, code ('QN', 'EX', 'TF', 'FF'), selection, product, amount}, where `selection` is the winning saddlecloth numbers in finishing order, e.g. '5,1'. Every `amount` is the return on a $1 stake, the same convention as the odds fields — a 'FIXED' straight dividend equals that runner's own settled fixed price. `product` names the settling pool: 'FIXED' is the bookmaker's own price, the rest are tote products (SP, MIDDIV, VIC, RD+, BT+SP). A product that declared no dividend is omitted rather than returned as 0. Exotic dividends are only declared once the race fully settles, a few minutes after the placings, so a just-resulted race can carry `straight` while `exotics` is still empty — it fills in on a later poll. Quaddie and daily-double dividends span several races and are NOT reported here. `straight_types` is the book's raw list of product codes, retained for backwards compatibility."},"resulted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resulted At"}},"type":"object","required":["venue","race_number","category","country","start_time","status","placings"],"title":"RaceResultOut","example":{"category":"horse","country":"AU","coverage_from":"2026-08-15T05:53:00Z","deductions":[{"name":"Acapulco Girl","number":5,"place":0.0,"scratched_at":"2026-08-14T07:06:29Z","win":0.01}],"distance_m":1200,"dividends":{"exotics":[{"amount":14.4,"code":"QN","product":"VIC","selection":"6,3","type":"Quinella"},{"amount":77.7,"code":"TF","product":"VIC","selection":"6,3,9","type":"Trifecta"}],"straight":[{"amount":4.6,"market":"WIN","name":"Grinzinger Champ","number":6,"position":1,"product":"FIXED"},{"amount":5.0,"market":"WIN","name":"Grinzinger Champ","number":6,"position":1,"product":"MIDDIV"},{"amount":1.8,"market":"PLC","name":"Grinzinger Champ","number":6,"position":1,"product":"FIXED"}],"straight_types":["FIXED","MIDDIV"]},"placings":[{"name":"Grinzinger Champ","number":6,"place_price":1.8,"position":1,"win_price":4.6}],"race_id":"race_123","race_name":"TAB ROSEBUD","race_number":8,"resulted_at":"2026-08-15T06:01:12Z","start_time":"2026-08-15T05:53:00Z","status":"final","track_condition":"Good (4)","venue":"Doomben","weather":"Light Rain"}},"RacingBestOddsOut":{"properties":{"race_id":{"type":"string","title":"Race Id"},"venue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Venue"},"race_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Race Number"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"start_time":{"type":"string","title":"Start Time"},"race_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Race Name"},"track_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Track Condition"},"market_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Percentage"},"books_compared":{"type":"integer","title":"Books Compared"},"scratchings":{"items":{"type":"object"},"type":"array","title":"Scratchings","default":[]},"data_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Age Seconds","description":"Age in seconds of the OLDEST bookmaker quote behind this race."},"freshest_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freshest Age Seconds"},"stale":{"type":"boolean","title":"Stale","default":false},"stale_bookmakers":{"items":{"type":"string"},"type":"array","title":"Stale Bookmakers"},"cached":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cached"},"cache_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Age Seconds"},"runners":{"items":{"type":"object"},"type":"array","title":"Runners"}},"type":"object","required":["race_id","venue","race_number","category","country","start_time","books_compared","runners"],"title":"RacingBestOddsOut","example":{"books_compared":11,"cache_age_seconds":0,"cached":false,"category":"horse","country":"AU","data_age_seconds":41,"freshest_age_seconds":3,"market_percentage":106.4,"race_id":"race_123","race_name":"TAB ROSEBUD","race_number":8,"runners":[{"barrier":3,"best_place":{"age_seconds":4,"bookmaker":"tab","last_update":"2026-08-15T05:44:21Z","price":2.15,"stale":false},"best_tote":{"bookmaker":"betright","price":7.1,"product":"RD+"},"best_win":{"age_seconds":6,"bookmaker":"betright","last_update":"2026-08-15T05:44:19Z","price":6.5,"source_url":"https://...","stale":false},"books_quoting":11,"jockey":"J Mcdonald","name":"Chilly Girl","number":7,"price_spread_pct":18.2,"trainer":"C Waller"}],"scratchings":[],"stale":false,"stale_bookmakers":[],"start_time":"2026-08-15T05:45:00Z","track_condition":"Good (4)","venue":"Rosehill"}},"RunnerIn":{"properties":{"name":{"type":"string","title":"Name"},"number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number"},"win_price":{"type":"number","title":"Win Price"},"place_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Place Price"}},"type":"object","required":["name","win_price"],"title":"RunnerIn"},"SelectionIn":{"properties":{"name":{"type":"string","title":"Name"},"price":{"type":"number","title":"Price"},"point":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Point"}},"type":"object","required":["name","price"],"title":"SelectionIn"},"SignupRequest":{"properties":{"email":{"type":"string","title":"Email"},"plan":{"type":"string","title":"Plan","default":"free"},"label":{"type":"string","title":"Label","default":"My Key"}},"type":"object","required":["email"],"title":"SignupRequest"},"SportEventIn":{"properties":{"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"sport_key":{"type":"string","title":"Sport Key"},"home_team":{"type":"string","title":"Home Team"},"away_team":{"type":"string","title":"Away Team"},"commence_time":{"type":"string","title":"Commence Time"},"markets":{"items":{"$ref":"#/components/schemas/MarketIn"},"type":"array","title":"Markets"}},"type":"object","required":["sport_key","home_team","away_team","commence_time","markets"],"title":"SportEventIn"},"SportIngestPayload":{"properties":{"bookmaker_key":{"type":"string","title":"Bookmaker Key"},"events":{"items":{"$ref":"#/components/schemas/SportEventIn"},"type":"array","title":"Events"}},"type":"object","required":["bookmaker_key","events"],"title":"SportIngestPayload"},"SportOddsEventOut":{"properties":{"id":{"type":"string","title":"Id"},"sport_key":{"type":"string","title":"Sport Key"},"sport_title":{"type":"string","title":"Sport Title"},"commence_time":{"type":"string","title":"Commence Time"},"home_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Team"},"away_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Away Team"},"competition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Competition"},"bookmakers":{"items":{"type":"object"},"type":"array","title":"Bookmakers"},"odds_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Odds Format"},"fetched_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fetched At"},"data_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Age Seconds"},"freshest_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freshest Age Seconds"},"stale":{"type":"boolean","title":"Stale","default":false},"stale_bookmakers":{"items":{"type":"string"},"type":"array","title":"Stale Bookmakers","default":[]},"cached":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cached"},"cache_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Age Seconds"},"canonical_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Event Id"},"data_quality":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data Quality"}},"type":"object","required":["id","sport_key","sport_title","commence_time","home_team","away_team","bookmakers"],"title":"SportOddsEventOut","example":{"away_team":"Collingwood","bookmakers":[{"key":"sportsbet","markets":[{"key":"h2h","outcomes":[{"name":"Brisbane Lions","price":1.9}]}],"title":"Sportsbet"}],"commence_time":"2026-06-07T09:30:00Z","data_age_seconds":15,"fetched_at":"2026-06-07T09:29:45+00:00","home_team":"Brisbane Lions","id":"event_123","sport_key":"afl","sport_title":"AFL","stale":false}},"SportOut":{"properties":{"key":{"type":"string","title":"Key"},"title":{"type":"string","title":"Title"},"group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Group"},"active":{"type":"boolean","title":"Active"},"cached":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cached"},"cache_age_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Age Seconds"},"canonical_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Event Id"},"data_quality":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data Quality"}},"type":"object","required":["key","title","group","active"],"title":"SportOut","example":{"active":true,"group":"Australian Rules","key":"afl","title":"AFL"}},"SportsArbOut":{"properties":{"event_id":{"type":"string","title":"Event Id"},"sport_key":{"type":"string","title":"Sport Key"},"home_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Team"},"away_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Away Team"},"commence_time":{"type":"string","title":"Commence Time"},"is_arb":{"type":"boolean","title":"Is Arb"},"arb_pct":{"type":"number","title":"Arb Pct"},"optimal_stakes":{"items":{"type":"object"},"type":"array","title":"Optimal Stakes"},"max_overlay_pct":{"type":"number","title":"Max Overlay Pct"},"selections":{"items":{"type":"object"},"type":"array","title":"Selections"}},"type":"object","required":["event_id","sport_key","home_team","away_team","commence_time","is_arb","arb_pct","optimal_stakes","max_overlay_pct","selections"],"title":"SportsArbOut","example":{"arb_pct":2.4,"away_team":"Magpies","commence_time":"2026-06-07T09:30:00Z","event_id":"event_123","home_team":"Lions","is_arb":true,"max_overlay_pct":5.1,"optimal_stakes":[],"selections":[{"best_bookmaker":"sportsbet","best_price":2.05,"name":"Lions"}],"sport_key":"afl"}},"UsageOut":{"properties":{"plan":{"type":"string","title":"Plan"},"credits_used":{"type":"integer","title":"Credits Used"},"credits_limit":{"type":"integer","title":"Credits Limit"},"credits_remaining":{"type":"integer","title":"Credits Remaining"},"reset_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reset At"},"usage_by_endpoint":{"items":{"type":"object"},"type":"array","title":"Usage By Endpoint","default":[]},"recent_activity":{"items":{"type":"object"},"type":"array","title":"Recent Activity","default":[]},"plans":{"additionalProperties":{"type":"object"},"type":"object","title":"Plans","default":{}}},"type":"object","required":["plan","credits_used","credits_limit","credits_remaining","reset_at"],"title":"UsageOut","example":{"credits_limit":1000,"credits_remaining":958,"credits_used":42,"plan":"free","plans":{"free":{"credits_per_month":500,"price_aud":0}},"recent_activity":[{"credits":1,"endpoint":"/v1/sports","ts":"2026-06-07T02:20:00"}],"reset_at":"2026-07-01T00:00:00","usage_by_endpoint":[{"calls":12,"credits":12,"endpoint":"/v1/sports"}]}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WebhookCreate":{"properties":{"url":{"type":"string","title":"Url","description":"HTTPS endpoint that receives the POST. Plain http:// is rejected with 422.","examples":["https://example.com/hooks/puntersedge"]},"events":{"items":{"type":"string"},"type":"array","title":"Events","description":"Events to subscribe to. `arb.opportunity` is the only event with a live producer. `odds.change` is delivered solely by POST /v1/webhooks/{id}/test; `race.result` and `market.suspend` are accepted but never fire.","examples":[["arb.opportunity"]]},"min_edge_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Edge Pct","description":"Only deliver arb.opportunity when the theoretical edge is at least this percentage. Omit for every opportunity.","examples":[1.5]},"sports":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sports","description":"Only deliver arb.opportunity for these sports. Sport keys as returned by GET /v1/sports; racing arbs arrive as racing_horse, racing_greyhound or racing_harness. Omit for all sports.","examples":[["nrl","afl"]]}},"type":"object","required":["url"],"title":"WebhookCreate"},"WebhookDeliveryResponse":{"properties":{"id":{"type":"string","title":"Id"},"webhook_id":{"type":"string","title":"Webhook Id"},"event_type":{"type":"string","title":"Event Type"},"payload":{"anyOf":[{},{"type":"null"}],"title":"Payload"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"delivered_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivered At"}},"type":"object","required":["id","webhook_id","event_type","payload","status_code","error","delivered_at"],"title":"WebhookDeliveryResponse"},"WebhookResponse":{"properties":{"id":{"type":"string","title":"Id"},"url":{"type":"string","title":"Url"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"min_edge_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Edge Pct"},"sports":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sports"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"last_delivery_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Delivery At"},"failure_count":{"type":"integer","title":"Failure Count"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret"}},"type":"object","required":["id","url","events","is_active","created_at","last_delivery_at","failure_count"],"title":"WebhookResponse"},"Problem":{"type":"object","properties":{"type":{"type":"string","format":"uri","description":"Stable URI identifying the error class.","example":"https://puntersedge.online/errors/rate-limit"},"title":{"type":"string","description":"Short human-readable summary."},"status":{"type":"integer","description":"HTTP status code.","example":429},"detail":{"description":"Explanation of this occurrence. A string for most errors; an array of field errors for 422; an object for 429."}},"required":["type","title","status"]}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"**Get a free key** at [puntersedge.online/api-platform](https://puntersedge.online/api-platform).\n\nPaste your key in the **Authorize** dialog (lock icon, top right of Swagger UI) to try all endpoints live."}}},"tags":[{"name":"Sports","description":"Sports catalogue and market odds endpoints for AFL, NRL, NBA, tennis, cricket, rugby and more. Racing is NOT here — horse, harness and greyhound live under the Racing tag at /v1/racing/next-to-go and /v1/racing/events. There is no racing sport_key."},{"name":"Racing","description":"Australian racing endpoints for next-to-go races, race events, runners and bookmaker prices."},{"name":"Best Odds","description":"Best available price per selection, bookmaker comparison and arbitrage indicators."},{"name":"Arb & Value","description":"Sports and racing arbitrage scanners plus overlay/value price comparison tools."},{"name":"Account","description":"Authenticated usage, credit balance, connector health and developer key utilities. Subscribers manage billing here too — GET /v1/billing/portal returns a Stripe portal link for changing the card, pulling invoices or cancelling, authenticated by the API key itself, so there is no separate account to create. It costs no credits."},{"name":"Webhooks","description":"Subscribe to real-time arb opportunity events via HTTP webhook. Payloads are HMAC-SHA256 signed. Creating a subscription requires a Pro plan or higher; other plans get 403."},{"name":"Signup","description":"Developer signup and API key creation endpoints."}],"security":[{"ApiKeyAuth":[]}]}