references/api-basics.md
# API Basics — U.S. Treasury Fiscal Data
## Overview
- RESTful API — accepts HTTP GET requests only
- Returns JSON by default (also CSV, XML)
- No API key, no authentication, no registration required
- Open data, free for commercial and non-commercial use
- Current versions: v1 and v2 (check each dataset's page for which version applies)
## URL Structure
```
BASE URL + ENDPOINT + PARAMETERS
Base URL: https://api.fiscaldata.treasury.gov/services/api/fiscal_service
Endpoint: /v2/accounting/od/debt_to_penny
Params: ?fields=record_date,tot_pub_debt_out_amt&sort=-record_date&page[size]=5
Full URL:
https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny?fields=record_date,tot_pub_debt_out_amt&sort=-record_date&page[size]=5
```
- Endpoint components use lowercase + underscores
- Endpoint names are singular
## API Versioning
- **v1**: Earlier datasets (DTS, MTS, some debt tables)
- **v2**: Newer or updated datasets (Debt to Penny, TROR, avg interest rates)
- Check the specific dataset page at `fiscaldata.treasury.gov/datasets/` to confirm the version
## Verifying Endpoint Paths
Endpoint paths change when datasets are restructured. Always confirm the current path on the dataset's **API Quick Guide** before querying.
Authoritative sources (in order):
1. Dataset detail page at `https://fiscaldata.treasury.gov/datasets/{slug}/`
2. Gatsby page data: `https://fiscaldata.treasury.gov/page-data/datasets/{slug}/page-data.json` (look for `"endpoint"` fields)
3. [API endpoint table](https://fiscaldata.treasury.gov/api-documentation/#list-of-endpoints-table)
## Data Types
All field values in responses are **strings** (quoted), regardless of their logical type.
| Logical Type | dataTypes value | Example value | How to convert |
|---|---|---|---|
| String | `STRING` | `"Canada-Dollar"` | No conversion needed |
| Number | `NUMBER` | `"36123456789012.34"` | `float(value)` |
| Date | `DATE` | `"2024-03-31"` | `pd.to_datetime(value)` |
| Currency | `CURRENCY` | `"1234567.89"` | `float(value)` |
| Integer | `INTEGER` | `"42"` | `int(value)` |
| Percentage | `PERCENTAGE` | `"4.25"` | `float(value)` |
**Null values** appear as the string `"null"` (not Python `None` or JSON `null`).
```python
# Safe numeric conversion handling nulls
def safe_float(val):
return float(val) if val and val != "null" else None
```
## HTTP Methods
- **Only GET is supported**
- POST, PUT, DELETE return HTTP 405
## Rate Limiting
- HTTP 429 is returned when rate limited
- No documented fixed rate limit; implement retry with backoff for bulk requests
```python
import time
import requests
def get_with_retry(url, params, retries=3):
for attempt in range(retries):
resp = requests.get(url, params=params)
if resp.status_code == 429:
time.sleep(2 ** attempt)
continue
resp.raise_for_status()
return resp.json()
raise Exception("Rate limited after retries")
```
## Caching
- HTTP 304 (Not Modified) can be returned for cached responses
- Safe to cache responses; most datasets update daily, monthly, or quarterly
## Pagination Headers
Responses include pagination in two places:
- **`links` object** in the JSON body (`self`, `first`, `prev`, `next`, `last`)
- **`Link` HTTP header** with RFC 5988 relations (`rel="first"`, `rel="next"`, etc.)
Either can be used to navigate pages programmatically. See [response-format.md](response-format.md) for details.
## Data Registry
The [Fiscal Service Data Registry](https://fiscal.treasury.gov/data-registry/index.html) contains field definitions, authoritative sources, data types, and formats across federal government data.
references/datasets-debt.md
# Debt Datasets — U.S. Treasury Fiscal Data
## Debt to the Penny
**Endpoint:** `/v2/accounting/od/debt_to_penny`
**Frequency:** Daily
**Date Range:** 1993-04-01 to present
Tracks the exact total public debt outstanding each business day.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Date of record |
| `debt_held_public_amt` | CURRENCY | Debt held by the public |
| `intragov_hold_amt` | CURRENCY | Intragovernmental holdings |
| `tot_pub_debt_out_amt` | CURRENCY | **Total public debt outstanding** |
```python
# Current national debt
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny",
params={"sort": "-record_date", "page[size]": 1}
)
latest = resp.json()["data"][0]
print(f"As of {latest['record_date']}: ${float(latest['tot_pub_debt_out_amt']):,.2f}")
# Debt over the last year
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny",
params={
"fields": "record_date,tot_pub_debt_out_amt",
"filter": "record_date:gte:2024-01-01",
"sort": "-record_date"
}
)
df = pd.DataFrame(resp.json()["data"])
df["tot_pub_debt_out_amt"] = df["tot_pub_debt_out_amt"].astype(float)
```
## Historical Debt Outstanding
**Endpoint:** `/v2/accounting/od/debt_outstanding`
**Frequency:** Annual
**Date Range:** 1790 to present
Annual record of U.S. national debt going back to the founding of the republic.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Year-end date |
| `debt_outstanding_amt` | CURRENCY | Total debt outstanding |
```python
# Full historical debt series
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_outstanding",
params={"sort": "-record_date", "page[size]": 10000}
)
df = pd.DataFrame(resp.json()["data"])
```
## Schedules of Federal Debt
**Endpoint:** `/v1/accounting/od/schedules_fed_debt`
**Frequency:** Monthly
**Date Range:** October 2005 to present
Monthly breakdown of federal debt by security type and component.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | End of month date |
| `security_type_desc` | STRING | Type of security |
| `security_class_desc` | STRING | Security class |
| `debt_outstanding_amt` | CURRENCY | Outstanding debt |
## Schedules of Federal Debt by Day
Two daily data tables under `/v1/accounting/od/`:
| Table | Endpoint | Description |
|-------|----------|-------------|
| Daily Activity | `/v1/accounting/od/schedules_fed_debt_daily_activity` | Daily debt activity |
| Daily Summary | `/v1/accounting/od/schedules_fed_debt_daily_summary` | Daily debt summary |
**Related:** `/v1/accounting/od/schedules_fed_debt_fytd` — fiscal year-to-date schedules.
## Treasury Report on Receivables (TROR)
**Endpoint:** `/v2/debt/tror`
**Frequency:** Quarterly
**Date Range:** December 2016 to present
Federal agency compliance and receivables data. Also includes:
- `/v2/debt/tror/data_act_compliance` — 120 Day Delinquent Debt Referral Compliance Report
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Quarter end date |
| `funding_type_desc` | STRING | Type of funding |
| `total_receivables_delinquent_amt` | CURRENCY | Delinquent amount |
```python
# TROR data, sorted by funding type
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/debt/tror",
params={"sort": "funding_type_id"}
)
```
## Gift Contributions to Reduce the Public Debt
**Endpoint:** `/v2/accounting/od/gift_contributions`
**Frequency:** Monthly
**Date Range:** September 1996 to present
Records voluntary contributions from the public to reduce the national debt.
## Interest Expense on the Public Debt Outstanding
**Endpoint:** `/v2/accounting/od/interest_expense`
**Frequency:** Monthly
**Date Range:** May 2010 to present
Monthly interest expense broken down by security type.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Month end date |
| `security_type_desc` | STRING | Security type |
| `expense_net_amt` | CURRENCY | Net interest expense |
| `expense_gross_amt` | CURRENCY | Gross interest expense |
```python
# Get total interest expense by month
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/interest_expense",
params={
"fields": "record_date,expense_net_amt",
"filter": "record_date:gte:2020-01-01",
"sort": "-record_date"
}
)
df = pd.DataFrame(resp.json()["data"])
df["expense_net_amt"] = df["expense_net_amt"].astype(float)
```
## Advances to State Unemployment Funds (Title XII)
**Endpoint:** `/v2/accounting/od/title_xii`
**Frequency:** Daily
**Date Range:** October 2016 to present
States and territories borrowing from the federal Unemployment Trust Fund.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Date of record |
| `state_nm` | STRING | State name |
| `debt_outstanding_amt` | CURRENCY | Outstanding advance amount |
references/datasets-fiscal.md
# Fiscal Statement Datasets — U.S. Treasury Fiscal Data
## Daily Treasury Statement (DTS)
The DTS dataset has **9 data tables**, all under `/v1/accounting/dts/`. Updated daily (business days).
**Date Range:** October 2005 to present
### DTS Tables
| Table | Endpoint | Description |
|-------|----------|-------------|
| Operating Cash Balance | `/v1/accounting/dts/operating_cash_balance` | Treasury General Account balance |
| Deposits & Withdrawals | `/v1/accounting/dts/deposits_withdrawals_operating_cash` | Changes to TGA |
| Public Debt Transactions | `/v1/accounting/dts/public_debt_transactions` | Issues and redemptions of securities |
| Adjustment of Public Debt | `/v1/accounting/dts/adjustment_public_debt_transactions_cash_basis` | Cash basis adjustments |
| Debt Subject to Limit | `/v1/accounting/dts/debt_subject_to_limit` | Debt vs. statutory limit |
| Inter-Agency Tax Transfers | `/v1/accounting/dts/inter_agency_tax_transfers` | Intra-government tax transfers |
| Federal Tax Deposits | `/v1/accounting/dts/federal_tax_deposits` | Tax deposit activity |
| Short-Term Cash Investments | `/v1/accounting/dts/short_term_cash_investments` | Cash investment activity |
| Income Tax Refunds Issued | `/v1/accounting/dts/income_tax_refunds_issued` | Tax refund issuances |
### Common DTS Fields
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Business date |
| `account_type` | STRING | Account/balance type |
| `open_today_bal` | CURRENCY | Opening balance |
| `open_month_bal` | CURRENCY | Opening month balance |
| `open_fiscal_year_bal` | CURRENCY | Opening fiscal year balance |
| `close_today_bal` | CURRENCY | Closing balance |
| `transaction_today_amt` | CURRENCY | Today's transaction amount |
| `transaction_mtd_amt` | CURRENCY | Month-to-date amount |
| `transaction_fytd_amt` | CURRENCY | Fiscal year-to-date amount |
```python
# Get current Treasury General Account (TGA) balance
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/dts/operating_cash_balance",
params={"sort": "-record_date", "page[size]": 5}
)
for row in resp.json()["data"]:
print(f"{row['record_date']}: ${float(row['close_today_bal']):,.0f}M (closing balance)")
# Get deposits and withdrawals for a specific period
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/dts/deposits_withdrawals_operating_cash",
params={
"filter": "record_date:gte:2024-01-01,record_date:lte:2024-01-31",
"sort": "record_date",
"page[size]": 1000
}
)
```
### Aggregation Example (DTS)
```python
# Get sum of today's transaction amounts by transaction type
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/dts/deposits_withdrawals_operating_cash",
params={
"fields": "record_date,transaction_type,transaction_today_amt",
"filter": "record_date:eq:2024-01-15"
}
)
```
---
## Monthly Treasury Statement (MTS)
The MTS dataset has **18 data tables**, all under `/v1/accounting/mts/`. Updated monthly.
**Date Range:** October 1980 to present
### MTS Tables
| Endpoint | Description |
|----------|-------------|
| `/v1/accounting/mts/mts_table_1` | Summary of receipts, outlays, and deficit/surplus |
| `/v1/accounting/mts/mts_table_2` | Summary of budget and off-budget results |
| `/v1/accounting/mts/mts_table_3` | Summary of receipts and outlays |
| `/v1/accounting/mts/mts_table_4` | Receipts of the U.S. Government |
| `/v1/accounting/mts/mts_table_5` | Outlays of the U.S. Government |
| `/v1/accounting/mts/mts_table_5m` | Receipts and outlays by month |
| `/v1/accounting/mts/mts_table_6` | Means of financing the deficit or disposition of surplus |
| `/v1/accounting/mts/mts_table_6a` | Analysis of change in excess of liabilities |
| `/v1/accounting/mts/mts_table_6b` | Securities issued under special financing authorities |
| `/v1/accounting/mts/mts_table_6c` | Federal agency borrowing via Treasury securities |
| `/v1/accounting/mts/mts_table_6d` | Investments of federal accounts in federal securities |
| `/v1/accounting/mts/mts_table_6e` | Guaranteed and direct loan financing, net activity |
| `/v1/accounting/mts/mts_table_7` | Receipts and outlays by month |
| `/v1/accounting/mts/mts_table_8` | Trust fund impact on budget results and holdings |
| `/v1/accounting/mts/mts_table_9` | Summary of receipts by source and outlays by function |
| `/v1/accounting/mts/mts_table_9_outlays_functions_subfunctions` | Outlays by function and subfunction |
| `/v1/accounting/mts/mts_distributed_offsetting_receipts` | Distributed offsetting receipts |
| `/v1/accounting/mts/mts_receipts_outlays_deficit_surplus` | Receipts, outlays, and deficit/surplus |
### Common MTS Fields
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Month end date |
| `record_fiscal_year` | STRING | Fiscal year (Oct–Sep) |
| `record_fiscal_quarter` | STRING | Fiscal quarter (1–4) |
| `classification_desc` | STRING | Line item description |
| `classification_id` | STRING | Line item code |
| `parent_id` | STRING | Parent classification ID |
| `current_month_gross_rcpt_amt` | CURRENCY | Current month gross receipts |
| `current_fytd_gross_rcpt_amt` | CURRENCY | Fiscal year-to-date gross receipts |
| `prior_fytd_gross_rcpt_amt` | CURRENCY | Prior year fiscal-year-to-date |
```python
# MTS Table 1: Summary of receipts and outlays
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/mts/mts_table_1",
params={
"filter": "record_fiscal_year:eq:2024",
"sort": "record_date"
}
)
df = pd.DataFrame(resp.json()["data"])
# MTS Table 9: Get line 120 (Total Receipts) for most recent period
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/mts/mts_table_9",
params={
"filter": "line_code_nbr:eq:120",
"sort": "-record_date",
"page[size]": 1
}
)
```
---
## U.S. Government Revenue Collections
**Endpoint:** `/v2/revenue/rcm`
**Frequency:** Daily
**Date Range:** October 2004 to present
Daily tax and non-tax revenue collections.
---
## Financial Report of the U.S. Government
**Endpoint:** (8 tables)
**Frequency:** Annual
**Date Range:** September 1995 to present (FY2024 latest)
Annual audited financial statements. Includes:
- Balance sheets
- Statement of net cost
- Statement of operations
- Statement of changes in net position
---
## Monthly Treasury Disbursements
**Frequency:** Monthly
**Date Range:** October 2013 to present
Monthly federal disbursements data.
---
## Receipts by Department
**Endpoint:** `/v1/accounting/od/receipts_by_department`
**Frequency:** Annual
**Date Range:** September 2015 to present
Annual breakdown of federal receipts by department.
---
## Treasury Managed Accounts
**Frequency:** Quarterly
**Date Range:** December 2022 to present (3 data tables)
Treasury-managed trust and special funds account data.
---
## Treasury Bulletin
**Frequency:** Quarterly
**Date Range:** March 2021 to present (13 tables)
Quarterly financial report covering government finances, public debt, savings bonds, and more. Endpoints use the `/v1/accounting/tb/` prefix (not `/v1/accounting/od/`).
| Endpoint | Description |
|----------|-------------|
| `/v1/accounting/tb/esf1_balances` | Exchange Stabilization Fund balances |
| `/v1/accounting/tb/esf2_statement_net_cost` | ESF statement of net cost |
| `/v1/accounting/tb/fcp1_weekly_report_major_market_participants` | Major market participants (weekly) |
| `/v1/accounting/tb/fcp2_monthly_report_major_market_participants` | Major market participants (monthly) |
| `/v1/accounting/tb/fcp3_quarterly_report_large_market_participants` | Large market participants (quarterly) |
| `/v1/accounting/tb/ffo5_internal_revenue_by_state` | Internal revenue receipts by state |
| `/v1/accounting/tb/ffo6_customs_border_protection_collections` | Customs and border protection collections |
| `/v1/accounting/tb/ofs1_distribution_federal_securities_class_investors_type_issues` | Distribution of federal securities by class and investor |
| `/v1/accounting/tb/ofs2_estimated_ownership_treasury_securities` | Estimated ownership of Treasury securities |
| `/v1/accounting/tb/pdo1_offerings_regular_weekly_treasury_bills` | Offerings of regular weekly Treasury bills |
| `/v1/accounting/tb/pdo2_offerings_marketable_securities_other_regular_weekly_treasury_bills` | Other marketable securities offerings |
| `/v1/accounting/tb/uscc1_amounts_outstanding_circulation` | Amounts outstanding and in circulation |
| `/v1/accounting/tb/uscc2_amounts_outstanding_circulation` | Amounts outstanding and in circulation (continued) |
references/datasets-interest-rates.md
# Interest Rates & Exchange Rate Datasets — U.S. Treasury Fiscal Data
## Average Interest Rates on U.S. Treasury Securities
**Endpoint:** `/v2/accounting/od/avg_interest_rates`
**Frequency:** Monthly
**Date Range:** January 2001 to present
Average interest rates for marketable and non-marketable Treasury securities, broken down by security type.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Month end date |
| `security_desc` | STRING | Security description (e.g., "Treasury Bills") |
| `security_type_desc` | STRING | "Marketable" or "Non-marketable" |
| `avg_interest_rate_amt` | PERCENTAGE | Average interest rate (%) |
```python
# Get average rates for all marketable securities, most recent month
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates",
params={
"filter": "security_type_desc:eq:Marketable",
"sort": "-record_date",
"page[size]": 50
}
)
df = pd.DataFrame(resp.json()["data"])
latest = df[df["record_date"] == df["record_date"].max()]
print(latest[["security_desc", "avg_interest_rate_amt"]])
# Historical rate for a specific security type
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates",
params={
"fields": "record_date,avg_interest_rate_amt",
"filter": "security_desc:eq:Treasury Notes,record_date:gte:2010-01-01",
"sort": "-record_date"
}
)
```
**Common security descriptions:**
- `Treasury Bills`
- `Treasury Notes`
- `Treasury Bonds`
- `Treasury Inflation-Protected Securities (TIPS)`
- `Treasury Floating Rate Notes (FRN)`
- `Federal Financing Bank`
- `United States Savings Securities`
- `Government Account Series`
- `Total Marketable`
- `Total Non-marketable`
- `Total Interest-bearing Debt`
---
## Treasury Reporting Rates of Exchange
**Endpoint:** `/v1/accounting/od/rates_of_exchange`
**Frequency:** Quarterly
**Date Range:** March 2001 to present
Official Treasury exchange rates for foreign currencies used by federal agencies for reporting purposes. Updated quarterly (March 31, June 30, September 30, December 31).
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Quarter end date |
| `country` | STRING | Country name |
| `currency` | STRING | Currency name |
| `country_currency_desc` | STRING | Combined "Country-Currency" (e.g., "Canada-Dollar") |
| `exchange_rate` | NUMBER | Units of foreign currency per 1 USD |
| `effective_date` | DATE | Date rate became effective |
```python
# Get all current exchange rates (latest quarter)
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/rates_of_exchange",
params={"sort": "-record_date", "page[size]": 200}
)
df = pd.DataFrame(resp.json()["data"])
latest_date = df["record_date"].max()
current_rates = df[df["record_date"] == latest_date].copy()
current_rates["exchange_rate"] = current_rates["exchange_rate"].astype(float)
print(current_rates[["country_currency_desc", "exchange_rate"]].to_string())
# Euro rate history
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/rates_of_exchange",
params={
"fields": "record_date,exchange_rate",
"filter": "country_currency_desc:eq:Euro Zone-Euro",
"sort": "-record_date",
"page[size]": 100
}
)
euro_df = pd.DataFrame(resp.json()["data"])
euro_df["exchange_rate"] = euro_df["exchange_rate"].astype(float)
euro_df["record_date"] = pd.to_datetime(euro_df["record_date"])
```
---
## TIPS and CPI Data
Two data tables under `/v1/accounting/od/`:
| Table | Endpoint | Description |
|-------|----------|-------------|
| Summary | `/v1/accounting/od/tips_cpi_data_summary` | Reference CPI numbers and daily index ratios (summary) |
| Detail | `/v1/accounting/od/tips_cpi_data_detail` | Reference CPI numbers and daily index ratios (detail) |
**Frequency:** Monthly
**Date Range:** April 1998 to present
Treasury Inflation-Protected Securities (TIPS) reference CPI data and index ratios used to calculate TIPS values.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Date of record |
| `index_ratio` | NUMBER | Index ratio for TIPS adjustment |
| `ref_cpi` | NUMBER | Reference CPI value |
---
## FRN Daily Indexes
**Endpoint:** `/v1/accounting/od/frn_daily_indexes`
**Frequency:** Monthly release (daily index rows per CUSIP)
**Date Range:** April 2024 to present
Daily index values for Treasury Floating Rate Notes (FRNs). The rate is based on the 13-week Treasury bill auction rate. Data is published monthly with daily index rows for each CUSIP.
---
## Treasury Certified Interest Rates
Four certification periods, each with their own endpoint set:
### Annual Certification
**Frequency:** Annual
**Date Range:** October 2006 to present (9 data tables)
### Monthly Certification
**Frequency:** Monthly
**Date Range:** October 2006 to present (6 data tables)
### Quarterly Certification
**Frequency:** Quarterly
**Date Range:** October 2006 to present (4 data tables)
### Semi-Annual Certification
**Frequency:** Semi-Annual
**Date Range:** January 2008 to present (1 data table)
These certified interest rates are used for federal loans, financing programs, and other purposes requiring official Treasury-certified rates.
---
## Federal Credit Similar Maturity Rates
**Endpoint:** `/v1/accounting/od/federal_maturity_rates`
**Frequency:** Annual
**Date Range:** September 1992 to present
Interest rates used for valuing federal credit programs (loans and loan guarantees) under the Federal Credit Reform Act.
---
## Historical Qualified Tax Credit Bond Interest Rates
**Frequency:** Daily (Discontinued)
**Date Range:** March 2009 – January 2018
Historical interest rates for Qualified Tax Credit Bonds (QTCB). No longer updated.
---
## State and Local Government Series (SLGS) Daily Rate Table
**Endpoint:** `/v1/accounting/od/slgs_savings_bonds` (2 tables)
**Frequency:** Daily
**Date Range:** June 1992 to present
Daily interest rates for State and Local Government Series securities, used by state and local issuers to comply with federal tax law arbitrage restrictions.
references/datasets-securities.md
# Securities & Savings Bonds Datasets — U.S. Treasury Fiscal Data
## Treasury Securities Auctions Data
**Endpoint:** `/v1/accounting/od/auctions_query`
**Frequency:** As Needed
**Date Range:** November 1979 to present
Historical data on Treasury securities auctions including bills, notes, bonds, TIPS, and FRNs.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Auction date |
| `security_type` | STRING | Bill, Note, Bond, TIPS, FRN |
| `security_term` | STRING | e.g., "4-Week", "2-Year", "10-Year" |
| `cusip` | STRING | CUSIP identifier |
| `offering_amt` | CURRENCY | Amount offered |
| `accepted_comp_bid_rate_amt` | PERCENTAGE | High accepted competitive bid rate |
| `bid_to_cover_ratio` | NUMBER | Bid-to-cover ratio |
| `total_accepted_amt` | CURRENCY | Total accepted amount |
| `indirect_bid_pct_accepted` | PERCENTAGE | Indirect bidder percentage |
| `issue_date` | DATE | Issue/settlement date |
| `maturity_date` | DATE | Maturity date |
```python
# Get recent 10-year Treasury note auctions
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/auctions_query",
params={
"filter": "security_type:eq:Note,security_term:eq:10-Year",
"sort": "-record_date",
"page[size]": 10
}
)
df = pd.DataFrame(resp.json()["data"])
# Get all auctions in 2024
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/auctions_query",
params={
"filter": "record_date:gte:2024-01-01,record_date:lte:2024-12-31",
"sort": "-record_date",
"page[size]": 10000
}
)
```
## Treasury Securities Upcoming Auctions
**Endpoint:** `/v1/accounting/od/upcoming_auctions`
**Frequency:** As Needed
**Date Range:** March 2024 to present
Announced but not yet settled auction schedule.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `auction_date` | DATE | Scheduled auction date |
| `security_type` | STRING | Security type |
| `security_term` | STRING | Maturity term |
| `offering_amt` | CURRENCY | Announced offering amount |
```python
# Get upcoming auctions
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/upcoming_auctions",
params={"sort": "auction_date"}
)
upcoming = pd.DataFrame(resp.json()["data"])
print(upcoming[["auction_date", "security_type", "security_term", "offering_amt"]])
```
## Record-Setting Treasury Securities Auction Data
**Frequency:** As Needed
Tracks auction records (largest, highest rate, lowest rate, etc.) for each security type and term.
## Treasury Securities Buybacks
**Frequency:** As Needed (2 data tables)
**Date Range:** March 2000 to present
Data on Treasury's secondary market buyback (repurchase) operations. Active since the program's relaunch in 2024.
| Table | Endpoint | Description |
|-------|----------|-------------|
| Buybacks Operations | `/v1/accounting/od/buybacks_operations` | Announcements and results per operation |
| Security Details | `/v1/accounting/od/buybacks_security_details` | Security details per operation |
```python
# Recent buyback operations
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/buybacks_operations",
params={"sort": "-operation_date", "page[size]": 10}
)
df = pd.DataFrame(resp.json()["data"])
print(df[["operation_date", "settlement_date"]].head())
```
---
## I Bonds Interest Rates
**Endpoint:** `/v1/accounting/od/i_bonds_interest_rates`
**Frequency:** Semi-Annual (May and November)
**Date Range:** September 1998 to present
Composite interest rates for Series I Savings Bonds, including fixed rate and inflation rate components.
**Key fields:**
| Field | Type | Description |
|-------|------|-------------|
| `earning_period_start` | DATE | Start of six-month earning period |
| `earning_period_end` | DATE | End of six-month earning period |
| `fixed_rate` | PERCENTAGE | Fixed rate component |
| `semi_annual_inflation_rate` | PERCENTAGE | Semi-annual CPI-U inflation rate |
| `combined_rate` | PERCENTAGE | Combined composite rate |
```python
# Current I Bond rates
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/i_bonds_interest_rates",
params={"sort": "-earning_period_start", "page[size]": 5}
)
df = pd.DataFrame(resp.json()["data"])
latest = df.iloc[0]
print(f"Current I Bond rate: {latest['combined_rate']}%")
print(f" Fixed rate: {latest['fixed_rate']}%")
print(f" Inflation component: {latest['semi_annual_inflation_rate']}%")
```
## U.S. Treasury Savings Bonds: Issues, Redemptions & Maturities
Three data tables under `/v1/accounting/od/`:
| Table | Endpoint | Description |
|-------|----------|-------------|
| Issues, Redemptions & Maturities | `/v1/accounting/od/savings_bonds_report` | Monthly statistics by series |
| Matured Unredeemed Debt | `/v1/accounting/od/savings_bonds_mud` | Matured unredeemed debt |
| Piece Information by Series | `/v1/accounting/od/savings_bonds_pcs` | Piece information by series |
**Frequency:** Monthly
**Date Range:** September 1998 to present
Monthly statistics on Series EE, Series I, and Series HH savings bonds outstanding, issued, and redeemed.
**Key fields (savings_bonds_report):**
| Field | Type | Description |
|-------|------|-------------|
| `record_date` | DATE | Month end date |
| `series_cd` | STRING | Bond series (EE, I, HH) |
| `issued_amt` | CURRENCY | Amount issued |
| `redeemed_amt` | CURRENCY | Amount redeemed |
| `matured_amt` | CURRENCY | Amount matured |
| `outstanding_amt` | CURRENCY | Total outstanding |
## Savings Bonds Value Files
**Frequency:** Semi-Annual
**Date Range:** May 1992 to present
Files for calculating current redemption values of savings bonds.
## Accrual Savings Bonds Redemption Tables (Discontinued)
**Endpoint:** `/v2/accounting/od/redemption_tables`
**Frequency:** Discontinued (last updated 2022)
**Date Range:** March 1999 – May 2023
Monthly redemption value tables for historical savings bonds.
## Savings Bonds Securities Sold (Discontinued)
**Frequency:** Discontinued
**Date Range:** October 1998 – June 2022
---
## State and Local Government Series (SLGS) Securities
**Endpoint:** `/v2/accounting/od/slgs_statistics`
**Frequency:** Daily
**Date Range:** October 1998 to present
SLGS securities outstanding data — non-marketable special purpose securities sold to state and local governments.
## Monthly State and Local Government Series (SLGS) Securities Program
**Frequency:** Monthly
**Date Range:** March 2014 to present
Monthly statistics on the SLGS program.
---
## Electronic Securities Transactions
**Frequency:** Monthly (8 data tables)
**Date Range:** January 2000 to present
Electronic book-entry transactions for Treasury securities in the TRADES (Treasury/Reserve Automated Debt Entry System) system.
---
## Federal Investments Program
### Interest Cost by Fund
**Frequency:** Monthly
**Date Range:** October 2001 to present
Monthly interest cost by government trust fund for invested federal funds.
### Principal Outstanding
**Frequency:** Monthly (2 tables)
**Date Range:** October 2017 to present
### Statement of Account
**Frequency:** Monthly (3 tables)
**Date Range:** November 2011 to present
---
## Federal Borrowings Program
### Distribution and Transaction Data
**Frequency:** Daily (2 tables)
**Date Range:** September 2000 to present
### Interest on Uninvested Funds
**Frequency:** Quarterly
**Date Range:** December 2016 to present
### Summary General Ledger Balances Report
**Frequency:** Monthly (2 tables)
**Date Range:** October 2005 to present
references/examples.md
# Code Examples — U.S. Treasury Fiscal Data
## Python Examples
### Setup
```python
import requests
import pandas as pd
BASE_URL = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service"
def fetch(endpoint, **params):
resp = requests.get(f"{BASE_URL}{endpoint}", params=params)
resp.raise_for_status()
return resp.json()
```
### National Debt Tracker
```python
# Current total public debt
result = fetch("/v2/accounting/od/debt_to_penny",
sort="-record_date", **{"page[size]": 1})
d = result["data"][0]
debt = float(d["tot_pub_debt_out_amt"])
print(f"National debt as of {d['record_date']}: ${debt/1e12:.2f} trillion")
# Debt trend over last 5 years
result = fetch("/v2/accounting/od/debt_to_penny",
fields="record_date,tot_pub_debt_out_amt",
filter="record_date:gte:2020-01-01",
sort="-record_date", **{"page[size]": 10000})
df = pd.DataFrame(result["data"])
df["date"] = pd.to_datetime(df["record_date"])
df["debt_trillion"] = df["tot_pub_debt_out_amt"].astype(float) / 1e12
df = df.sort_values("date")
print(df[["date", "debt_trillion"]].tail(10))
```
### Federal Exchange Rates
```python
# All current Treasury exchange rates
result = fetch("/v1/accounting/od/rates_of_exchange",
sort="-record_date", **{"page[size]": 300})
df = pd.DataFrame(result["data"])
latest = df[df["record_date"] == df["record_date"].max()]
latest = latest.copy()
latest["exchange_rate"] = latest["exchange_rate"].astype(float)
latest = latest.sort_values("country_currency_desc")
print(latest[["country_currency_desc", "exchange_rate", "record_date"]].to_string(index=False))
# Convert USD amount to foreign currencies
def convert_usd(usd_amount, rates_df):
rates_df = rates_df.copy()
rates_df["value_in_foreign"] = usd_amount * rates_df["exchange_rate"].astype(float)
return rates_df[["country_currency_desc", "value_in_foreign"]]
conversions = convert_usd(1000, latest)
print(conversions.head(10))
```
### Treasury Securities Auction Analysis
```python
# Recent 10-year note auctions
result = fetch("/v1/accounting/od/auctions_query",
filter="security_type:eq:Note,security_term:eq:10-Year",
sort="-record_date", **{"page[size]": 20})
df = pd.DataFrame(result["data"])
numeric_cols = ["accepted_comp_bid_rate_amt", "bid_to_cover_ratio",
"total_accepted_amt", "indirect_bid_pct_accepted"]
for col in numeric_cols:
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors="coerce")
print(df[["record_date", "security_term", "accepted_comp_bid_rate_amt",
"bid_to_cover_ratio"]].head(10))
# Auction yield trend: 2-year vs 10-year
def get_auction_yields(term, n=24):
result = fetch("/v1/accounting/od/auctions_query",
fields="record_date,security_term,accepted_comp_bid_rate_amt",
filter=f"security_type:eq:Note,security_term:eq:{term}",
sort="-record_date", **{"page[size]": n})
df = pd.DataFrame(result["data"])
df["yield"] = df["accepted_comp_bid_rate_amt"].astype(float)
df["date"] = pd.to_datetime(df["record_date"])
return df[["date", "yield", "security_term"]].sort_values("date")
t2 = get_auction_yields("2-Year")
t10 = get_auction_yields("10-Year")
yield_curve = t2.merge(t10, on="date", suffixes=("_2y", "_10y"), how="inner")
yield_curve["spread"] = yield_curve["yield_10y"] - yield_curve["yield_2y"]
print("Yield curve spread (10y - 2y):")
print(yield_curve[["date", "yield_2y", "yield_10y", "spread"]].tail(10))
```
### Daily Treasury Statement Analysis
```python
# Recent Treasury General Account (TGA) balance
result = fetch("/v1/accounting/dts/operating_cash_balance",
sort="-record_date", **{"page[size]": 10})
df = pd.DataFrame(result["data"])
print("Treasury General Account Balances (most recent):")
for _, row in df.head(5).iterrows():
bal = float(row["close_today_bal"])
print(f" {row['record_date']}: ${bal:,.0f} million")
# Monthly total receipts and withdrawals
result = fetch("/v1/accounting/dts/deposits_withdrawals_operating_cash",
fields="record_date,transaction_type,transaction_today_amt",
filter="record_date:gte:2024-01-01",
sort="-record_date", **{"page[size]": 10000})
df = pd.DataFrame(result["data"])
df["amount"] = df["transaction_today_amt"].astype(float)
summary = df.groupby(["record_date", "transaction_type"])["amount"].sum().unstack()
print(summary.tail(10))
```
### Monthly Treasury Statement (Budget)
```python
# Federal budget receipts and outlays (MTS Table 1)
result = fetch("/v1/accounting/mts/mts_table_1",
filter="record_fiscal_year:eq:2024",
sort="record_date", **{"page[size]": 1000})
df = pd.DataFrame(result["data"])
# Get total receipts line (line code varies; filter by description)
receipts = df[df["classification_desc"].str.contains("Total Receipts", na=False, case=False)]
outlays = df[df["classification_desc"].str.contains("Total Outlays", na=False, case=False)]
print("FY2024 Monthly Summary:")
print(receipts[["record_date", "current_month_gross_rcpt_amt"]].head(12))
```
### Interest Rate Analysis
```python
# Average interest rates on all marketable Treasury securities
result = fetch("/v2/accounting/od/avg_interest_rates",
filter="security_type_desc:eq:Marketable,record_date:gte:2015-01-01",
sort="-record_date", **{"page[size]": 10000})
df = pd.DataFrame(result["data"])
df["date"] = pd.to_datetime(df["record_date"])
df["rate"] = df["avg_interest_rate_amt"].astype(float)
# Pivot to compare rates across security types
pivot = df.pivot_table(index="date", columns="security_desc", values="rate")
print(pivot.tail(5))
# I Bond rates history
result = fetch("/v1/accounting/od/i_bonds_interest_rates",
sort="-earning_period_start", **{"page[size]": 20})
df = pd.DataFrame(result["data"])
df["combined_rate"] = df["combined_rate"].astype(float)
df["fixed_rate"] = df["fixed_rate"].astype(float)
print("I Bond rate history:")
print(df[["earning_period_start", "fixed_rate", "combined_rate"]].head(10))
```
### Fiscal Year Summary
```python
def get_fiscal_year_summary(fy: int):
"""Get key fiscal metrics for a given fiscal year."""
# Total debt at end of FY
fy_end = f"{fy}-09-30"
result = fetch("/v2/accounting/od/debt_to_penny",
filter=f"record_date:lte:{fy_end}",
sort="-record_date", **{"page[size]": 1})
debt = float(result["data"][0]["tot_pub_debt_out_amt"]) / 1e12
# Interest expense for FY
result = fetch("/v2/accounting/od/interest_expense",
fields="record_date,expense_net_amt",
filter=f"record_fiscal_year:eq:{fy}",
**{"page[size]": 10000})
interest_df = pd.DataFrame(result["data"])
if not interest_df.empty:
total_interest = interest_df["expense_net_amt"].astype(float).sum() / 1e9
else:
total_interest = None
return {
"fiscal_year": fy,
"total_debt_trillion": round(debt, 2),
"interest_expense_billion": round(total_interest, 1) if total_interest else None
}
for fy in [2021, 2022, 2023, 2024]:
summary = get_fiscal_year_summary(fy)
print(f"FY{fy}: Debt=${summary['total_debt_trillion']}T, "
f"Interest=${summary['interest_expense_billion']}B")
```
---
## R Examples
```r
library(httr)
library(jsonlite)
BASE_URL <- "https://api.fiscaldata.treasury.gov/services/api/fiscal_service"
# National debt
response <- GET(paste0(BASE_URL, "/v2/accounting/od/debt_to_penny"),
query = list(sort = "-record_date", `page[size]` = 1))
data <- fromJSON(rawToChar(response$content))$data
cat(sprintf("Total debt: $%.2f trillion\n",
as.numeric(data$tot_pub_debt_out_amt) / 1e12))
# Exchange rates
response <- GET(paste0(BASE_URL, "/v1/accounting/od/rates_of_exchange"),
query = list(
fields = "country_currency_desc,exchange_rate,record_date",
filter = "record_date:gte:2024-01-01",
sort = "-record_date",
`page[size]` = 200
))
rates <- fromJSON(rawToChar(response$content))$data
rates$exchange_rate <- as.numeric(rates$exchange_rate)
head(rates)
# MTS Table 9: latest total receipts
response <- GET(paste0(BASE_URL, "/v1/accounting/mts/mts_table_9"),
query = list(
filter = "line_code_nbr:eq:120",
sort = "-record_date",
`page[size]` = 1
))
mts_data <- fromJSON(rawToChar(response$content))$data
cat("Latest total receipts line:", mts_data$current_month_gross_rcpt_amt, "\n")
```
---
## Discovering Available Fields
To find available fields for any endpoint, request a small sample and inspect the `meta.labels` and `meta.dataTypes`:
```python
result = fetch("/v2/accounting/od/debt_to_penny", **{"page[size]": 1})
meta = result["meta"]
for field, label in meta["labels"].items():
dtype = meta["dataTypes"].get(field, "?")
fmt = meta["dataFormats"].get(field, "?")
print(f"{field:40s} | {dtype:12s} | {label}")
```
## Finding Datasets
Browse the full list of 54 datasets and 179 data tables at:
- [Dataset Search](https://fiscaldata.treasury.gov/datasets/) — searchable dataset catalog
- [API endpoint table](https://fiscaldata.treasury.gov/api-documentation/#list-of-endpoints-table) — full endpoint list
references/parameters.md
# Query Parameters — U.S. Treasury Fiscal Data API
All parameters are optional. Combine them with `&` in the URL query string.
## `fields=` — Select Columns
Returns only the specified fields. Accepts a comma-separated list of field names.
```
?fields=record_date,tot_pub_debt_out_amt
?fields=country_currency_desc,exchange_rate,record_date
```
- If omitted, all fields are returned
- Invalid field names cause an error
- Omitting some fields can trigger **automatic aggregation** (see below)
### Aggregation / Auto-Sum
When the `fields=` parameter excludes some non-numeric fields, the API automatically groups by the remaining fields and sums numeric values.
```python
# Returns sum of transaction amounts grouped by record_date and transaction_type
params = {
"fields": "record_date,transaction_type,transaction_today_amt"
}
```
## `filter=` — Filter Records
Narrow results by field values. Multiple field filters are **comma-separated in a single `filter=` parameter**.
### Filter Syntax
```
filter=<field>:<operator>:<value>
filter=<field>:<operator>:<value>,<field>:<operator>:<value>
```
### Operators
| Operator | Meaning | Example |
|----------|---------|---------|
| `eq` | Equal to | `filter=record_date:eq:2024-03-31` |
| `lt` | Less than | `filter=exchange_rate:lt:1.5` |
| `lte` | Less than or equal | `filter=record_date:lte:2024-12-31` |
| `gt` | Greater than | `filter=record_fiscal_year:gt:2010` |
| `gte` | Greater than or equal | `filter=record_date:gte:2024-01-01` |
| `in` | Contained in set | `filter=country_currency_desc:in:(Canada-Dollar,Mexico-Peso)` |
### Date Filters
Use `YYYY-MM-DD` format for dates:
```
filter=record_date:gte:2024-01-01
filter=record_date:gte:2023-01-01,record_date:lte:2023-12-31
```
### Multi-Field Filters
```
filter=country_currency_desc:in:(Canada-Dollar,Mexico-Peso),record_date:gte:2024-01-01
```
### Common Filter Fields
Most endpoints have these standard date fields:
- `record_date` — The date of the record (YYYY-MM-DD)
- `record_fiscal_year` — Fiscal year (e.g., `2024`)
- `record_fiscal_quarter` — Fiscal quarter (1-4)
- `record_calendar_year` — Calendar year
- `record_calendar_month` — Calendar month (01-12)
## `sort=` — Sort Results
Sort by one or more fields. Prefix `-` for descending order.
```
?sort=-record_date # Most recent first
?sort=record_date # Oldest first
?sort=-record_fiscal_year,-record_fiscal_quarter # Nested sort
```
**Default:** Sorted by the first column (usually `record_date` ascending).
## `format=` — Output Format
```
?format=json # Default
?format=csv # Comma-separated values
?format=xml # XML
```
When using CSV or XML format, the response is the raw file content rather than JSON.
## `page[size]=` and `page[number]=` — Pagination
Controls how many records per page and which page to return.
```
?page[size]=100&page[number]=1 # Default (100 records, page 1)
?page[size]=10000 # Large page to reduce requests
?page[number]=5&page[size]=50 # 50 records starting at page 5
```
- Default page size: **100**
- Default page number: **1**
- Use `meta.total-pages` in the response to know how many pages exist
- Use `meta.total-count` for total record count
### Fetch All Records
For small result sets where `meta.total-pages` is 1, a single request with `page[size]=10000` is enough. Use `fetch_all()` below when pagination is required.
```python
import time
import requests
import pandas as pd
def fetch_all(endpoint, params=None, max_pages=50, max_records=500_000):
"""Fetch paginated results and return as DataFrame.
Stops when all pages are retrieved or when max_pages / max_records limits
are reached. Retries on HTTP 429 with exponential backoff.
"""
params = dict(params or {})
params["page[size]"] = min(params.get("page[size]", 10000), 10000)
params["page[number]"] = 1
base = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service"
all_data = []
for _ in range(max_pages):
for attempt in range(3):
resp = requests.get(f"{base}{endpoint}", params=params)
if resp.status_code == 429:
time.sleep(2 ** attempt)
continue
resp.raise_for_status()
break
else:
raise RuntimeError("Rate limited after retries")
result = resp.json()
if "error" in result:
raise ValueError(f"API error: {result['error']} — {result.get('message', '')}")
all_data.extend(result["data"])
if len(all_data) >= max_records:
all_data = all_data[:max_records]
break
meta = result["meta"]
if params["page[number]"] >= meta["total-pages"]:
break
params["page[number]"] += 1
time.sleep(0.1)
else:
raise RuntimeError(
f"Reached max_pages={max_pages}; increase limit or narrow filters"
)
return pd.DataFrame(all_data)
```
## Combining Parameters
```python
params = {
"fields": "country_currency_desc,exchange_rate,record_date",
"filter": "country_currency_desc:in:(Canada-Dollar,Euro),record_date:gte:2020-01-01",
"sort": "-record_date",
"format": "json",
"page[size]": 100,
"page[number]": 1
}
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/rates_of_exchange",
params=params
)
```
references/response-format.md
# Response Format — U.S. Treasury Fiscal Data API
## Response Structure (JSON)
```json
{
"data": [
{
"record_date": "2024-03-31",
"tot_pub_debt_out_amt": "34589629941.12"
}
],
"meta": {
"count": 100,
"labels": {
"record_date": "Record Date",
"tot_pub_debt_out_amt": "Total Public Debt Outstanding"
},
"dataTypes": {
"record_date": "DATE",
"tot_pub_debt_out_amt": "CURRENCY"
},
"dataFormats": {
"record_date": "YYYY-MM-DD",
"tot_pub_debt_out_amt": "10.2"
},
"total-count": 3790,
"total-pages": 38
},
"links": {
"self": "&page%5Bnumber%5D=1&page%5Bsize%5D=100",
"first": "&page%5Bnumber%5D=1&page%5Bsize%5D=100",
"prev": null,
"next": "&page%5Bnumber%5D=2&page%5Bsize%5D=100",
"last": "&page%5Bnumber%5D=38&page%5Bsize%5D=100"
}
}
```
## `meta` Object
| Field | Description |
|-------|-------------|
| `count` | Number of records in this response page |
| `total-count` | Total records matching the query (all pages) |
| `total-pages` | Total pages available at current page size |
| `labels` | Human-readable column labels |
| `dataTypes` | Logical data type: `STRING`, `NUMBER`, `DATE`, `CURRENCY`, `INTEGER`, `PERCENTAGE` |
| `dataFormats` | Format hints: `YYYY-MM-DD`, `10.2` (10 digits, 2 decimal), `String` |
## `links` Object
Use the `links` object to navigate pagination programmatically:
| Field | Value |
|-------|-------|
| `self` | Current page query params |
| `first` | First page |
| `prev` | Previous page (null if on first page) |
| `next` | Next page (null if on last page) |
| `last` | Last page |
The HTTP response also includes a **`Link` header** with RFC 5988 relations (`rel="first"`, `rel="prev"`, `rel="next"`, `rel="last"`). Either the JSON `links` object or the `Link` header can be used for pagination.
## `data` Object
Array of row objects. All values are **strings**, regardless of logical type.
## Response Codes
| Code | Meaning |
|------|---------|
| 200 | OK — successful GET |
| 304 | Not Modified — cached response |
| 400 | Bad Request — malformed URL or invalid parameter |
| 403 | Forbidden — invalid API key (N/A; no key required) |
| 404 | Not Found — endpoint does not exist |
| 405 | Method Not Allowed — non-GET request |
| 429 | Too Many Requests — rate limited |
| 500 | Internal Server Error |
## Error Object
When an error occurs, the response contains an error object instead of `data`:
```json
{
"error": "Invalid Query Param",
"message": "Invalid query parameter 'sorts' with value '[-record_date]'. For more information please see the documentation."
}
```
```python
resp = requests.get(url, params=params)
result = resp.json()
if "error" in result:
print(f"API Error: {result['error']}")
print(f"Message: {result['message']}")
elif resp.status_code != 200:
print(f"HTTP {resp.status_code}: {resp.text}")
else:
data = result["data"]
```
## Common Error Causes
- Invalid field name in `fields=` parameter
- Invalid filter operator (use `eq`, `gte`, `lte`, `gt`, `lt`, `in`)
- Wrong date format (must be `YYYY-MM-DD`)
- Accessing a v2 endpoint with `/v1/` in the URL
- `sort` field not available in the endpoint
## Parsing Responses
```python
import requests
import pandas as pd
def api_to_dataframe(endpoint, params=None):
"""Fetch API data and return a typed DataFrame."""
base = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service"
resp = requests.get(f"{base}{endpoint}", params=params)
resp.raise_for_status()
result = resp.json()
df = pd.DataFrame(result["data"])
meta = result["meta"]
# Apply type conversions using metadata
for col, dtype in meta["dataTypes"].items():
if col not in df.columns:
continue
if dtype in ("NUMBER", "CURRENCY", "PERCENTAGE"):
df[col] = pd.to_numeric(df[col].replace("null", None), errors="coerce")
elif dtype == "DATE":
df[col] = pd.to_datetime(df[col].replace("null", None), errors="coerce")
elif dtype == "INTEGER":
df[col] = pd.to_numeric(df[col].replace("null", None), errors="coerce").astype("Int64")
return df, meta
# Usage
df, meta = api_to_dataframe(
"/v2/accounting/od/debt_to_penny",
params={"sort": "-record_date", "page[size]": 30}
)
print(f"Total records available: {meta['total-count']}")
print(df[["record_date", "tot_pub_debt_out_amt"]].head())
```
## CSV Format Response
When `format=csv` is specified, the response body is plain CSV text (not JSON):
```python
import io
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny",
params={"format": "csv", "sort": "-record_date", "page[size]": 100}
)
df = pd.read_csv(io.StringIO(resp.text))
```
## XML Format Response
When `format=xml` is specified, the response body is XML:
```python
import xml.etree.ElementTree as ET
resp = requests.get(
"https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny",
params={"format": "xml", "page[size]": 10}
)
root = ET.fromstring(resp.text)
```