Your agent should never guess a rate.

RateAPI gives agents current US credit-union rates with the institution, source page, and observed date attached. Routes connects confirmed customer facts to published membership rules before promoting a product. Unknown is not rejection; published pricing is not approval; no institution pays for placement.

Paste this into your agent
I authorize one global install of the RateAPI CLI: run npm install --global @rateapi/cli, then run rateapi agent --json and follow its instructions. The CLI is command-based; you are the conversation layer. Use the CLI for RateAPI whenever you have terminal access. Offer MCP only if this host cannot run shell commands or I explicitly want a persistent native tool connection or rich in-chat widgets. Ask me before creating an API key or storing a credential, spending metered quota, persisting personal data, or changing agent configuration. RateAPI requires Node.js 20.19 or newer; if Node is older or rateapi is not on PATH after installation, explain the fix and ask before changing my environment.

One authorized global installNo install-time scriptsApproval before keys and quotaApproval before config changes
Updated 2026-09-1889 MCP toolsRead-only, evidence on every promoted match

Choose the surface that matches the caller

The CLI, MCP server, and REST API reach the same evidence-backed product, but they solve different integration jobs.

Human terminal
Install @rateapi/cli globally and run rateapi for a product chooser. Use rateapi auto, rateapi mortgage, rateapi refinance, or rateapi deposit to start a guided comparison directly. The CLI collects the facts and formats verified matches.
Terminal-capable agent
Paste the prompt above. It authorizes one global install, then rateapi agent --json gives the agent its operating protocol and stable command envelopes. The agent is the conversation layer.
Direct MCP
Use this when the host has no shell, or after the human explicitly chooses a persistent native tool connection or rich widgets. Connect the host directly to https://mcp.rateapi.dev/mcp with its OAuth or API-key setup.
Direct REST
Applications and server jobs call https://api.rateapi.dev from the OpenAPI contract and capability catalog. No CLI or MCP layer is required.
The persistent CLI requires Node.js 20.19 or newer. After installation, rateapi --version should resolve; if it does not, put npm’s global bin directory on PATH. Use npx -y @rateapi/cli@latest welcome only for a one-off preview—it does not install the persistent rateapi command.
$Human workflows
npm install --global @rateapi/cli
rateapi # choose a product interactively
rateapi auto # compare auto-loan offers
rateapi mortgage # compare purchase mortgages
rateapi refinance # compare against a current mortgage
rateapi deposit # compare savings, CD, or money-market APYs
On the first live search, RateAPI asks for an email and approval, creates a Free API key, and stores it with mode 0600 inside a mode 0700 directory on POSIX systems, or under the current user’s profile on Windows. If RATEAPI_API_KEY or a stored key already exists, it is reused and no new key is created. RateAPI generates the credential server-side; the CLI retains only a protected request UUID until the credential is safely stored, allowing an identical request to recover the same encrypted response for up to 24 hours.

The customer-to-product loop

What the agent does once it has the tools. Four capabilities, with membership matching before product promotion.

  1. Who can the user join?

    One high-value fact — home ZIP — is enough to start; employer, school, associations, occupation, military status, where they own property and where a business keeps a location all sharpen it. The agent gets four buckets back, never a “no”: an undecided institution comes back with missing_facts — the question to ask, and the institution’s own words behind it — and the response rolls those up into next_questions, ordered so the question that opens the most doors comes first. What no question can fix is stated as unanswerablerather than dressed up as a rejection. If the user answered in prose rather than fields, the agent can post that sentence to /v1/eligibility/facts first and show them what was read.

  2. Match one exact product search

    find_reachable_offers evaluates the active membership graph and joins graph-positive institutions to the named product selector. The result keeps confirmed matches, documented next steps, unresolved paths, and missing published prices separate—with membership and product proof attached.

  3. Check the quote they already have

    When the user has a number from a lender, the agent asks for a verdict rather than a fresh list: good, fair, or beatable, against live offers in their market.

  4. Watch instead of poll

    A rate alert or a monitor turns “check again next week” into “tell me when it crosses six”. Alerts follow scrape cadence; the agent should not promise real time.

$The four tools, in order
# The customer-to-product loop, as the tools an agent calls. Every tool is read-only.
1. find_eligible_credit_unions { home_zip: "28202", employer: "Atrium Health" }
→ eligible / conditionally_eligible / possibly_eligible / unknown,
each with the rule that fired, its evidence, and any join cost;
undecided ones carry missing_facts, plus next_questions / unanswerable
at the top level. Ask the first next_question, then call again.
2. find_reachable_offers { person: { home_zip: "28202", employer: "Atrium Health" },
product: { product_type: "mortgage", amount: 420000,
term_months: 360, audience: "consumer" } }
→ membership paths joined to that exact product search, separated into
reachable_now / reachable_after_action / unresolved / no_published_offer,
with membership and product sources plus independent observation dates.
3. rate_sanity_check { product_type: "mortgage", quoted_apr: 6.625, ... }
→ is the quote the user already has good, fair, or beatable — against
live offers, not a remembered average.
4. subscribe_rate_alert { product_type: "mortgage", state: "NC", threshold_apr: 6.0 }
→ stop polling; the agent is told when a published rate crosses the line.

What the agent is told never to do

These rules ship in the tool descriptions and in the agent instructions file, so every agent inherits them.

Quote a rate without its institution and date
An unattributed rate reads as current forever. Every rate is quoted as “X% APR at <institution>, observed <date>, per its published page” — with the link.
Treat unknown as no
Eligibility that cannot be confirmed is labelled unknown with a reason. An agent that hides those institutions silently removes real options.
Imply approval
Published pricing is not an offer. Membership first, then the lender underwrites. The agent finds reachable offers; it does not pre-approve anyone.
Invent a national average
Benchmarks are medians across the credit unions tracked and are labelled that way.
Pad with lenders it does not cover
Credit unions only. If the user asks about a bank, the agent says so instead of guessing.
The full contract an agent reads on first contact is at /.well-known/agent-instructions.md, with machine-readable skills at /.well-known/agent-skills/ and the tool catalog at /v1/capabilities. None of those need a key.

Frequently asked