Skip to content

Explore federal budget data

Beta — surface may change

The /api/budget/... endpoints and the budget-related shape leaves on /api/organizations/ and /api/entities/ are beta. The data is real and refreshed on the normal cadence, but field names, shape leaves, default fields, filter names, and URL paths may still change based on early-consumer feedback. Pin a specific request shape (?shape=...) in production code so a default-shape change can't move under you, and watch the changelog for the move-to-stable announcement. If you build something on this and a change would hurt, open an issue — we'd rather learn about it before locking the shape down.

The /api/budget/... surface exposes federal-account budget data — what Congress requested, what it enacted, what got apportioned to spend, what's been obligated, and what's actually been paid out. This guide walks you through the questions consumers actually ask of this data, with copy-paste requests for each.

If you've worked with USAspending's File A (account-level) or OMB's MAX feeds before, this is the same kind of data — pre-joined to FPDS contract activity, with pre-computed ratios and trends so you don't have to derive them yourself.

What's in here

Resource What it answers
GET /api/budget/accounts/ One row per (federal account × fiscal year). The full lifecycle (requested → enacted → apportioned → obligated → outlayed), contract vs assistance split, year-over-year + 5-year trends, next-year request signal.
GET /api/budget/accounts/{pk}/recipients/ Who actually got paid out of a given account — funding office × recipient × PIIDs, hydrated with the matching contract records.
GET /api/budget/accounts/{pk}/quarters/ Treasury Account Symbol (TAS)-grain quarterly flow — SF-133 obligations and outlays per quarter. FY21+.
?shape=*,appendix(*) on account detail President's Budget Appendix object-class breakdown — what kinds of spending Congress was asked to authorize (personnel, contractual services, grants, etc.).
?shape=*,narratives(*) on account detail Appendix narrative + appropriations text for the account.
?shape=budget_appropriation(*),budget_spending(*) on /api/organizations/{key}/ Rolls up budget data to an org. Departments get their appropriation; offices get their funding-office spending across the org's subtree.
GET /api/entities/{uei}/budget-flows/ Which federal accounts paid a given vendor — the inverse of the recipients drill-down.

Coverage windows differ across these surfaces (and across years for individual fields) because the underlying source documents do — Appendix runs FY08–FY27, the lifecycle rollup runs FY17–FY26, and SF-133 quarters begin in FY21. Each surface returns an empty list or null for FYs it can't cover.

Quick start

All requests need an X-API-KEY header. Set it once:

export TANGO_API_KEY="your-api-key-here"
import os
import requests

HEADERS = {"X-API-KEY": os.environ["TANGO_API_KEY"]}
BASE = "https://tango.makegov.com/api"

The 20 biggest accounts of the most recent fiscal year, by enacted budget authority:

curl -H "X-API-KEY: $TANGO_API_KEY" \
  "https://tango.makegov.com/api/budget/accounts/?limit=20"
resp = requests.get(f"{BASE}/budget/accounts/", params={"limit": 20}, headers=HEADERS)
for a in resp.json()["results"]:
    print(a["federal_account_symbol"], a["account_title"], a["enacted_ba"])

The default sort is -fiscal_year, -enacted_ba, so without filters or ordering you land on the largest accounts of the current year. Pass any of the filters in the next section to narrow.

Find accounts

By identity

