Public API · v1
Your league's data, in your tools.
A read-only JSON API over Armchair leagues: rosters and lineups week by week, the full transaction ledger, trades, draft boards and standings. No account, no key, no cost — enough to build a league analysis tool, a history site or a Discord bot against.
Start here
Everything is keyed off a league. Pass either the league UUID or the short number the app shows you, then use the teamIndex values it returns for every other call.
# The league, its rules, its teams and their managers curl https://armchairff.com/api/public/v1/leagues/100482 # What team 3 actually started in week 7, and what each player scored curl "https://armchairff.com/api/public/v1/leagues/100482/rosters?season=2025&week=7&teamIndex=3" # Every trade the league has completed curl https://armchairff.com/api/public/v1/leagues/100482/trades # Resolve a roster's player ids in one request curl "https://armchairff.com/api/public/v1/players?ids=14876,19238,21455"
Endpoints
| GET | /api/public/v1/leagues | Leagues open to the API. `joinable=true` for ones taking managers. |
| GET | /api/public/v1/leagues/{league} | Settings, scoring, roster shape, teams, managers and records. |
| GET | /api/public/v1/leagues/{league}/teams | Teams with managers and season records. |
| GET | /api/public/v1/leagues/{league}/teams/{teamIndex} | One team, its current roster, and every season it has played. |
| GET | /api/public/v1/leagues/{league}/rosters | Current rosters, or the scored snapshot for any past week. |
| GET | /api/public/v1/leagues/{league}/matchups | Schedule and results, by season or week. |
| GET | /api/public/v1/leagues/{league}/standings | The table, plus every season the league has played. |
| GET | /api/public/v1/leagues/{league}/transactions | Adds, drops, claims, drafts and trade legs. |
| GET | /api/public/v1/leagues/{league}/trades | Completed trades: players, picks, FAAB and veto votes. |
| GET | /api/public/v1/leagues/{league}/drafts | Full draft boards, with autopick flags and auction prices. |
| GET | /api/public/v1/leagues/{league}/players/{playerId} | One player's ownership stints inside a league. |
| GET | /api/public/v1/players | Player search, or bulk id resolution with `ids=`. |
| GET | /api/public/v1/players/{playerId} | One player. |
Rate limits
| Tier | Per minute | Per day |
|---|---|---|
| Anonymous | 60 | 5,000 |
| With a key | 600 | 120,000 |
Every response carries RateLimit-* headers; a 429 carries Retry-After. Responses are cached at the edge, from 30 seconds for live scores to an hour for finished seasons — so re-requesting is cheap, and polling beats mirroring.
Keys are optional
Every endpoint answers without one. A key exists for two reasons: it raises your ceiling, and it means we can reach you before we throttle you if something goes wrong.
Send it as X-Api-Key, or as Authorization: Bearer armch_pk_… if your client only speaks bearer tokens.
What we will and will not hand over
Commissioners opt in
Public leagues are readable by default — they are already browseable and joinable. Private leagues stay closed until a commissioner switches access on, and can be switched off again at any time. A league that has not opted in returns 404, identical to one that does not exist.
League data, not personal data
Managers appear as a display name and a team index. No user ids, emails, real names, phone numbers or profile details are returned anywhere, and nothing here lets you tell that the same person plays in two leagues.
Some things stay private
Trades appear once they have been accepted — live negotiations and the messages between two managers never do. Neither do private watchlists or the commissioner’s note to their own league.
Commissioners control this per league, under League Settings → Public API access. If you are a manager and would rather your league were not readable, that is the person to ask.
Full reference
Generated from the running build, so it always describes what is actually deployed.