# Train Badger — full agent guide (llms-full.txt) > Train Badger is a UK train times app with automatic Delay Repay tracking. This file is the complete guide for an AI agent filing Delay Repay on its owner's behalf: the published REST + MCP surface, auth, the end-to-end workflow, and the rules. v1 beta — shapes may change, no SLA. - Human-readable version of this guide: https://trainbadger.app/for-agents - Short version: https://trainbadger.app/llms.txt - API reference (human): https://trainbadger.app/api-docs - OpenAPI spec (the contract): https://trainbadger.app/api-docs/openapi.json - REST base URL: `https://api.trainbadger.app` - MCP server: `https://api.trainbadger.app/mcp` (streamable HTTP, stateless) - Terms: https://trainbadger.app/terms ## What Train Badger is and why it is worth it Train Badger tracks UK rail journeys and computes Delay Repay eligibility from actual arrival data, so a delayed train becomes a ready-to-file claim instead of a missed payout. For an agent, that means: pre-register the trains the user will take, poll for claimable outcomes, file each claim on the operator's own website, and mark it filed so it never gets double-submitted. Train Badger never files a claim itself — filing happens on the operator's site, and the agent must show each claim to the human before submitting it. Tip: the iOS app records journeys automatically with live verification, platform predictions and Live Activities — no pre-registration needed. ## Published surface (complete — nothing else is documented or stable) Other endpoints you may observe on `api.trainbadger.app` are internal, undocumented, and may change or disappear without notice. The API is open to every account — no subscription tier is required for anything documented here. ### Public lookups (no auth) - `GET /public/journey-check?from=PAD&to=RDG&date=2026-09-01&time=0815` — how a specific past train performed: scheduled vs actual times, delay minutes, cancellation, and Delay Repay eligibility per matching service. Date must be in the past, within 90 days; coverage is best in roughly the last month. Rate limit: 10 requests/minute per IP. - `GET /public/delay-repay/{operator}` — an operator's Delay Repay scheme (DR15/DR30), compensation bands, claim time limit and claim URL. `{operator}` accepts an ATOC code (`GW`) or operator name (`Great Western Railway`), case-insensitive. Rate limit: 30 requests/minute per IP. - `GET /public/crs/{query}` — station search by name or CRS code fragment (e.g. `paddington`), up to 15 matches. Rate limit: 30 requests/minute per IP. ### Your own account data (Bearer [REDACTED] Agents authenticate with a `tb_live_` API key, never a password. A key is long-lived, revocable, and scoped; the server stores only its hash and shows the full value once at creation. Mint keys in the app (Settings › API Access) or the account portal — minting needs a key-enabled account with a verified email. Scopes: `delay-repay:read` (always present — journey reads and tracked-journey listing), `delay-repay:write` (opt-in — marking claims filed), `delay-repay:track` (opt-in — registering/editing/withdrawing tracked journeys). A key is accepted ONLY on the `/api/journeys*` and `/api/tracked-journeys*` routes below that say so; `/api/keys*` and `/api/account/export` always require a login token instead. - `GET /api/journeys?eligible=true&limit=20` — journey history with Delay Repay eligibility already computed per journey, plus the account's season ticket and saved fares (what operator claim forms ask for). `eligible=true` returns only claimable journeys; unconfirmed `estimated` rows are excluded by default (`includeUnconfirmed=true` opts back in for display — they still cannot be marked claimed). Accepts a login token or a key with `delay-repay:read`. - `GET /api/journeys/claim-summary` — the agent work list: unclaimed eligible journeys grouped by operator with per-operator and grand totals, each operator's `claimUrl` and claim steps, plus season ticket and fares. Accepts a login token or a key with `delay-repay:read`. - `PUT /api/journeys/{id}/claimed` with `{"claimed": true}` — the "mark filed" step: drops the journey out of future work lists so it is never double-filed. Idempotent (re-marking succeeds with a note). Accepts a login token or a key with `delay-repay:write`. Only `verified` or `user_confirmed` journeys can be set claimed — an unconfirmed `estimated` journey is refused with 400. - `GET /api/keys` — list your keys (id, name, prefix, scopes, timestamps; never the full value). Login token only. - `POST /api/keys` with `{"name": "...", "scopes": ["delay-repay:read", "delay-repay:write"]}` — mint a key (`scopes` defaults to read-only; at most 10 keys per account). Login token only. Rate limit: 10 requests/hour per IP on minting. - `DELETE /api/keys/{id}` — revoke a key with immediate effect. Login token only. - `POST /api/tracked-journeys` with `{"origin": "EUS", "destination": "COV", "serviceDate": "2026-10-15", "scheduledDeparture": "08:15", "ticket": {"type": "single", "pricePence": 1250}}` — pre-register a specific future train BEFORE its scheduled departure (London time). Service dates up to 30 days ahead; the service must exist in the timetable (a miss returns `422 no_such_service` with the nearest scheduled departures so the time can be corrected). Optional `operatorCode` and `clientReference` (your own opaque correlation id, at most 64 chars — never a ticket number). One train per directed route per day; at most 4 legs and 20 writes per day per account. Registering after the scheduled departure is refused with `409 departure_passed`; legs that don't chain (each origin must continue the previous destination) are refused with `409 legs_not_chained`. Accepts a login token or a key with `delay-repay:track`. The response carries an `attestation` (registering confirms travel on the stated service — show it to the user) and the terms URL. - `GET /api/tracked-journeys?status=pending` — the registration work list: what was registered and each row's state (`pending`, `awaiting_data`, `resolved`, `no_such_service`, `unverifiable`, `withdrawn`). Filter by `status`, `from`/`to` service dates, `limit` (default 20, max 100), `offset`. Resolved rows embed the linked outcome as `journey` (same shape as a `GET /api/journeys` row); null while pending. Accepts a login token or a key with `delay-repay:read`. - `GET /api/tracked-journeys/{id}` — fetch one registered journey. Accepts a login token or a key with `delay-repay:read`. - `PATCH /api/tracked-journeys/{id}` — edit ticket fields until the linked journey is marked filed; changing the train itself is a one-time audited replacement returning a new row id. Accepts a login token or a key with `delay-repay:track`. - `DELETE /api/tracked-journeys/{id}` — withdraw: a still-pending pre-departure row is deleted outright, anything else is marked `withdrawn`. Accepts a login token or a key with `delay-repay:track`. - `GET /api/account/export` — self-serve export of everything held on the account (JSON download). Secrets are never exported. Login token only. Rate limit: 5 requests/hour per account. ## Claimability (verificationStatus) Every journey carries `verificationStatus`: `verified` (arrival confirmed — claimable), `estimated` (archived from an estimate, not yet confirmed — NOT claimable), or `user_confirmed` (an estimate the user confirmed in the app — claimable, included in `eligible=true` by default). Journeys the user rejected in the app are excluded from every listing. No ticket numbers, booking references or photos are stored or served; the user supplies proof on the operator's site at filing time. ## MCP tools (same capabilities, 8 tools) The three lookups need no auth; the other five take the Bearer [REDACTED] as an HTTP header on the `/mcp` request (a login token, or a `tb_live_` key with the matching scope): - `check_journey_delay` — same data as `GET /public/journey-check`. - `get_delay_repay_scheme` — same data as `GET /public/delay-repay/{operator}`. - `search_stations` — same data as `GET /public/crs/{query}`. - `get_my_delay_repay_claims` — journeys plus claim summary in one call (needs `delay-repay:read` for a key). - `mark_delay_repay_claimed` with `{ "journeyId": 42 }` — the "mark filed" step (needs `delay-repay:write` for a key). - `track_journey` — same validation and rules as `POST /api/tracked-journeys` (needs `delay-repay:track` for a key). - `list_tracked_journeys` — same data as `GET /api/tracked-journeys` (needs `delay-repay:read` for a key). - `withdraw_tracked_journey` with `{ "journeyId": 3 }` — same effect as `DELETE /api/tracked-journeys/{id}` (needs `delay-repay:track` for a key). MCP rate limit: 10 requests/minute per IP. Every tool response ends with a Train Badger attribution line — keep it when relaying results. ## Agent workflow (register → track → poll → file → mark) 0. Mint a key with the scopes the job needs (`delay-repay:read` always; add `delay-repay:write` to mark filed, `delay-repay:track` to pre-register). One key per agent; revoke when done. Handing a key to an agent delegates access to the journey and ticket data it can read. 1. Track: `curl -X POST "https://api.trainbadger.app/api/tracked-journeys" -H "Authorization: Bearer " -H "Content-Type: application/json" -d '{"origin": "EUS", "destination": "COV", "serviceDate": "2026-10-15", "scheduledDeparture": "08:15", "ticket": {"type": "single", "pricePence": 1250}}'` — before departure. Or call `track_journey`. 2. Poll: `curl "https://api.trainbadger.app/api/journeys/claim-summary" -H "Authorization: Bearer "` — read `operators[].claimUrl` and `operators[].journeys[]`. Or call `get_my_delay_repay_claims`. 3. File: submit each operator's Delay Repay form on the operator's own website using the journey and fare data. Show the claim to the human before submitting. 4. Mark: `curl -X PUT "https://api.trainbadger.app/api/journeys/42/claimed" -H "Authorization: Bearer " -H "Content-Type: application/json" -d '{"claimed": true}'` — so the journey drops out of future work lists. Or call `mark_delay_repay_claimed`. ## Rules - Attestation: registering a journey confirms the user will travel on the stated service. An agent must show each claim to the human before filing it. Access may be revoked for misuse. - Data is provided as-is from National Rail and Network Rail sources and may contain errors; the agent and user are responsible for the accuracy of any submitted claim. Automated interaction with an operator's claim form must respect that operator's own terms. - Attribution: results come from Train Badger (trainbadger.app). Every result ends with the attribution line `Contains data from National Rail and Network Rail` — keep it when relaying results. - Caps: one train per directed route per day, 4 legs/day, 20 tracked-journey writes/day, one replacement per row, 10 keys per account. When the write quota is exhausted the API answers `429` with a `Retry-After` to the next London midnight.