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/leaguesLeagues 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}/teamsTeams 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}/rostersCurrent rosters, or the scored snapshot for any past week.
GET/api/public/v1/leagues/{league}/matchupsSchedule and results, by season or week.
GET/api/public/v1/leagues/{league}/standingsThe table, plus every season the league has played.
GET/api/public/v1/leagues/{league}/transactionsAdds, drops, claims, drafts and trade legs.
GET/api/public/v1/leagues/{league}/tradesCompleted trades: players, picks, FAAB and veto votes.
GET/api/public/v1/leagues/{league}/draftsFull 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/playersPlayer search, or bulk id resolution with `ids=`.
GET/api/public/v1/players/{playerId}One player.

Rate limits

TierPer minutePer day
Anonymous605,000
With a key600120,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.

Request a key

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.