federal_account_symbol is the canonical key ({agency_cgac}-{account_number} — e.g. 075-0512 for HHS's NIH research account). It's exact-match by default; __in accepts a comma-separated list.

?federal_account_symbol=075-0512&fiscal_year=2024
?federal_account_symbol__in=075-0512,075-0540&fiscal_year=2024

By agency

?agency_code=075                          # HHS, all years
?agency_code=075&fiscal_year__gte=2022    # HHS, recent years
?bureau_name__icontains=indian            # any bureau with "indian" in the name

agency_code is the 3-character CGAC. bureau_name is free-text from the source — use icontains for fuzzy matches.

By taxonomy

?bea_category=Defense
?on_off_budget=ON
?subfunction_code=051

bea_category is the Bureau of Economic Analysis category (Defense, Nondefense, Mandatory programs, Net interest, ...). subfunction_code is the OMB budget subfunction (e.g. 051 = national defense, 551 = health care services).

?search=acquisition+services+fund
?search=cybersecurity

Searches across account_title, agency_name, and bureau_name.

By dollar threshold

Every dollar field supports __gte / __lte:

?enacted_ba__gte=1000000000&fiscal_year=2024     # accounts ≥ $1B enacted in FY24
?contract_obligated__gte=500000000                # ≥ $500M in contract obligations

Spot pipeline anomalies

Three ratio-based questions surface anomalies in the appropriation pipeline.

Where did Congress give more than the President requested?

?enacted_to_requested_pct_capped__gte=1.1

enacted_to_requested_pct is the ratio of enacted BA to the President's request. Values above 1.0 mean Congress added money beyond the ask; values below mean it cut.

The _capped variants cap extreme values (typically at 5.0) to keep them sortable and chart-friendly. There's a corresponding _flag boolean if you want to filter to only the rows where the cap was applied.

Where's apportionment lagging vs enacted?

?apportioned_to_enacted_pct_capped__lte=0.5&fiscal_year=2024

A low apportioned-to-enacted ratio mid-year usually means OMB has been slow to release funds — a strong leading indicator for spending pushes later in the year.

Where's the obligation pipeline backed up?

?obligated_to_apportioned_pct_capped__lte=0.4&fiscal_year=2024&ba_growth_next_year_pct__gte=0.0

Apportioned money that hasn't been obligated mid-year is contract-pipeline pressure. Combine with ba_growth_next_year_pct__gte=0.0 to find accounts whose next-year request is also trending up — those are the ones the agency is likely re-justifying.

Forward-look: next year's request

Every account row carries next_year_requested_ba, ba_growth_next_year, and ba_growth_next_year_pct — derived from the President's most recent Budget submission against the current enacted level.

?ba_growth_next_year_pct__gte=0.5&contract_share_of_obligated_capped__gte=0.5

Accounts whose next-year request is ≥ 50% higher than current enacted, and whose obligations historically run ≥ 50% through contracts. Useful for finding "contract-heavy growth accounts" — the accounts most likely to drive new contract opportunities in the coming year.

The BUDGET_ACCOUNT_TRENDS_FIELDS cluster is opt-in — pass it explicitly in ?shape= to get year-over-year and 5-year trend signal:

?shape=federal_account_symbol,account_title,enacted_ba,enacted_ba_yoy_pct,enacted_ba_5yr_cagr,contract_obligated_5yr_cagr&agency_code=097&fiscal_year=2024
Field What it means
enacted_ba_yoy_pct Year-over-year change in enacted BA, vs the prior FY.
obligated_yoy_pct Year-over-year change in total obligations.
contract_obligated_yoy_pct Year-over-year change in contract-side obligations.
enacted_ba_5yr_cagr 5-year compound annual growth rate of enacted BA.
contract_obligated_5yr_cagr 5-year CAGR of contract obligations.

Pull the account detail

GET /api/budget/accounts/{pk}/

Returns a single account row with the default shape. To pull everything, pass ?shape=*:

GET /api/budget/accounts/{pk}/?shape=*

Add the Appendix breakdown

GET /api/budget/accounts/{pk}/?shape=*,appendix(*)

The appendix leaf returns the President's Budget Appendix object-class breakdown — the 16 OMB request buckets (personnel comp, travel, contractual services, grants, etc.) plus the appendix granule ID and PDF URL.

appendix is null for accounts with no object-class detail in the Appendix — typically large mandatory programs (e.g. Medicaid) whose breakdown isn't published.

Add the narrative text

GET /api/budget/accounts/{pk}/?shape=*,narratives(*)

narratives is a list (some accounts have multiple narrative entries per year, split by subaccount) containing the Appendix narrative and appropriations language. Text fields can be a few KB each — they're a separate leaf from appendix(*) so they only load when asked for.

Drill down to recipients

GET /api/budget/accounts/{pk}/recipients/
GET /api/budget/accounts/{pk}/recipients/?funding_organization_id={org_uuid}

One row per (funding office × recipient × account-year) on the contract side. Each row is hydrated with:

  • funding_office — full Department / Agency / Office hierarchy for the funding org.
  • recipient — UEI, legal name, DBA name. Resolvable via /api/entities/{uei}/.
  • contracts — minimal Contract shape (key, piid, naics, psc, obligated, award_date) for every contract under this (account, funding office, recipient) tuple. Use the key to follow back to the full Contract record.

Sorted by contract_obligated desc — the largest recipients first. Standard count / next / previous / results pagination.

Pull quarterly cash flow

GET /api/budget/accounts/{pk}/quarters/
GET /api/budget/accounts/{pk}/quarters/?tas=075-2024-2024-0512

One row per (Treasury Account Symbol × quarter × period type) for this account-year. A federal account typically rolls up several TAS (different appropriation-year vintages), so the response is a list.

Field Meaning
tas Treasury Account Symbol — full TAS code including appropriation year.
quarter 1 through 4.
period quarterly or cumulative — both are returned for each quarter.
obligated_quarterly, outlayed_quarterly Flow during the quarter.
obligated_cumulative, outlayed_cumulative Running total through end of the quarter.
quarterly_source Provenance flag — which SF-133 snapshot the row came from.

Coverage is FY21+. Earlier years return an empty page; use the account detail's lifecycle fields for FY17–FY20.

Roll budget data up to an organization

The Organization detail endpoint exposes budget rollups as two shape leaves. Use them when you want a budget view keyed by agency / office rather than by federal account.

GET /api/organizations/{key}/?shape=name,budget_appropriation(*),budget_spending(*)

budget_appropriation(*)

The dept-level appropriation rollup — sums every federal account whose agency_code matches the org's CGAC.

The payload carries a scope field so consumers can tell whose number they're looking at:

scope When What you're seeing
"self" Org is L1 (a department) The dept's own appropriation totals.
"department" Org is L2+ (an agency or office inside a department) The parent dept's totals (sub-orgs inherit the dept's CGAC). Useful as context on a sub-org page.

