Give us a consumer. We tell you what they can actually get.
RateAPI’s eligibility API accepts consumer attributes — where they live, who they work for, where they studied, what they belong to — and returns the financial institutions that consumer appears eligible to join, what it would take to join the ones they cannot yet, and the live rates on the products those institutions offer. POST /v1/eligibility/search is the entry point.
The problem this solves
A rate is only useful to a consumer who can actually get it. Most rate data answers “what does this product cost?” and leaves the harder question — “can this particular person even open it?” — to you. For US credit unions that question is genuinely hard: eligibility is governed by each institution’s field of membership, published as prose across thousands of separate websites and charter documents.
Consumer facts in
Send whatever you know. Every field is optional; the endpoint needs at least one discriminating fact and gets sharper as you send more. No SSN, no date of birth, no credit pull.
Institution eligibility out
Candidates are narrowed with indexed lookups, then each is evaluated against its whole rule set — never on the strength of the one condition that surfaced it — and bucketed by verdict with its evidence.
Products and rates
Take the institutions from step 2 into
POST /v1/ratesorPOST /v1/decisionsto get the products they offer and what those products cost today.
The endpoints
/v1/eligibility/searchPerson-based discovery. “Which institutions can THIS person join?” Returns four buckets with evidence. This is the endpoint most integrations start with.
/v1/eligibility/searchThe inverse lookup. “Which institutions’ published membership area reaches this county?” Same path, different question — useful for coverage maps and geo-first product surfaces.
/v1/eligibility/checkBatch verdicts against a known set of institutions, for when you already have a shortlist and need it evaluated rather than discovered.
/v1/credit-unions/:id/eligibilityThe full membership-eligibility record for one institution — every published rule, with its source and evidence quote.
Request
Every field is optional. Send what you have.
curl -X POST "https://api.rateapi.dev/v1/eligibility/search" \ -H "Authorization: Bearer $RATEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "home_state": "NC", "home_county": "Mecklenburg", "employer": "Atrium Health", "military_status": "veteran", "associations": ["American Consumer Council"], "willing_to_join_association": true, "limit": 25 }'- home_zip
- ZIP code. Resolved server-side to county and state, so this one field usually does the most work.
- home_state
- Two-letter state code.
- home_county
- County name. "Mecklenburg" and "Mecklenburg County" both resolve.
- employer
- Employer name, resolved against an organisation alias index — you do not need to send a canonical id.
- school
- School name, with school_relationship as student, alumni, or employee.
- associations
- Up to 20 association or membership-group names.
- military_status
- active_duty, veteran, reservist, dod_civilian, or military_family.
- worship
- Place of worship, for institutions chartered around a congregation.
- willing_to_join_association
- When true, institutions reachable by joining an affiliated association are surfaced as conditionally eligible rather than dropped. This one boolean typically moves the most institutions.
- limit
- Entries returned per bucket. Default 50, maximum 200.
Response
Four buckets, each sorted by confidence, each item carrying the evidence for its verdict.
{ "counts": { "eligible": 13, "conditionally_eligible": 2, "possibly_eligible": 0, "unknown": 20 }, "candidates_evaluated": 35, "eligible": [ { "credit_union_id": "charlotte metro|charlotte|NC", "name": "Charlotte Metro Credit Union", "state": "NC", "status": "eligible", "confidence": 1, "reasons": [ "You appear to be eligible to join. Qualifies: Live or work in Mecklenburg County" ], "paths": [ { "rule_id": 4848, "kind": "geography", "reason": "Qualifies: Live or work in Mecklenburg County", "conditions_matched": ["geo_residence"], "status": "eligible" } ], "engine": "graph" } ], "conditionally_eligible": [ { "credit_union_id": "american 1|jackson|MI", "name": "American 1 Credit Union", "state": "MI", "status": "conditionally_eligible", "confidence": 1, "reasons": [ "You can join by completing one additional step. Qualifies after one step: Open to anyone and Qualifying payment of $3 — requires a qualifying deposit or donation of $3." ], "join_cost_usd": 3, "engine": "graph" } ], "resolved": { "orgs": [], "geo_keys": ["state:NC", "county:NC:mecklenburg"] }, "limit": 25, "engine": "graph+legacy_fallback", "disclosure": "Membership eligibility is guidance based on public charter data and institution websites; final determination is made by the institution."}- eligible
- A published rule matches the facts you sent.
- conditionally_eligible
- One additional step qualifies them. The reason names the step, and join_cost_usd carries its cost when the rule states one.
- possibly_eligible
- A rule plausibly applies, but the facts you sent do not confirm it. Usually resolved by asking the user one more question.
- unknown
- We hold the institution but not enough rule data to judge. Unknown is NEVER treated as ineligible.
- confidence
- 0–1. Reflects the quality of the underlying rule evidence, not the strength of the match.
- paths
- The structured rules that matched — rule_id, kind, and the conditions satisfied. Log these for audit; render reasons for humans.
- engine
- graph when the verdict came from published rules, legacy for the annotation fallback on institutions the rule graph has not reached yet.
- candidates_evaluated
- How many institutions were actually assessed to produce this answer.
Consumer → institution → product → rate
Eligibility on its own is half an answer. The other half is what the eligible institutions actually sell, and for how much.
# 2. Now price the products those institutions actually offer.curl -X POST "https://api.rateapi.dev/v1/rates" \ -H "Authorization: Bearer $RATEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "product_type": "auto_loan", "state": "NC", "sort": "apr_asc", "limit": 25 }'POST /v1/decisions takes the same consumer context and returns ordered offers with the reasoning attached — see the recommendation API.Coverage and freshness
- Institutions
- Thousands of US credit unions, with membership rules sourced from public charter data and institution websites.
- Rule provenance
- Every rule carries its source and an evidence quote. You can always see why a verdict was reached.
- Rate freshness
- Rate rows carry an as_of timestamp and are filtered for freshness before they are served. See /data-coverage for the current windows.
- Rule coverage
- Not every institution has machine-readable rules yet. Those land in unknown rather than being guessed at — coverage gaps shrink the answer’s confidence, never its recall.
Frequently asked
It decides which institutions a consumer appears able to JOIN, based on published field-of-membership rules — geography, employer, school, association, military service, and family relationships. It does not decide creditworthiness and it does not run a credit check. Joining eligibility and credit approval are different questions, and this endpoint answers only the first.
eligible means a published rule matches the facts you sent. conditionally_eligible means one additional step qualifies them — usually joining an affiliated association for a small fee, and the response names the step and its cost. possibly_eligible means a rule plausibly applies but the facts you sent do not confirm it. unknown means we hold the institution but not enough rule data to judge. A two-value answer would have to collapse "you can join for $5" and "we do not know" into the same bucket, and those lead to completely different product behaviour.
Because we are not confident enough to publish one, and a wrong ineligible verdict is much more damaging than a wrong unknown. An institution that deterministically fails every path is simply absent from the response. Unknown is never treated as ineligible anywhere in the system.
Each item carries reasons (deterministic sentences, never model prose), a confidence score, and paths — the structured rules that matched, each with a rule_id, the kind of rule, and the conditions that were satisfied. You can render the reason to a user or log the path for audit.
The endpoint narrows on indexed inverse lookups from the facts you send, then evaluates every candidate against that institution’s full rule set — never on the strength of the single condition that surfaced it. The response reports candidates_evaluated so you can see the size of the search that produced your answer.
Guidance. It is derived from public charter data and institution websites, and the final determination is always made by the institution. Every response carries that disclosure inline. Do not present a verdict to an end user as an approval.