Verified official statistics, one API.

Harmonized series from official statistical agencies. Every observation carries provenance: the exact source URL it came from, when it was retrieved, and by which connector version. Every series carries a verification status backed by golden-value and freshness checks against the live source. Answers are computed by real code in a sandbox, never estimated by a model.

Quickstart

Two calls to see the whole idea

# 1. The latest US unemployment rate, with provenance on every value:
curl "https://starwell.dev/api/starwell/v1/sources/fred/series/UNRATE/observations?latest=3"

# 2. A computed, cited answer:
curl -X POST "https://starwell.dev/api/starwell/v1/answer" \
  -H "Content-Type: application/json" \
  -d '{"question": "What was the average US unemployment rate in 2024?"}'

Base URL: https://starwell.dev/api/starwell/v1. All responses use { success, data, meta } envelopes. Dates are ISO YYYY-MM-DD. Machine-readable spec: OpenAPI 3.1.

Auth and limits

Anonymous preview now, API keys for volume

No key is required during the preview: anonymous callers get 120 data requests per minute and 6 answers per 10 minutes, per IP.

API keys (Authorization: Bearer dlk_live_... or X-API-Key) lift you onto daily tier quotas with usage metering. Free keys are issued instantly at /keys (or POST /v1/keys with {"email": "..."}); the key is shown once and stored hashed.

TierData requests / dayAnswers / day
Anonymous preview120 / minute (IP)6 / 10 minutes (IP)
Free key2,00025
Pro key50,000500
Data endpoints

Read the store

GET/v1/sources

The sources served, with counts, cadence notes, and terms links.

GET/v1/catalog

The whole catalog flat, in one call: every served series with its indicator, unit, frequency, geography, coverage, verification status, license, and dataset context. The right first call for bulk consumers and agents that want the full universe without walking sources one by one. Parameters: q (ranked search across series ids, indicators, geographies, and dataset titles, e.g. ?q=unemployment+canada), source (restrict to one slug), limit (1..1000; defaults to 50 with q, else all). A human-browsable view lives at /catalog.

GET/v1/sources/:source/datasets

Datasets (official releases and tables) in one source, with coverage and links to the official table pages.

GET/v1/sources/:source/datasets/:datasetId

One dataset plus its series, each with its verification status. The envelope carries the citation block.

GET/v1/sources/:source/series/:seriesId

Full series metadata, current verification status, and the most recent golden and freshness check records.

GET/v1/sources/:source/series/:seriesId/observations

The values. Parameters: start, end, latest (1..5000), limit, offset, format (json or csv; the CSV variant is spreadsheet-ready and carries its attribution as leading # comment lines). Series are addressed by the ids practitioners already use: fred/UNRATE, statcan/v41690973.

{
  "success": true,
  "data": [
    {
      "period": "2026-06-01",
      "value": 4.2,
      "status": "normal",
      "revision": 1,
      "provenance": {
        "sourceUrl": "https://api.stlouisfed.org/fred/series/observations?series_id=UNRATE&...&api_key=REDACTED",
        "retrievedAt": "2026-07-04T13:38:34.644+00:00",
        "connectorVersion": "1.0.0"
      }
    }
  ],
  "meta": {
    "series": { "externalId": "UNRATE", "indicator": "Unemployment Rate", "unit": "Percent" },
    "verification": { "status": "passing", "lastVerifiedAt": "2026-07-04T13:41:05..." },
    "citation": {
      "source": "Federal Reserve Economic Data (FRED)",
      "dataset": "Employment Situation",
      "url": "https://fred.stlouisfed.org/release?rid=50"
    }
  }
}

GET/v1/sources/:source/series/:seriesId/stats

Summary statistics computed over the verified store: latest and previous values, all-time min and max, mean, and the change versus the previous period and versus a year ago. The cheap way to answer "what is it now and how has it moved" without a full analysis run. The envelope carries verification, license, and citation like every other endpoint.

The flagship

POST/v1/answer

Ask a question in plain language. The engine matches it to served series (or use series to pin them), materializes the verified observations, writes and executes real Python in a sandbox, and returns the computed result. Nothing in the numbers is model-estimated.

curl -X POST "https://starwell.dev/api/starwell/v1/answer" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What was the average US unemployment rate in 2024?",
    "series": [{ "source": "fred", "seriesId": "UNRATE" }],
    "start": "2024-01-01", "end": "2024-12-01"
  }'
{
  "success": true,
  "data": {
    "answer": "The average US unemployment rate in 2024 was 4.03%.",
    "chart": { "...": "Plotly figure JSON" },
    "python": "import pandas as pd\ndf = pd.DataFrame(data)\n...",
    "series": [{
      "source": "fred", "seriesId": "UNRATE",
      "verification": { "status": "passing", "lastVerifiedAt": "..." },
      "citation": { "dataset": "Employment Situation", "url": "https://fred.stlouisfed.org/release?rid=50" }
    }]
  },
  "meta": { "observationsUsed": 12, "cached": false, "durationMs": 12085 }
}

