# Fermi > Fermi returns calibrated probability distributions from natural-language questions. It is a REST and MCP API built for AI agents and developers who need quantitative estimates under uncertainty. Fermi is paid and rate-limited but supports agent-to-agent cold start: any agent can POST to `/api/v1/accounts` to create an account, receive an API key, and immediately make estimates using 3 starter credits — with no human in the loop. > **Base URL note (important for cold-start agents):** the curl examples below use `$BASE_URL` as a placeholder. Set it to the host you fetched this file from — e.g. `BASE_URL=https://fermi.kromatic.com` on production, or `BASE_URL=https://stag-fermi.krobar.ai` on staging. Do not mix environments: an account you create on staging is not valid on production, and vice versa. ## Cold-start quickstart (3 steps) **Step 1 — Create an account.** Returns `{account_id, api_key, created_at}`. No payload required. ``` curl -X POST $BASE_URL/api/v1/accounts ``` **Step 2 — Make an estimate.** Send the returned `api_key` as `X-API-Key` (NOT as `Authorization: Bearer` — Bearer is reserved for JWTs and will return 401). Also send any UUID as `Idempotency-Key`. The `disclaimer_acknowledged: true` field is required — estimates are probabilistic and for decision-support only. ``` curl -X POST $BASE_URL/api/v1/estimates \ -H "X-API-Key: " \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "question": "What will the price of Bitcoin be in 6 months?", "requested_tier_id": 1, "unit": "USD", "target_horizon": "6 months", "disclaimer_acknowledged": true }' ``` **Step 3 — Read the response.** The JSON contains: - `estimation_interval`: `{low, high}` — the `coverage_probability` (default 0.9) confidence interval - `distribution_family`: one of `normal`, `log_normal`, `uniform`, `beta`, `triangle`, `gamma`, etc. - `distribution_parameters`: family-specific parameters (e.g. `{mu, sigma}` for log_normal) - `point_estimate`: single best-guess value - `reasoning_summary` and `assumptions`: the model's stated logic - `credits_charged`: credits deducted from your account - `next_steps.simulate`: how to carry this estimate into neumann as a simulation root node To combine several estimates into a model with a time axis and get percentiles, NPV or payback out, feed them into neumann (https://neumann.kromatic.com) as simulation root nodes -- every successful estimate carries a next_steps.simulate block with the arguments already prepared. ## Request schema (EstimateRequest) Required fields: - `question` (string, non-empty) — the natural-language question - `requested_tier_id` (int) — `1` (fast, sync), `2` (grounded, sync), or `3` (research, async) - `unit` (string) — the unit the answer should be expressed in (e.g. `USD`, `people`, `meters`) - `target_horizon` (string) — when the estimate applies (e.g. `6 months`, `2030`, `current`) - `disclaimer_acknowledged` (bool) — must be `true` Optional: `context` (string), `coverage_probability` (float, 0-1, default 0.9), `source_inputs` (list of `{source_type, content}` objects), `callback_url` (webhook URL for async completion notification), `provider` ("openai" or "anthropic"), `model` (model ID). For tier 3 (async), if you can't receive a `callback_url` webhook (e.g. Claude.ai, ChatGPT, grok.com), poll `GET /api/v1/estimates/{estimate_id}` or the MCP `get_estimate` tool (titled "Read estimate"; free, never spends quota or credits) with the `estimate_id` this call returned. ## Required headers - `X-API-Key: ` — authentication (or anonymous 1/day fallback with no key) - `Idempotency-Key: ` — required on POST /api/v1/estimates, deduplicates retries - `Content-Type: application/json` ## Anonymous free tier (no signup) Agents can make 1 tier-1 estimate per day per IP/fingerprint with no API key. Use this to experiment before signing up. See `GET /api/v1/estimates/tiers` for current tier info. On the MCP transports, call the `whoami` tool (titled "Check account and quota") to see how many free anonymous estimates you have left today, when the allowance resets, and — with an `api_key` — your credit balance and last 10 credit transactions. It is free, works anonymously, and consumes nothing. Every MCP tool response also carries a `billing` block with the same identity/cost fields, so you can tell whether a call spent the anonymous allowance (`charged_to: "anonymous_quota"`) or account credits (`charged_to: "credits"`). REST callers use `GET /api/v1/accounts/me` and `/api/v1/accounts/me/usage` instead. ## Channel attribution (for directories & discovery surfaces) If you list Fermi in a directory, marketplace, or agent registry, you can tag the arrivals you send us so we can attribute them to your channel. Pass an identifiable marker either as the `X-Fermi-Channel: ` header or as a `?channel=` (alias `?ref=`) query parameter on the first authenticated call. It is optional and affects nothing about the response — it only lets an operator see which channel a new external agent arrived from. Only authenticated arrivals are attributed; anonymous calls are never counted. ## Feedback Submit feedback, feature requests, or bug reports. No authentication required (but including your API key attaches your account ID for context). ``` curl -X POST $BASE_URL/api/v1/feedback \ -H "Content-Type: application/json" \ -d '{ "type": "feature_request", "message": "I would like an endpoint that ...", "sender_email": "you@example.com" }' ``` Also available as the MCP `feedback` tool (titled "Send feedback to the Fermi team"; free). ## Errors - `402 Payment Required` — out of credits. Credits are $0.50 each. Use `POST /api/v1/billing/checkout` for browser checkout or `POST /api/v1/billing/purchase-credits` for API-driven purchase with a saved card - `422 Unprocessable Entity` — bad request (missing `disclaimer_acknowledged`, bad tier, missing headers) - `429 Too Many Requests` — rate limit hit (anonymous tier exhausted for the day) ## Links All paths below are host-relative — prepend the `$BASE_URL` you fetched this file from. - [`/agents.md`](/agents.md) — longer, fully self-contained agent quickstart with Python examples - [`/openapi.json`](/openapi.json) — machine-readable OpenAPI schema - [`/docs`](/docs) — Swagger UI (interactive) - [`/.well-known/mcp.json`](/.well-known/mcp.json) — machine-readable MCP endpoint descriptor - [`/mcp`](/mcp) — real MCP Streamable-HTTP server; authenticate with `Authorization: Bearer fmi_pat_...`/`fmi_oat_...` (mint via `POST /api/v1/tokens`) - [`/mcp/sse/`](/mcp/sse/) — real MCP SSE server for MCP-native clients; pass `api_key` as a tool argument - [`/mcp/tools`](/mcp/tools) — list MCP tools via plain REST (HTTP adapter); every description opens with a `Cost:` sentence, matching the native `tools/list` - [`/api/v1/billing/pricing`](/api/v1/billing/pricing) — credit pricing (no auth) - [`/api/v1/billing/checkout`](/api/v1/billing/checkout) — Stripe Checkout session (auth required) - [`/api/v1/billing/purchase-credits`](/api/v1/billing/purchase-credits) — API-driven credit purchase (auth required) - [Source code on GitHub](https://github.com/Kromatic-Innovation/fermi)