When summing across siblings, filter on scope == "self" to avoid double-counting — the same dept payload appears on every sub-org under it.

Returns null only for orgs with no CGAC at all (rare; the org has no usable budget signal).

?shape=name,budget_appropriation(*)                                  # default FY = latest
?shape=name,budget_appropriation[fiscal_year=2024](*)                # specific FY
?shape=name,budget_appropriation(cgac,fiscal_year,summary)           # narrow projection

The payload includes a top_accounts array (top 10 by enacted BA) for quick orientation.

budget_spending(*)

The funding-office-side rollup — aggregates contract spending where the org (or any descendant in the FH subtree) was the funding office. Walks the hierarchy via the denormalized l{level}_fh_key fields, so an L2 like "Technology Transformation Services" can roll up its L3/L4 grandchildren without you having to chase them yourself.

Returns null when nothing in the subtree has funding-office activity in the budget data.

?shape=name,budget_spending(*)
?shape=name,budget_spending[fiscal_year=2024](*)

summary.contract_obligated is the headline number; n_orgs_in_rollup tells you how many orgs participated (1 = the org itself; >1 = the org plus descendants).

Asking for both

Departments can request both leaves in one shot — budget_appropriation returns the dept totals (scope: "self"), budget_spending returns the dept's direct funding-office activity (most dept rollups are nominal; the real spending sits in sub-offices).

?shape=name,budget_appropriation(*),budget_spending(*)

Look up budget flows for a vendor

The inverse of the recipients drill-down — given a UEI, list the federal accounts that paid this vendor:

GET /api/entities/{uei}/budget-flows/
GET /api/entities/{uei}/budget-flows/?fiscal_year=2024

Each row is one (account × funding office × this UEI) flow, with surrounding account context (account title, agency, bureau, BEA category, total enacted BA, contract share of obligated) and a hydrated contracts list for the PIIDs in this flow. Sorted by contract_obligated desc — the largest accounts funding this vendor first.

This is the right surface for "show me everywhere money flowed to this vendor, with budget context." Note it's contract-side only — grants and other assistance aren't in this index.

A few things worth knowing

Capped vs raw ratios

Every ratio field comes in three forms — *_pct, *_pct_capped, and *_pct_capped_flag. The capped variant is bounded at a sensible upper limit (typically 5.0) so it sorts and charts cleanly without one extreme row blowing out an axis. The flag tells you whether the cap was actually applied for that row.

Use raw (obligated_to_apportioned_pct) when you need exact math; use capped (obligated_to_apportioned_pct_capped) when filtering, sorting, or visualizing.

Top-recipient arrays vs the drill-down

top_contract_recipients and top_grant_recipients on the account detail are lightweight name-only arrays — handy for a quick label on a card. For real recipient analysis use the /recipients/ drill-down (or /budget-flows/ from the vendor side) — it carries UEI, hydrated entity payload, PIIDs, and the full matching Contract records.

Coverage windows

Surface Years covered
/api/budget/accounts/ lifecycle FY17–FY26
appendix(*) FY08–FY27
narratives(*) FY08–FY27
/quarters/ FY21+
/recipients/, /budget-flows/ FY17–FY26 (matches lifecycle)
Org rollups (budget_appropriation, budget_spending) Whatever coverage the underlying lifecycle rollup has for the requested FY

When you ask for a year outside the covered window, lists return empty and shape leaves return null — no error, just absence.

Cache TTL on Organization rollups

/api/organizations/{key}/ is cached at the response level (1-week TTL by default). If you've just been added to a hierarchy and a budget rollup looks stale, that's expected — the cached version will turn over within the TTL window, or you can bust it by varying any query param. The budget data itself updates whenever the upstream SF-133 / Appendix / contract-share signals refresh.

What's intentionally not in this guide

  • Account-level forecasts / projections. Tango ships the President's next-year request as a single field (next_year_requested_ba) plus growth math, but doesn't model multi-year scenarios. Build those on top of the historic lifecycle + 5yr CAGR.
  • Apportionment line-item detail. OMB publishes line-item apportionments separately; Tango currently exposes only the rollup-level apportioned dollar amount per account, not the per-line restrictions.
  • Treasury outlay reconciliation. The outlay numbers are the SF-133 outlay totals as published. Reconciling against Treasury's daily statement is out of scope.

See also