LOSGL API v1
Every number on this site comes from these files. Static JSON, regenerated on publish, served with Access-Control-Allow-Origin: *. No auth, no rate limit beyond Cloudflare's, no writes. Cache for at least five minutes — the data only moves when we publish.
Base
https://losgl.thebatcave.cloud/api/v1/
For your AI agent: hand it /api/llms.txt — every endpoint, field, rule, error code and two ready recipes (Google Sheet → survivor sync, ranking submission) in one plain-text file. Machine schema: /api/openapi.json (OpenAPI 3.1).
All endpoints are GET. Responses are UTF-8 JSON. Fields marked nullable are null when the data is missing — never zero, never invented. Check status on matchups before using scores.
curl -s https://losgl.thebatcave.cloud/api/v1/published.json
# {"published_at":"2026-…Z","published_human":"…","content_hash":"41e7380c82d5aae1…"}
Endpoints
| Path | What |
|---|---|
| (every file) | _meta.as_of = when the underlying data last changed (UTC), on every JSON file; records carry their own dates (date, processed_at, published_at, as_of). Former bare arrays are {_meta, items}. |
| published.json | Last publish time + content hash. Poll this (no-store) to know when anything changed. |
| site.json | League meta: name, league_name, current_season, last_complete_season, seasons[] (year, available, complete, champion, last_place, latest_week), sync (ok, auth_expired, status), status/bug vocab. |
| seasons/{year}.json | One season: standings[] (wins, losses, ties, pf, pa, allplay_w/l/t, ppg, streak, rank, final_rank, manager_slug, franchise_slug), weeks[] → tickets[] (matchup_id, week, tier, is_playoff, status, home/away {name, manager, manager_slug, points, result, projected, box}, margin, winner, line), playoffs[], consolation[], byes[], draft.rounds[], draft_report, outcomes (champion, runner_up, last_place, champion_verification), gaps[], rule_change. |
| managers.json | Every manager: slug, name, aliases[] (ESPN handles only), seasons[], career, playoffs, titles[], last_places[], rivals[]. |
| franchises.json | Franchise lineages: slug, name, names[] (every team name used), owners[] (manager_slug, start, end), seasons[], career. |
| h2h.json | manager and franchise maps keyed "a-slug|b-slug": record.all/regular/playoff as [W, L, T] from A's side, games[], pf_a, pf_b, streak_a, line. Consolation games excluded. |
| records.json | The record book: rules + categories[] (key, title, scope, items[] with matchup_id/year/week links). |
| rankings/{year}.json | statistical[] (one entry per week: rank, score, components, delta) and commissioner[] (published editions only: rank, comment, delta). formula documents the math. |
| draft/{year}.json | Draft report card: teams[] (points = season fantasy points produced by that team's picks, best, bust, reach, steal), late_gems[], reaches[], steals[], coverage, rules. Derived from FantasyPros consensus + season points; only our derived numbers are published. |
| notes.json | Published commissioner notes (metadata + excerpt; full HTML lives at /notes/{slug}/). |
| sleepers.json | Sleepers: per-season top 5 late-round/undrafted finds ranked by points over positional replacement, with who found them; all-time "sleeper hunter" board. |
| transactions/{year}.json | The Wire: faab[] (remaining/spent per team), weeks[] with waivers_won, waivers_failed (with reason), free_agents, trades (outcome, pieces). Archive starts 2026-09-14 (ESPN only serves the current season). |
| survivor/{year}.json | Survivor pool snapshot synced from the commissioner's sheet: participants[] (name, alive, eliminated_week, picks by week with NFL code + result), alive_count, winner. |
| trades.json | Trade History: every completed trade since 2018 valued two ways (raw post‑trade points and position‑adjusted value above replacement), manager and manager‑pair records, season leaders, leaderboards, most‑traded players, the method. trades/{trade_id}.json carries the full per‑player, per‑week audit and the cumulative series. |
| players/{espn_player_id}.json | One rostered player, everything: fantasy_team (slot, starter, projected starter next week), injury (ESPN's status first, FantasyPros' type / probability / IR), projection (FantasyPros PPR and losgl_points re-scored with this league's first-down bonuses, stat line), ecr, season_to_date by week, and notes[] — the complete ESPN player-news feed (stat line + analysis, dated). players/index.json lists them all. |
| players/rosters.json | Current rosters per team with the full player records above, the injured list, and the projected best lineup in LOSGL points. |
| players/free_agents.json | The waiver wire: every unrostered / on‑waivers player with availability (waiver clear time, who dropped him), value (projections in this league's scoring, ECR, season to date), desirability (% rostered and 7‑day change, % started, this league's adds/drops/claims), injury and latest note; plus a position‑relative hot[] top 15 and trending. Refreshed every 6 hours in season. |
| players/news.json | Every ESPN player note for every rostered player, newest first, tagged with the player's fantasy team and injury status. |
| memory/{year}.json | The ingestion feed. One dated document per fact — player notes, injuries, matchups (with box lines and coaching losses), weekly standings, waivers/free agents/trades, every ranking entry with its comment, editorial notes — each with a stable id, ISO date, entities and a link back. Built for embeddings/reranker memories; upsert by id. |
| episodes.json | The Booth: published podcast episodes (title, aired, duration, audio_url, show notes, the item ids the script used). RSS at /pod/feed.xml. |
| nfl/schedule/{year}.json | NFL schedule by week from ESPN's public scoreboard: kickoff (UTC), teams, status, scores, and the line ESPN attaches (spread, favorite, over/under). Raw material for a survivor picker. |
Power rankings · read & submit
Read: rankings/{year}.json → statistical[] (one object per week: week, entries[] with rank, season_team_id, name, manager_slug, score, components {ppg, allplay, win_pct, form}, delta) and commissioner[] (published editions: week, title, intro, published_at, entries[] with rank, season_team_id, name, manager, comment, delta). season_team_id is the stable key for a team in a season; the full list for a year is in seasons/{year}.json → standings[].season_team_id.
Submit (external ranking systems): the one write endpoint on this hostname. Ask the commissioner for a bearer token; each token is a named source and its editions appear as their own set under Power Rankings — they never overwrite the commissioner's or the formula's.
# who am I / does my token work
curl -H "Authorization: Bearer $TOKEN" https://losgl.thebatcave.cloud/api/v1/submit/whoami
# the season_team_ids you must rank (also in seasons/{year}.json → standings[])
curl -H "Authorization: Bearer $TOKEN" https://losgl.thebatcave.cloud/api/v1/submit/teams/2026
# publish an edition (one entry per team, ranks 1..N each used once; re-POST the same year+week to replace)
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
https://losgl.thebatcave.cloud/api/v1/submit/rankings -d '{
"year": 2026, "week": 3,
"title": "Week 3: somebody call his mother",
"intro": "optional, 2–4 sentences",
"entries": [
{"season_team_id": 145, "rank": 1, "comment": "1–3 sentences, optional"},
{"season_team_id": 152, "rank": 2, "comment": "…"}
]
}'
# 201 {"kind":"external:josh","year":2026,"week":3,"entries":12,"public_within":"15 minutes (next publish tick)"}
# 401 bad token · 403 wrong scope · 422 validation message · 413 body over 256 KB · 429 over 30 req/min
Only ranking editions can be written. Comments are plain text (max 1200 chars), titles/intros max 2000; slurs are rejected. The site republishes within one timer tick, so read back rankings/{year}.json after ~15 minutes. Tokens are hashed at rest and can be revoked by the commissioner at any time.
Vocabulary
Matchup status: final (counted everywhere) · provisional (decided, inside the stat-correction window; counted in standings, not in records) · live (in progress; never counted) · scheduled · missing (ESPN has no score; never counted) · bye.
Tier: NONE regular season · WINNERS_BRACKET playoffs · WINNERS_CONSOLATION_LADDER / LOSERS_CONSOLATION_LADDER consolation (excluded from every stat).
Identity: a manager is a person (may span several ESPN accounts); a franchise is the ESPN team slot lineage; a season team is one team in one year with that year's name. Slugs are stable across publishes unless the commissioner renames someone.
Privacy: no ESPN ids, emails, or real names are published — only display handles and team names. Nothing here proxies ESPN or FantasyPros; there is no key to steal.
Versioning: breaking changes get a new /api/v2/; v1 stays. Questions go to the commissioner.