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 cost reasoning for the ordering. When membership matters, start with POST /v1/reachable-offers so the candidate products carry documented membership and product evidence. Neither endpoint decides underwriting or approval.

Explainable orderingNo paid placement, everBatch scoring availableFree tier: 20 requests/month

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 belongs in the comparison
Membership matching. A cheaper product should not be promoted when there is no proven path connecting the customer to the institution.
3. What is actually best
Ranking by real cost over the scenario, with reasoning you can show a user — or defend to a regulator.
Skipping step 2 is the most common and most expensive mistake. It is the difference between a comparison table and a recommendation: a table can list anything, a recommendation is a claim about this person.

The endpoints

POST/v1/decisions

One scenario in, ranked offers out, with the reasoning for the ordering.

POST/v1/decisions/batch

Many scenarios in one request — the shape for scoring an existing book rather than a live user.

POST/v1/explain-ranking

Expand one lending decision ordering in detail. Deposit matches use the ranking basis, membership path, and selected-product evidence returned by reachable offers.

POST/v1/simulate-decision

Run a scenario without it counting as a live decision — useful in tests and in what-if UI.

Request

$POST /v1/decisions
curl -X POST "https://api.rateapi.dev/v1/decisions" \
-H "Authorization: Bearer $RATEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"decision_type": "financing",
"context": { "geo": { "state": "NC", "zip": "28202" } },
"product_request": {
"product_type": "auto_loan",
"amount": 35000,
"term_months": 60
}
}'
{}200 OK
{
"request_id": "...",
"decision_type": "financing",
"as_of": "2026-08-22T01:00:00Z",
"actions": [
{
"type": "...",
"offers": [
{
"rank": 1,
"credit_union_id": "electel cooperative|raleigh|NC",
"credit_union_name": "Electel Cooperative Credit Union",
"state": "NC",
"product_type": "auto_new",
"product_name": "New Auto Loan",
"rate": 3.65,
"apr": 3.65,
"monthly_payment": 639.06,
"last_updated": "2026-08-21T09:05:55.973Z",
"eligibility": {
"status": "unknown",
"eligibility_type": "multi",
"confidence": 0.98,
"unknown_reason": "charter_type_not_geo_matchable",
"requirements_summary": "Membership via employers (A &N Electric +49 more) or the North Carolina or Virginia electric or telephone cooperatives"
},
"true_cost": { "...": "..." }
}
]
}
],
"disclosures": ["..."]
}

Eligibility-aware product routing

The pattern worth copying: use graph-first product routing when membership matters, and preserve its ranking basis and proof.

JSPOST /v1/reachable-offers
// When membership matters, use the graph-first product-routing endpoint.
const matched = await rateapi("/v1/reachable-offers", {
person: {
home_zip: user.zip,
employer: user.employer,
willing_to_join_association: true,
},
product: {
product_type: "auto_loan",
intent: "purchase",
amount: 35_000,
term_months: 60,
vehicle_condition: "new",
audience: "consumer",
},
});
// Already ordered by matched.ranking_basis, with membership and product proof.
const promotedMatches = matched.reachable_now;
const oneStepMatches = matched.reachable_after_action;
Do not derive a market median from the cheapest offer. The top of a sorted list is the extreme of a distribution, not its centre. When you need a representative comparison point, use /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