Ranked financial product offers, with the reasoning attached.
POST /v1/decisions takes a consumer scenario — what they are borrowing for, how much, over what term, where they are — and returns ordered product offers with structured reasoning for the ordering. Pair it with the eligibility API and the ranking covers only products the consumer can actually get.
Recommendation is three problems, not one
Most teams discover this in the order below, usually after shipping the first one alone and finding it does not hold up.
- 1. What exists
- Current, comparable product data across institutions. The part everyone starts with, and the part that quietly rots without a pipeline behind it.
- 2. What they can get
- Eligibility. A cheaper product at an institution the consumer cannot join is not an offer, and ranking it first actively damages trust.
- 3. What is actually best
- Ranking by real cost over the scenario, with reasoning you can show a user — or defend to a regulator.
The endpoints
/v1/decisionsOne scenario in, ranked offers out, with the reasoning for the ordering.
/v1/decisions/batchMany scenarios in one request — the shape for scoring an existing book rather than a live user.
/v1/explain-rankingExpand one ordering in detail, for a “why this order?” surface or an audit log.
/v1/simulate-decisionRun a scenario without it counting as a live decision — useful in tests and in what-if UI.
Request
curl -X POST "https://api.rateapi.dev/v1/decisions" \ -H "Authorization: Bearer $RATEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "scenario": "auto_purchase", "loan_amount": 35000, "term_months": 60, "state": "NC", "vehicle_condition": "used" }'Eligibility-aware recommendation
The pattern worth copying: narrow to what the consumer can reach, then rank what is left.
// The full shape: eligibility narrows the field, decisions ranks what is left.const eligible = await rateapi("/v1/eligibility/search", { home_zip: user.zip, employer: user.employer, willing_to_join_association: true,}); const reachable = [...eligible.eligible, ...eligible.conditionally_eligible] .map((institution) => institution.credit_union_id); const ranked = await rateapi("/v1/decisions", { scenario: "auto_purchase", loan_amount: 35_000, term_months: 60, state: user.state,}); // Show only what this person can actually get, cheapest real cost first.const offers = ranked.actions[0].offers .filter((offer) => reachable.includes(offer.credit_union_id));/v1/benchmarks, which publishes a median built for that purpose.Ranking you can defend
- Cost over the scenario
- Ranked by what the consumer actually pays for the loan they described, not by the headline number that markets best.
- Reasoning in the response
- Every ordering carries structured reasoning. Render it, log it, or override it — but you always have it.
- No paid placement
- No institution can pay to appear, rank higher, or exclude a rival. A ranking that can be bought is advertising.
- Deterministic
- The same scenario against the same data produces the same order. Reproducibility is what makes an explanation worth anything.
Frequently asked
/v1/rates returns raw rate rows — you filter, you rank, you decide. /v1/decisions takes a scenario and returns an ordered answer with the reasoning attached. Use rates when you are building your own ranking and want the primitive; use decisions when you want the answer and would rather not reimplement cost comparison, eligibility filtering and tie-breaking yourself.
By the cost the consumer actually bears over the scenario you describe, not by headline APR alone. APR is a comparison tool with real limits: it does not capture fees the same way across product types, and it says nothing about whether the consumer can access the product at all. The response carries the reasoning so you can show, log or override it.
No. No institution can pay to appear, to rank higher, or to exclude a competitor. This is a fixed constraint on the product, not a current policy — the ordering is a function of the scenario and the data, and nothing else. If a ranking API can be bought, its rankings are advertising, and the whole value of an explainable recommendation disappears.
It can, and it should. Recommending a product the consumer cannot access is worse than recommending nothing — pair it with the eligibility API so the ranked set is a set they can actually reach. A cheaper rate at an institution they cannot join is not an offer.
Yes — that is what the reasoning in the response is for, and /v1/explain-ranking exists to expand one ordering in detail. Deterministic, reproducible reasoning is a hard requirement here: a recommendation you cannot explain is one you cannot defend.
Yes. POST /v1/decisions/batch evaluates multiple scenarios in one request — the usual shape for scoring a book of existing customers rather than answering one live user.