livetennisapi 1.2.1
livetennisapi: ^1.2.1 copied to clipboard
Dart and Flutter client for the Live Tennis API — real-time tennis scores, players, rankings, history and fixtures for ATP, WTA, Challenger, ITF and juniors over REST.
Changelog #
All notable changes to this project are documented here. This project adheres to Semantic Versioning.
1.2.1 — 2026-08-16 #
Added #
PackageKind.rally— the charted rally corpus (shot-by-shot) as yearly exports (ULTRA), andPackageKind.archive— the results archive (1968–2022) as yearly exports, same entitlement as the tape packages. Both are yearly kinds: theirperiodis the bare yearYYYY. Additive — the wire default (tape) and existing behaviour are unchanged.
Fixed #
- README install instruction now points at
^1.0.0— the latest version published on pub.dev — instead of^1.2.0, which is not yet on pub.dev and madepub getfail. Newer versions are tagged on GitHub and pending pub.dev publication; a git-dependency snippet documents the interim path.
1.2.0 — 2026-08-07 #
Full API parity: every documented public v1 REST path now has a typed method.
Added #
getUsage(/usage, any tier and quota-exempt) → typedUsagewithUsageLimits,UsageTodayand a 30-dayUsageDayhistory. Note the daily reset instant is not part of this response — it exists only asresets_aton a daily-429 body.- Webhooks (ULTRA, direct keys only):
createWebhook(POST, one-timeWebhook.secret, server-default events when omitted),listWebhooks(never includes the secret) anddeleteWebhook;WebhookEventenum (score,break_point). Max 3 per key — the 4th raises the newConflictException(409webhook_limit). Mutating requests are never auto-retried, so a transient failure cannot register a duplicate webhook. - Tournament catalogue:
listTournaments/getTournament(FREE) → typedTournament(stable id joined byMatch.tournamentId, curated host city/country, category only where the catalogues agree). listMatchPrices(/matches/{id}/prices, PRO): bare price ticks of the mapped match-winner market —limit≤ 500,minuteslookback window, no offset (meta.has_moremarks a clipped window).
Notes #
- Deliberately out of scope (documented in the README): undocumented gateway alias routes, HTML views and static assets; package file downloads stream as attachments and stay with your HTTP tooling (the client returns the JSON manifest).
1.1.0 — 2026-08-07 #
Added #
- History & analytics endpoints:
getMatchTape(point-by-point tape with?sequence=raw|clean, works on live matches),getHeadToHead(/h2h), the deep results archive —listArchiveMatches,getArchiveMatch,listArchivePlayers,getArchiveCareer(1968–2022, own id space) — and bulk packages vialistHistoryPackages/getHistoryPackage(withkind: tape|rankingsand theyeararchive listing). - ULTRA endpoints:
getMatchStatistics(derived + measured families with per-family freshness), rally construction —listRallyMatches,getRallyMatch,getMatchRally(by our match id; 404not_chartedis distinct fromnot_found) — shot-level charting viagetChartingPlayer/getChartingMatch, andgetWsTokenfor the push WebSocket feed (WsTokenwithwsUrl, channel vocabulary incl.slate:all, and amatchChannel()helper). - Rankings:
listRankingscovers both modes — the rank-ordered listing (PRO, onesystem) and per-player as-of records (ULTRA, up to 50 ids) — returning typedRankingRecords withpreviousRank. - New
Matchfields:tour(filter vocabulary, groupable),tournamentId,roundCode,withdrew(who retired/conceded a walkover). - Tape models:
TapeRow.pointWinner(clean sequence only) and per-set tiebreak final scores (MatchTape.tiebreaks). - New list filters on
listMatchesandlistCompletedMatches:players(≤ 50 ids, repeated on the wire),country(IOC-style 3-letter code),from/todate bounds, andcoverageon the history list. Unknown filter values are a400, never silently ignored. - Errors: daily-quota 429s expose
resetsAt,scopeandlimitPerDayonRateLimitedException; the newAbuseThrottledExceptioncarriesretryAtEpoch/retryAtand is never auto-retried (it is a 24-hour block for broken retry loops — waiting a few seconds cannot clear it). ListMeta.totalandListMeta.hasMore.scripts/truthcheck.shtruth-pin, run in CI.
Changed #
- Tier attribution for 403s now covers the full surface (statistics, rally,
charting, ws-token, packages, h2h, archive), including mode-dependent
endpoints: rankings 403s name PRO in listing mode and ULTRA in per-player
mode, and
listMatches(status: completed)names BASIC. - Docs and README now state the current quota grid (2026-08-06: FREE 100/day, BASIC 1,000/day, PRO 10,000/day, ULTRA 500,000/day) and the five-tour coverage phrasing (ATP, WTA, Challenger, ITF and juniors).
1.0.0 #
First release.
Added #
LiveTennisApicovering all 12 REST endpoints:health,listMatches,getMatch,getMatchScore,listMatchEvents,getMatchAnalysis,searchPlayers,getPlayer,listMarkets,getMarketPrices,listCompletedMatchesandlistFixtures.- Immutable models with
fromJson:Match,Player,Score,DataCompleteness,Market,Price,Analysis,MatchEvent,Fixture,Page,ListMeta. TourandMatchStatusfilter enums.- Typed error hierarchy.
UpgradeRequiredExceptioncarriesrequiredTier;RateLimitedExceptioncarriesretryAfter. - Retries on
429and5xxonly, honouringRetry-Afterwith exponential backoff and jitter. Other4xxare never retried. paginate()stream for walking list endpoints.
Notes #
- Models never reject unknown fields. The API ships additive changes within
v1, so unrecognised fields are ignored by the typed getters but preserved in each model'srawmap — a new server field works without upgrading. Score.gamesis player-major ([games_p1, games_p2], each a per-set list). UseScore.gamesForSet()to read it safely.Score.serverandMatch.scoreare nullable;Score.pointsare strings.DataCompleteness.knownand.ofarenullon a doubles team (with anote), distinct from0.- Depends only on
package:http, with no Flutter dependency, so it runs in pure Dart, Flutter, and on the web.