FedFlow data
Every number FedFlow draws is served as plain JSON from a public, CORS-enabled endpoint. The data is US government public-domain material; use it however you like.
Base URL
All endpoints below are relative to https://fedflow-data.fedflow.workers.dev.
curl -s https://fedflow-data.fedflow.workers.dev/snap/top/2025.json | jq '.totals'
Endpoints
| Path | Contents |
|---|---|
/manifest.json | Which fiscal years are available, when the set was last generated, and any build errors. |
/snap/top/<fy>.json | Top-level flow for one fiscal year: revenue sources → agencies, plus government-wide totals. |
/snap/agency-<id>/<fy>.json | One agency broken into its federal accounts. <id> is the short agency id, e.g. hhs. |
/snap/agency-<id>/fa-<code>/<fy>.json | One federal account broken into program activities. |
/snap/agency-<id>/fa-<code>/pa-<id>/<fy>.json | One program activity broken into object classes. |
/geo/<anchor>/<fy>.json | Prime-award obligations by state for an anchor (top or agency-<id>). |
Fiscal years currently published: FY2017, FY2018, FY2019, FY2020, FY2021, FY2022, FY2023, FY2024, FY2025.
Units
Every monetary value in every snapshot is US dollars in billions — 1873.7 means $1.87 trillion. totals.gdp is nominal GDP in trillions and totals.pop is population in millions, which is what the "% of GDP" and "per capita" views divide by.
Obligations vs. outlays
An obligation is a binding commitment to pay — a signed contract, an awarded grant, an entitlement claim accepted — recorded in the year the government promises the money. An outlay is cash actually leaving the Treasury, which often happens in a later year than the obligation that authorized it, so the two figures for the same account rarely match.
Schema
The TypeScript contract every snapshot satisfies:
export type Measure = 'obligations' | 'outlays';
export type NodeKind = 'revenue' | 'agency' | 'federal_account' | 'program_activity' | 'object_class' | 'gap' | 'other';
export interface SnapNode {
id: string; name: string; color: string; kind: NodeKind;
parent?: string; drillable: boolean; note?: string;
/** USAspending identifiers needed to fetch the next level (worker-internal, harmless in JSON) */
ref?: { toptier?: string; agencyId?: string; faId?: string; paId?: string };
}
export interface SnapLink { source: string; target: string; obligations: number; outlays: number }
export interface Snapshot {
meta: { fy: number; period: 12; anchor: string[]; generated: string; caveats: string[] };
nodes: SnapNode[]; links: SnapLink[];
totals: { receipts: number; obligations: number; outlays: number; gdp: number; pop: number };
}
export interface Manifest { fys: number[]; generatedAt: string; errors: string[] }
export interface GeoSnapshot { fy: number; anchor: string[]; states: { code: string; name: string; obligations: number }[] }
Refresh, caching and CORS
- A scheduled job refreshes the two most recent fiscal years nightly at 09:00 UTC — the only ones whose figures still move; closed years are rebuilt on demand.
manifest.jsoncarries thegeneratedAttimestamp of the last successful run (currently2026-08-23T22:02:07.910Z). manifest.jsonis served withcache-control: public, max-age=300; every snapshot is served withpublic, max-age=86400.- Responses carry an
access-control-allow-originheader, so browser clients on other origins can read them directly. OnlyGETis supported. - A path that is not a valid snapshot key returns
404— also with the CORS header, so a fetch failure is always readable.
Known gaps
The figures are a best-effort assembly of several public feeds, and each has real gaps worth knowing about before drawing conclusions:
- Sub-award data is incomplete. The map view shows prime awards by place of performance; sub-awards (money that flows on from a prime recipient to a subcontractor or subgrantee) are not reliably reported to USAspending and are excluded.
- Classified spending is absent. Defense Department programs that are classified are not reported to USAspending, so the Defense figures below the top level understate actual outlays.
- Outlays below the federal-account level are apportioned pro-rata from obligations, not independently measured — USAspending does not publish an outlays breakdown at that granularity, so each child’s share of its parent’s outlays is assumed equal to its share of obligations.
- The top-level total mixes sources. The top-level total is Treasury's Monthly Treasury Statement (MTS) net outlays figure, while every drilled-in level (agency, federal account, program activity, object class) comes from USAspending's gross award/obligation figures. The two are not perfectly reconcilable.
- GDP and population are a bundled static table (shared/src/static.ts), not fetched live — Treasury’s Fiscal Data API does not publish either series, so the "% GDP" and "per capita" units are computed against fixed, approximate annual figures rather than live data.
License
US federal government data is not subject to copyright. The assembled snapshots are released under CC0 1.0. Attribution is appreciated but not required; a link back to FedFlow helps people find the caveats above.