Federal Budgets
Enacted appropriations and monthly outlays from the Treasury and OMB, normalized into the same bearer-authenticated shape as the rest of the Archivist.
Authentication
Every budgets endpoint uses the same bearer-token contract as the rest of the Archivist. Pass your key in the Authorization header — send `Authorization: Bearer $ARCHIVIST_KEY` on every request and you’re in. No cookies, no sessions, no CSRF surface.
curl 'https://api.archivist.dev/budgets/appropriations?fiscal_year=2024' \
-H "Authorization: Bearer $ARCHIVIST_KEY" \
-H "Accept: application/json"const res = await fetch(
'https://api.archivist.dev/budgets/appropriations?fiscal_year=2024',
{
headers: {
Authorization: `Bearer ${process.env.ARCHIVIST_KEY}`,
Accept: 'application/json',
},
},
);
if (!res.ok) throw new Error(`Archivist ${res.status}`);
const { items, nextCursor } = await res.json();For full key-handling guidance and the 401 / 403 / 429 status table, see Errors & limits on the authentication page.
Endpoints
Both endpoints share the same query semantics — filter by fiscal_year, agency, or account and page through results with cursor and limit.
Enacted appropriation amounts by Treasury Account Symbol, keyed to a fiscal year and Congress.
Request
The endpoint accepts the following query parameters.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| congress | query | integer | optional | Filter to a single Congress number (e.g. 118). |
| fiscal_year | query | integer | optional | Filter to a single fiscal year (e.g. 2024). |
| agency | query | string | optional | Filter to a single agency by name (case-insensitive substring) — e.g. "Education". |
| bureau_code | query | string | optional | OMB bureau code, e.g. 91-1000 for the Department of Education. |
| account | query | string | optional | Substring match on the account title. |
| cursor | query | string | optional | Opaque pagination cursor returned in the previous response. |
| limit | query | integer | optional | Page size, 1–100. Defaults to 25. |
Run it — curl
# FY 2024 Department of Education appropriations
curl 'https://api.archivist.dev/budgets/appropriations?fiscal_year=2024&agency=Education' \
-H "Authorization: Bearer $ARCHIVIST_KEY"Run it — JavaScript
Plain fetch — no SDK, no runtime dependency. The key reads from env at server startup.
const res = await fetch(
'https://api.archivist.dev/budgets/appropriations?fiscal_year=2024&agency=Education',
{ headers: { Authorization: `Bearer ${process.env.ARCHIVIST_KEY}` } },
);
const { items, nextCursor } = await res.json();
for (const a of items) {
console.log(`${a.account_title} — $${a.appropriation_amount.current.toLocaleString()}`);
}Response
Successful responses are 200 OK with the shape below. Errors come back as { "error": "..." } — see the error reference for the full status table.
| Field | Type | Required | Description |
|---|---|---|---|
| items | AppropriationItem[] | required | Page of appropriation records, newest fiscal year first. |
| items[].account_id | string | required | Stable Treasury account id, e.g. 091-2024-091-1000. |
| items[].account_title | string | required | Plain-language account title, e.g. "Innovation and Improvement". |
| items[].agency | string | required | Owning agency as recorded in the apportionment. |
| items[].bureau | string | null | required | Bureau within the agency, or null if the appropriation is agency-wide. |
| items[].fiscal_year | integer | required | Fiscal year the appropriation covers. |
| items[].appropriation_amount.current | number | required | Enacted current-year amount in nominal USD. |
| items[].appropriation_amount.mandatory_discretionary | "mandatory" | "discretionary" | required | Whether the appropriation is mandatory or discretionary. |
| items[].appropriation_amount.supplemental | boolean | required | True when the amount was a supplemental appropriation. |
| items[].treasury_symbol | string | required | Treasury Account Symbol (TAS), e.g. 091/2024/091-1000. |
| items[].congress | integer | required | Congress during whose session the appropriation was enacted. |
| items[].source_url | string | null | optional | Canonical appropriations.gov detail URL, when present. |
| nextCursor | string | null | required | Pass into the next page; null on the last page. |
{
"items": [
{
"account_id": "091-2024-091-1000",
"account_title": "Innovation and Improvement",
"agency": "Department of Education",
"bureau": "Office of Elementary and Secondary Education",
"fiscal_year": 2024,
"appropriation_amount": {
"current": 1736000000,
"mandatory_discretionary": "discretionary",
"supplemental": false
},
"treasury_symbol": "091/2024/091-1000",
"congress": 118,
"source_url": "https://www.appropriations.gov/fy2024/091-1000"
}
],
"nextCursor": null
}- appropriation_amount.current is in nominal dollars; the API does not adjust for inflation.
- A single Treasury Account Symbol (TAS) may appear across multiple fiscal years — query by fiscal_year to disambiguate.
- source_url is null for agency-wide or suppressed accounts that are not surfaced on appropriations.gov.
Monthly outlay and obligation amounts reported in the Monthly Treasury Statement (MTS).
Request
The endpoint accepts the following query parameters.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| congress | query | integer | optional | Filter to a single Congress number. |
| fiscal_year | query | integer | optional | Filter to a single fiscal year. |
| month | query | string | optional | Filter to a single month in YYYY-MM form (e.g. 2024-09). |
| agency | query | string | optional | Case-insensitive substring match on the agency name. |
| account | query | string | optional | Substring match on the account title. |
| cursor | query | string | optional | Opaque pagination cursor. |
| limit | query | integer | optional | Page size, 1–100. Defaults to 25. |
Run it — curl
# FY 2024-09 Department of Agriculture outlays
curl 'https://api.archivist.dev/budgets/outlays?fiscal_year=2024&month=2024-09&agency=Agriculture' \
-H "Authorization: Bearer $ARCHIVIST_KEY"Run it — JavaScript
Plain fetch — no SDK, no runtime dependency. The key reads from env at server startup.
const res = await fetch(
'https://api.archivist.dev/budgets/outlays?fiscal_year=2024&month=2024-09&agency=Agriculture',
{ headers: { Authorization: `Bearer ${process.env.ARCHIVIST_KEY}` } },
);
const { items } = await res.json();
const total = items.reduce((s, o) => s + o.outlay_amount, 0);
console.log(`Sept 2024 USDA outlays: $${total.toLocaleString()}`);Response
Successful responses are 200 OK with the shape below. Errors come back as { "error": "..." } — see the error reference for the full status table.
| Field | Type | Required | Description |
|---|---|---|---|
| items | OutlayItem[] | required | Page of monthly outlay aggregates. |
| items[].account_id | string | required | Stable Treasury account id, joins to /budgets/appropriations. |
| items[].fiscal_year | integer | required | Fiscal year the outlay applies to. |
| items[].month | string | required | Reporting month in YYYY-MM form. |
| items[].outlay_amount | number | required | Outlays for the month in nominal USD. |
| items[].obligations_amount | number | required | Obligations incurred for the month in nominal USD. |
| items[].agency | string | required | Owning agency as recorded in MTS. |
| items[].bureau | string | null | required | Bureau within the agency, or null if the line is agency-wide. |
| items[].congress | integer | required | Congress during whose session the outlay was reported. |
| nextCursor | string | null | required | Pass into the next page; null on the last page. |
{
"items": [
{
"account_id": "012-2024-012-1000",
"fiscal_year": 2024,
"month": "2024-09",
"outlay_amount": 18230000000,
"obligations_amount": 19450000000,
"agency": "Department of Agriculture",
"bureau": "Farm Service Agency",
"congress": 118
}
],
"nextCursor": null
}- Outlays are reported by Treasury on a monthly lag; the most recent full month is the default upper bound.
- account_id is the join key into /budgets/appropriations — resolve a specific line back to its enacted amount.
- Page by ascending month for time-series reads; the list endpoint is stable as new months land at the end.