Static snapshot API

All endpoints are served as static JSON files from Cloudflare's global CDN — no rate limits, no query-parameter filtering. Fetch a snapshot covering your range (e.g. /api/rates/6m.json) and filter client-side. Files are regenerated every business day at 4:30–6:30 PM ET via GitHub Actions.

GET Latest Rates

/api/rates/latest GET

Returns the most recent yield curve data available. This is the primary endpoint for displaying current treasury rates. Served from /api/rates/latest.json.

Response

Example Response
{
  "success": true,
  "data": {
    "date": "2026-10-09",
    "dateFormatted": "October 9, 2026",
    "rates": [
      { "maturity": "4WK", "rate": 4.13 },
      { "maturity": "6WK", "rate": 4.13 },
      { "maturity": "2MO", "rate": 4.13 },
      { "maturity": "3MO", "rate": 4.25 },
      { "maturity": "4MO", "rate": 4.29 },
      { "maturity": "6MO", "rate": 4.32 },
      { "maturity": "1YR", "rate": 4.47 },
      { "maturity": "2YR", "rate": 4.8 },
      { "maturity": "3YR", "rate": 4.89 },
      { "maturity": "5YR", "rate": 5.02 },
      { "maturity": "7YR", "rate": 5.13 },
      { "maturity": "10YR", "rate": 5.24 },
      { "maturity": "20YR", "rate": 5.65 },
      { "maturity": "30YR", "rate": 5.6 }
    ]
  }
}

GET Rate History Snapshots

/api/rates.json GET

Returns the complete yield-curve history as a single static file: 9,200 business days back to 1990 (~3.5 MB). There is no server-side filtering — fetch a pre-trimmed snapshot (see table) or filter client-side. The extensionless form /api/rates is rewritten (HTTP 200) to /api/rates.json, so both work.

Response

Example Response (truncated)
{
  "success": true,
  "data": [
    {
      "date": "2026-10-09",
      "rates": [
        { "maturity": "4WK", "rate": 4.13 },
        { "maturity": "2YR", "rate": 4.8 },
        { "maturity": "10YR", "rate": 5.24 }
      ]
    }
  ],
  "meta": {
    "from": "earliest",
    "to": "latest",
    "maturity": "all",
    "count": 9200,
    "limit": 9200,
    "offset": 0,
    "hasMore": false
  }
}

Snapshot Files

Each snapshot returns the same shape with a concrete meta range (from, to, count, hasMore):

File Coverage
/api/rates.json (alias /api/rates) Complete history — 9,200 business days back to 1990-01-02
/api/rates/3m.json Trailing 3 months
/api/rates/6m.json Trailing 6 months
/api/rates/1y.json Trailing 1 year
/api/rates/2y.json Trailing 2 years
/api/rates/5y.json Trailing 5 years

GET Available Maturities

/api/rates/maturities GET

Returns all available maturity periods with their position in years (used for plotting the curve on a time axis). Served from /api/rates/maturities.json.

Response

Example Response
{
  "success": true,
  "data": [
    { "maturity": "4WK", "years": 0.08333333333333333 },
    { "maturity": "6WK", "years": 0.125 },
    { "maturity": "2MO", "years": 0.16666666666666666 },
    { "maturity": "3MO", "years": 0.25 },
    { "maturity": "4MO", "years": 0.3333333333333333 },
    { "maturity": "6MO", "years": 0.5 },
    { "maturity": "1YR", "years": 1 },
    { "maturity": "2YR", "years": 2 },
    { "maturity": "3YR", "years": 3 },
    { "maturity": "5YR", "years": 5 },
    { "maturity": "7YR", "years": 7 },
    { "maturity": "10YR", "years": 10 },
    { "maturity": "20YR", "years": 20 },
    { "maturity": "30YR", "years": 30 }
  ]
}

GET Rate Statistics

/api/rates/stats GET

Returns the current-year high and low rate for each maturity, with the dates those records occurred. The allTime* fields are reserved for future use and currently return null. Served from /api/rates/stats.json.

Response

Example Response
{
  "success": true,
  "data": [
    {
      "maturity": "10YR",
      "yearHigh": 5.31,
      "yearHighDate": "2026-10-05",
      "yearLow": 3.97,
      "yearLowDate": "2026-02-27",
      "allTimeHigh": null,
      "allTimeHighDate": null,
      "allTimeLow": null,
      "allTimeLowDate": null
    }
  ]
}

GET Health Check

/health GET

Simple health check. Returns service status plus the dates of the latest data files. Served from /health.json (a 200 rewrite from /health).

Response

Example Response
{
  "status": "ok",
  "latestRateDate": "2026-10-09",
  "latestSummaryDate": "2026-10-09"
}

GET Daily Summary

/api/daily-summary GET

Plain-text summary of the latest business day's Treasury market, written by the automated daily writer. This is what powers the homepage summary block.

Response

Example Response (text/plain)
Short-term Treasury bills moved higher over the past week, with the 4-week and
6-week rates at 4.13 percent on Friday, October 9, 2026, ...

GET Blog Post Data

/api/blog/2026-10-09.json GET

Structured data for one business day's post: date, dateFormatted, long-form summary, shorter blogSummary, and that day's rates. One file per business day (e.g. /api/blog/2026-10-08.json). Available years are listed at /api/blog/years.json, which returns {"success": true, "data": ["2026"]}.

Response

Example Response (truncated)
{
  "success": true,
  "data": {
    "date": "2026-10-09",
    "dateFormatted": "October 9, 2026",
    "summary": "Short-term Treasury bills moved higher over the past week, ...",
    "blogSummary": "The short end of the Treasury market opened Friday, ...",
    "rates": [
      { "maturity": "4WK", "rate": 4.13 },
      { "maturity": "10YR", "rate": 5.24 }
    ]
  }
}

Response Codes

Code Description
200 Success
301 Permanent redirect (legacy URLs like /blog?page=2 redirect to /blog/2/)
404 Not Found - File doesn't exist (e.g. a blog date with no published post)