The Fixed Basket
The Fixed Basket · API Reference v1

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.

Endpoints
17
Geographies
56
Archetypes
10
Rate limit
120/min
5,000/day per IP

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, and generated_at.

Getting started

No API key required. No auth header required. All endpoints are public read-only.

Hello-world request
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.

ParameterTypeDefaultBehavior
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."
}
HTTPerrorTrigger
400bad_requestUnknown or malformed query parameter (strict validation — typos fail loudly rather than silently returning the default), or a required parameter missing.
404not_foundUnknown path, archetype, or geography; wrong-level geography for path.
429rate_limitedPer-IP rate limit exceeded. Body includes retry_after_seconds; response carries a Retry-After header.
500internal_errorUnhandled server-side exception. Body never includes a stack trace. Every error body carries a request_id.

Endpoints — Health & Status

GET /api/v1/health

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
curl https://fixedbasket.org/api/v1/health
Example response
{
  "status": "ok",
  "methodology_version": "2.2.0",
  "basket_version": "1.0.14",
  "database": "ok"
}
GET /api/v1/status

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
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": []
    }
  }
}
GET /api/v1/versions

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.

GET /api/v1/index/headline

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
GET /api/v1/index/archetypes

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
GET /api/v1/index/<archetype>/series

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
GET /api/v1/index/strata

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

GET /api/v1/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.

GET /api/v1/archetype/<archetype>/headline

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
GET /api/v1/archetype/<archetype>/series

Full monthly time series for one archetype at the national level.

curl https://fixedbasket.org/api/v1/archetype/renter/series
GET /api/v1/archetype/<archetype>/decomposition

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.

GET /api/v1/state/<code>/coverage

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
GET /api/v1/state/<code>/archetype/<archetype>/headline

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
GET /api/v1/state/<code>/archetype/<archetype>/series

Full state × archetype monthly time series.

curl https://fixedbasket.org/api/v1/state/TX/archetype/working_parent/series
GET /api/v1/state/<code>/archetype/<archetype>/decomposition

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.

GET /api/v1/bulk

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)

GET /api/v1/series

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.

Archetype mode — full index for one (archetype, geography)
curl "https://fixedbasket.org/api/v1/series?archetype=retiree&geography=FL"
Stratum mode — price relative for one (stratum, geography)
curl "https://fixedbasket.org/api/v1/series?archetype=retiree&geography=FL&stratum=healthcare_premium"

Endpoints — Basket & Methodology

GET /api/v1/basket

Locked basket definition. Per-archetype stratum weights, headline-archetype identifier, canonical stratum list, per-stratum source map.

curl https://fixedbasket.org/api/v1/basket
GET /api/v1/methodology

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:

AxisFieldBumps on
API contract/v1/ URL prefixBreaking changes
Methodologymethodology_versionAny change to how the index is computed
Basketbasket_versionAny change to the locked basket (items, weights, source-precedence)