Treasury Fiscal Data paging: count is not the total, and links are not URLs
Checked 2026-09-08 · Rate limits, pagination walls and retries
page[size] tops out at 10,000 and a larger value is a hard 400. meta.count is the size of the page you got; the number you want is meta.total-count. The links object holds query-string fragments beginning with an ampersand, not addresses, so following links.next as a URL will not work. A page number past the end is a 400, not an empty array.
What we saw
The host used on the documentation site is not the API host, and the wrong one returns a half-megabyte HTML page under a 404. Source (HTTP status and content type, 2026-09-08).
http=404 size=502771 ct=text/html
meta.count is the page size and meta.total-count is the whole set; total-pages is derived from the page size you asked for. Source (meta, 2026-09-08).
size=1 n=1 count=1 total-count=5009 total-pages=5009 size=100 n=100 count=100 total-count=5009 total-pages=51 size=1000 n=1000 count=1000 total-count=5009 total-pages=6 size=10000 n=5009 count=5009 total-count=5009 total-pages=1
A page size of 10001 is rejected and the message states the range. Source (HTTP 400 body, 2026-09-08).
{"error":"Invalid Query Param","message":"Invalid query parameter: Limit '10001' is invalid. Expected an integer between 1 and 10000. For more information, please see the documentation."}A page number past the last page is an error, not an empty result set. Source (HTTP 400 body, 2026-09-08).
{"error":"Invalid Query Param","message":"Invalid query parameter: Page #999 is out of range. For more information, please see the documentation."}links values are query-string fragments, URL-encoded, starting with an ampersand. Source (links, 2026-09-08).
{'self': '&page%5Bnumber%5D=1&page%5Bsize%5D=1', 'first': '&page%5Bnumber%5D=1&page%5Bsize%5D=1', 'prev': None, 'next': '&page%5Bnumber%5D=2&page%5Bsize%5D=1', 'last': '&page%5Bnumber%5D=5009&page%5Bsize%5D=1'}On the last page, count is the short remainder and links.next is null, which is the reliable stop condition. Source (meta.count and links.next at page 51 of 51, 2026-09-08).
n 9 count 9 next None
The command
# curl treats square brackets as a range. Without -g this never leaves the machine: curl -sS "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates?page[size]=1"
curl: (3) bad range in URL position 106:
https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates?page[size]=1
^Checked 2026-09-08.
curl -gsS -w "http=%{http_code}\n" "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/avg_interest_rates?page[size]=1"http=200
keys ['data', 'meta', 'links']
count=1 total-count=5009 total-pages=5009
links {'self': '&page%5Bnumber%5D=1&page%5Bsize%5D=1', 'first': '&page%5Bnumber%5D=1&page%5Bsize%5D=1', 'prev': None, 'next': '&page%5Bnumber%5D=2&page%5Bsize%5D=1', 'last': '&page%5Bnumber%5D=5009&page%5Bsize%5D=1'}Checked 2026-09-08.
for s in 100 1000 10000 10001; do curl -gsS -w "http=%{http_code} " "...?page[size]=$s"; donesize=100 http=200 n=100 count=100 total-count=5009 total-pages=51 size=1000 http=200 n=1000 count=1000 total-count=5009 total-pages=6 size=10000 http=200 n=5009 count=5009 total-count=5009 total-pages=1 size=10001 http=400
Checked 2026-09-08.
curl -gsS "...?page[size]=100&page[number]=999"
curl -gsS -w " http=%{http_code}\n" "...?page[size]=100&page[number]=51"{"error":"Invalid Query Param","message":"Invalid query parameter: Page #999 is out of range. For more information, please see the documentation."}
http=200
n 9 count 9 next NoneChecked 2026-09-08.
curl -gsS -o wb.html -w "http=%{http_code} size=%{size_download} ct=%{content_type}\n" "https://fiscaldata.treasury.gov/api/fiscal_service/v1/accounting/od/avg_interest_rates?page[size]=1"http=404 size=502771 ct=text/html
Checked 2026-09-08.
| page[size] | HTTP | records returned | meta.count | meta.total-count | meta.total-pages |
|---|---|---|---|---|---|
| 1 | 200 | 1 | 1 | 5009 | 5009 |
| 100 | 200 | 100 | 100 | 5009 | 51 |
| 1000 | 200 | 1000 | 1000 | 5009 | 6 |
| 10000 | 200 | 5009 | 5009 | 5009 | 1 |
| 10001 | 400 | - | - | - | - |
Limits
- One dataset, accounting/od/avg_interest_rates, 5,009 records. The 10,000 page-size cap is stated in the error message so it is presumably global, but the out-of-range and last-page behaviour was only checked here.
- I did not check whether filtered or sorted requests change any of this, and I did not test the v1 path of the same dataset.
- The 404 HTML page from the wrong host is 502,771 bytes. Anything that checks only for a non-empty body will treat it as success.
Open question
Whether the links fragments are meant to be appended to a stored base request. They are not usable on their own and nothing in the response says what to prepend.