Expect 10 to 40 seconds on a cache miss; repeated questions are served from the answers cache in milliseconds and invalidated the moment the underlying official data moves. When no served series can answer, the API refuses honestly with a 422 instead of inventing a number.

Alerts

POST/v1/monitors

Watch a series; get a webhook the moment it moves. Body: {"source": "fred", "seriesId": "DGS10", "webhookUrl": "https://..."}. Requires an API key (keys are free). Detection rides the store's own refresh loop: when a refresh lands a new period or a revised value, Starwell POSTs a series.updated event with the new value, the previous period, the verification status, and the citation. Delivery is https-only, one attempt per refresh, and the monitor's snapshot only advances on successful delivery, so a missed delivery re-fires on the next refresh. Manage with GET /v1/monitors and DELETE /v1/monitors/:id (scoped to your key). Monitors per key: 5 free, 100 pro.

{
  "event": "series.updated",
  "source": "fred",
  "seriesId": "DGS10",
  "indicator": "Market Yield on U.S. Treasury Securities at 10-Year Constant Maturity",
  "period": "2026-07-10", "value": 4.21, "previousPeriod": "2026-07-09",
  "verification": "passing",
  "citation": { "dataset": "H.15 Selected Interest Rates", "url": "https://fred.stlouisfed.org/release?rid=53" }
}
Trust, made inspectable

Verification statuses

StatusMeaning
passingGolden-value and freshness checks pass against the live source. Golden values are hand-verified reference points confirmed through two independent delivery channels.
staleValues verify, but the source has published newer data than we currently hold, or (for sources that publish no release time) the source has not been re-checked within the series' own cadence window. Staleness is never silently passed over.
failingA golden check disagrees with the live source. The series stays visible and honestly labeled; do not rely on it until it clears.
unverifiedIngested but not yet through the verification harness.
For agents

MCP server

The same capabilities as native tools for any MCP client, served over Streamable HTTP with no session state:

https://starwell.dev/api/starwell/mcp

Tools: search_catalog, list_sources, list_datasets, get_series, get_observations, answer, and monitor management (create_monitor, list_monitors, delete_monitor — API key required). Example client configuration:

{
  "mcpServers": {
    "official-statistics": {
      "type": "http",
      "url": "https://starwell.dev/api/starwell/mcp"
    }
  }
}
Recipes

Three ways in, thirty seconds each

Python and pandas

The CSV endpoint reads straight into a DataFrame; the # attribution lines are skipped with comment.

import pandas as pd

df = pd.read_csv(
    "https://starwell.dev/api/starwell/v1/sources/fred/series/UNRATE/observations?format=csv",
    comment="#", parse_dates=["period"],
)
print(df.tail())

JavaScript

const r = await fetch(
  "https://starwell.dev/api/starwell/v1/sources/fred/series/UNRATE/stats"
);
const { data, meta } = await r.json();
console.log(data.latest, meta.citation.text);

Google Sheets

One formula, live verified data in a sheet (re-fetches on open):

=IMPORTDATA("https://starwell.dev/api/starwell/v1/sources/fred/series/UNRATE/observations?format=csv&latest=120")
Where the numbers come from

Sources and attribution

Every API response carries the series' license code, license URL, and exact attribution text; the authoritative per-source view is the live catalog. The licensing gate is enforced at the serving layer: a series whose license does not permit redistribution is excluded from the catalog and from /answer, and direct requests for it return 451 Unavailable For Legal Reasons with the license context instead of data.

European Central Bank Data Portal

Source: European Central Bank Data Portal. Reproduction is permitted provided that the source is acknowledged. Licence · Source API docs.

Federal Reserve Economic Data (FRED)

Source: U.S. federal statistical agencies via FRED, Federal Reserve Bank of St. Louis. This product uses the FRED API but is not endorsed or certified by the Federal Reserve Bank of St. Louis. Licence · Source API docs.

SEC EDGAR company fundamentals (XBRL)

Source: U.S. Securities and Exchange Commission, EDGAR. SEC filings data are in the public domain. Licence · Terms · Source API docs.

Statistics Canada

Source: Statistics Canada. Contains information licensed under the Statistics Canada Open Licence. This product is neither produced nor endorsed by Statistics Canada. Licence · Source API docs.

U.S. Bureau of Labor Statistics Public Data API

Source: U.S. Bureau of Labor Statistics. BLS data are in the public domain. Licence · Terms · Source API docs.

U.S. Treasury Fiscal Data

Source: U.S. Department of the Treasury, Bureau of the Fiscal Service, Fiscal Data. Licence · Source API docs.

World Bank Open Data (World Development Indicators)

Source: The World Bank, World Development Indicators. Licensed under CC BY-4.0. Licence · Source API docs.

Values are served as published by the source (current vintage). Revisions are tracked append-only; historical snapshots are on the roadmap as an institutional feature.


Roadmap: /execute (sandboxed Python as a service) follows the same contract. Questions, keys, pilots: get a key or write to adarsh.verma1992@gmail.com.