API Reference
Read-only JSON API serving the Fixed Basket Index, its annual rate,
and per-stratum decomposition for 52 geographies and 10
household archetypes. URL-versioned at /api/v1/.
No authentication. Open CORS. Per-IP rate-limited.
Overview
- Base URL.
https://fixedbasket.org/api/v1 - Protocol. HTTPS only. All endpoints
GET. - Content type.
application/json; charset=utf-8 - Versioning. URL-prefixed (
/v1/). Backward-incompatible changes get a/v2/prefix. - CORS. Open (
*) for all/api/*paths. - Provenance. Every response includes
methodology_version,basket_version, andgenerated_at.
Getting started
No API key required. No auth header required. All endpoints are public read-only.
curl https://fixedbasket.org/api/v1/health
Authentication
None. Every endpoint is public read-only. No
Authorization header, query token, or API key is
read by the application. If future write endpoints are added,
they will be introduced under a separate path with auth
documented inline; the read API will remain unauthenticated.
Rate limits
Global per-IP limits enforced by Flask-Limiter:
- 120 requests per minute per client IP
- 5,000 requests per day per client IP
Exceeding either limit returns HTTP 429 with the
error body documented in Error format.
The retry_after_seconds field indicates suggested
back-off (default 60). Higher tiers are not offered; clients
requiring sustained throughput should cache locally — responses
are stable until the next ingest run.
Response conventions
Every successful response is wrapped in a provenance envelope:
{
"methodology_version": "2.2.0",
"basket_version": "1.0.14",
"generated_at": "2026-05-27T14:22:03.119482+00:00",
"data": <endpoint-specific payload>
}
Some endpoints add sibling keys alongside data
(for example coverage_months on series endpoints).
Numeric types. All index levels and rates are
JSON numbers. Internal computation uses Decimal;
serialization converts to float at the response
boundary.
Period strings. Monthly periods are
YYYY-MM. Annual periods are YYYY.
Both order lexicographically.
Tracing & caching. Every response carries an
X-Request-ID header (send your own to correlate, or echo
ours when reporting an issue — it's also in every error body). Read
responses carry ETag + Last-Modified keyed
to the data vintage; send If-None-Match for a
304 Not Modified when nothing changed. Poll
/versions to detect a new
month without refetching every cell. Reads are served from a
materialized snapshot — deterministic and cacheable, so they should
never 5xx.
Common query parameters
Accepted across the index surface (/index/*, /archetype/*, /state/*, including /index/headline). The static reference endpoints (/basket, /methodology) ignore them.
| Parameter | Type | Default | Behavior |
|---|---|---|---|
basket_version |
string | active version | Pin response to a specific locked basket version. Stable downstream consumers should pin. |
as_of |
YYYY-MM-DD | current month | Point-in-time cutoff. Pins the forward-fill ceiling to that date and recomputes the index as of then — observations after the date are excluded, so the response is reproducible for a fixed (basket_version, as_of). Malformed dates return 400. |
basket |
string | standard |
Basket variant. standard is the headline; spendable removes the employer-paid share of the health-insurance premium (out-of-pocket exposure only). Unknown values return 400. The chosen variant is echoed at the top level as basket. |
Error format
Errors return a JSON body and a matching HTTP status code.
{
"error": "not_found",
"message": "Unknown geography 'ZZ'. Valid: 'US' or a USPS 2-letter state code."
}
| HTTP | error | Trigger |
|---|---|---|
| 400 | bad_request | Unknown or malformed query parameter (strict validation — typos fail loudly rather than silently returning the default), or a required parameter missing. |
| 404 | not_found | Unknown path, archetype, or geography; wrong-level geography for path. |
| 429 | rate_limited | Per-IP rate limit exceeded. Body includes retry_after_seconds; response carries a Retry-After header. |
| 500 | internal_error | Unhandled server-side exception. Body never includes a stack trace. Every error body carries a request_id. |
Endpoints — Health & Status
Lightweight liveness probe. Reports overall app status, methodology and basket versions, and a single database-connectivity check. Intentionally cheap so it can be polled at high frequency — the per-source data-freshness scan lives at /api/v1/status.
Status values: ok or degraded. degraded when the database connectivity ping fails.
curl https://fixedbasket.org/api/v1/health
Example response
{
"status": "ok",
"methodology_version": "2.2.0",
"basket_version": "1.0.14",
"database": "ok"
}
Per-source data-freshness readiness report. Each registered source's latest period is compared against its publish-lag SLA and bucketed GREEN / YELLOW / RED. Heavier than /api/v1/health (one query per source); intended for dashboards and monitoring, not high-frequency probing.
Status values: ok or degraded. degraded when any source is blocking-stale or the freshness check itself errored.
curl https://fixedbasket.org/api/v1/status
Example response
{
"methodology_version": "2.2.0",
"basket_version": "1.0.14",
"data": {
"status": "ok",
"data_freshness": {
"summary": { "any_blocking": false, "any_warning": false, "checked": 11 },
"sources": [ { "source": "eia", "status": "GREEN", "days_old": 6, "cadence": "monthly", "max_lag_days": 60 } ],
"blocking_sources": []
}
}
}
Freshness + version signal for batch consumers — poll this cheaply and
refetch data only when latest_month or
surface_computed_at changes (or use the ETag /
Last-Modified headers on any read for conditional GETs).
Fields: methodology_version, basket_version, latest_month, surface_computed_at, reproducibility, changelog.
curl https://fixedbasket.org/api/v1/versions
Endpoints — Index (v1.0)
National-only surface. Retained for backward compatibility.
National-Average headline numbers — the public-citation surface.
Fields: as_of_month, index_level (Jan 2000 = 100), annual_rate_pct (long-run annualized %/yr — the headline), rolling_12m_rate_pct (trailing-12-month annualized %), rolling_12m_anchor, purchasing_power_usd (what a 2000 dollar buys today = 100 / index_level), long_run_first_month, long_run_last_month, coverage_months.
curl https://fixedbasket.org/api/v1/index/headline
Latest values for all 10 archetypes side-by-side. Returns an array; is_headline: true marks national_average.
curl https://fixedbasket.org/api/v1/index/archetypes
Full monthly time series for one archetype at the national level.
Path parameters. archetype: one of national_average, homeowner, renter, working_parent, retiree, income_lowest_quintile, income_second_quintile, income_middle_quintile, income_fourth_quintile, income_highest_quintile.
Observation shape. {period, index_level, rolling_12m_rate_pct, purchasing_power_usd}.
curl https://fixedbasket.org/api/v1/index/retiree/series
Per-stratum latest price-relative table — machine-readable form of the The Fixed Basket-vs-CPI comparison.
Per row. {stratum, first_period, last_period, latest_relative, coverage_months} anchored at 2000-01 = 1.0.
curl https://fixedbasket.org/api/v1/index/strata
Endpoints — Geographies
Index of all 52 published geographies, grouped by level (national, states).
Top-level fields. national, states, total_count, published_series_total, level_construction_note.
curl https://fixedbasket.org/api/v1/geographies
Endpoints — Archetype (v1.1)
Geography- and archetype-first routing per the v1.1 contract.
National headline for one archetype. Same fields as /index/headline plus archetype and geography: "US".
curl https://fixedbasket.org/api/v1/archetype/working_parent/headline
Full monthly time series for one archetype at the national level.
curl https://fixedbasket.org/api/v1/archetype/renter/series
Per-stratum X-ray decomposition. Top-level annual_rate_pct plus a strata array; each row: {stratum, weight, rate_annualized, contribution_pp, coverage_months}. Contributions sum approximately to the headline annual rate.
curl https://fixedbasket.org/api/v1/archetype/retiree/decomposition
Endpoints — State (v1.1)
USPS 2-letter codes (50 states + DC). National CEX weights × state-specific prices, with documented per-stratum fallback when state-level data is unavailable.
Per-state coverage map. For each stratum: which source band drives the value (state | national), when state-specific data begins, and what share of basket weight is genuinely state-specific.
This endpoint is the §5.8 disclosure surface — readers can see how much of a state headline is genuinely state-resolved versus national-pass-through.
curl https://fixedbasket.org/api/v1/state/CA/coverage
State × archetype headline. Same shape as the archetype headline endpoint with geography set to the state code.
curl https://fixedbasket.org/api/v1/state/CA/archetype/retiree/headline
Full state × archetype monthly time series.
curl https://fixedbasket.org/api/v1/state/TX/archetype/working_parent/series
Per-stratum X-ray for (state, archetype). Same row shape as the archetype decomposition.
curl https://fixedbasket.org/api/v1/state/NY/archetype/renter/decomposition
Endpoints — Bulk (v1.1)
Whole-surface reads for batch consumers — no cell-by-cell scraping. Served from a materialized snapshot of the standard/active vintage, so it's a single fast request instead of 52+ round trips.
All geographies for one archetype (or the whole 520-series surface).
Query. archetype (required) — one of the 10 archetypes, or all for every (geography × archetype) cell. include=decomposition (optional) attaches the per-stratum X-ray to each cell. format=csv (optional) returns a CSV of the headline fields.
Each item is the same shape as a per-cell /headline response. Spendable / pinned-as_of vintages are not bulk-served — use the per-cell endpoints for those.
curl "https://fixedbasket.org/api/v1/bulk?archetype=retiree" curl "https://fixedbasket.org/api/v1/bulk?archetype=all&format=csv"
Endpoints — Generic series (v1.1)
Flexible time-series query. Two modes depending on whether stratum is supplied.
Required query params. archetype (one of 10 slugs).
Optional. geography (default US), stratum (if present, returns per-stratum price relatives), basket_version, as_of.
curl "https://fixedbasket.org/api/v1/series?archetype=retiree&geography=FL"
curl "https://fixedbasket.org/api/v1/series?archetype=retiree&geography=FL&stratum=healthcare_premium"
Endpoints — Basket & Methodology
Locked basket definition. Per-archetype stratum weights, headline-archetype identifier, canonical stratum list, per-stratum source map.
curl https://fixedbasket.org/api/v1/basket
Methodology version + a short summary of the load-bearing pillars, with links to the canonical documents.
curl https://fixedbasket.org/api/v1/methodology
Versioning policy
URL versioning. All endpoints live under /api/v1/. Backward-incompatible changes get a new prefix (/api/v2/). The /v1/ surface continues to serve until announced sunset.
What counts as breaking (requires a new prefix):
- Removing an endpoint.
- Removing or renaming a field in a successful response.
- Changing the type of a field.
- Tightening enum values for an existing parameter.
- Changing the semantics of an existing field.
What is additive (same /v1/ prefix):
- Adding a new endpoint.
- Adding a new field to an existing response.
- Adding a new accepted enum value (e.g., a new archetype or geography).
- Adding a new optional query parameter.
Three independent version axes:
| Axis | Field | Bumps on |
|---|---|---|
| API contract | /v1/ URL prefix | Breaking changes |
| Methodology | methodology_version | Any change to how the index is computed |
| Basket | basket_version | Any change to the locked basket (items, weights, source-precedence) |