Give us a customer profile. Know which products to show—and why.

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 fresh evidenced rates those institutions publish. POST /v1/reachable-offers is the product-routing entry point.

Read the API docs →
Last updated 2026-09-20Live endpoint, not a waitlistEnterprise API & MCPEvidence on every promoted resultNo credit check required

What is a financial product eligibility API?

A financial product eligibility API turns customer facts and published access rules into an explainable list of products the customer may be able to access.

In RateAPI, “eligible” has a deliberately narrow meaning: the customer has a published path to join the US credit union offering the product. The API can match geography, employer, school, association, military, worship, and family facts without a credit pull. It then intersects that membership result with current published product rates. It does not predict underwriting, approve an application, or claim that a customer qualifies for credit.

Access eligibility
Can this customer reach the institution and product? RateAPI answers this from published membership rules and product evidence.
Prequalification
Does the customer appear to meet a lender’s credit criteria? This may use income, debt, credit, collateral, and lender policy; RateAPI does not decide it.
Approval
Will the lender extend credit on final terms? Only the lender can answer after its application and underwriting process.
Use the right verb in your product. Say a customer “may be able to access” or “appears eligible to join,” not that they “qualify for” a loan. Product access, credit prequalification, and approval are three different decisions.

Which eligibility question does RateAPI answer?

RateAPI determines product access from published rules; it does not determine whether a lender will approve the consumer.

Which products can this user access?
Use POST /v1/reachable-offers. Send confirmed person facts and one product request; receive evidence-backed credit-union products grouped by access status.
Which products are available in this location?
Send home_zip, or home_state plus home_county. A location match counts only where a published geographic membership rule supports it; other membership paths are evaluated too.
Which loans does this customer qualify for?
RateAPI cannot make that claim. It can identify accessible institutions and published loan products, but credit qualification requires the lender’s underwriting criteria and application process.
Which institutions can this person join?
Use POST /v1/eligibility/search when no product has been chosen. The result explains each matching membership path without treating missing evidence as rejection.
Short answer: use RateAPI as the eligibility rules engine before a product catalog or comparison. It converts location and affiliation facts into explainable access paths, then returns only current product matches whose membership and pricing evidence can be inspected. The lender remains the authority for qualification and approval.

The problem this solves

A published rate becomes a credible customer option only when there is a documented path to the institution. Most rate data answers “what does this product cost?” and leaves the harder question — “does this product belong in front of this customer?” — 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.

  1. 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.

  2. The complete active fleet first

    Every active US credit union is evaluated against all active published graph rules RateAPI holds before rate lookup. The visible result limit cannot erase a family, employer, association, military, or geography path.

  3. Evidence-backed rates intersected

    In the same request, RateAPI looks for a fresh, rankable, source-evidenced rate only inside that graph-positive institution set. Reachable results require both complete membership evidence and complete rate evidence.

Eligibility to join is not credit approval. This endpoint answers whether a person can become a member of an institution. Whether that institution will then approve them for a specific loan is a separate decision that belongs to the lender. Presenting an eligibility verdict to an end user as an approval would be wrong, and the API’s inline disclosure says so on every response.

The endpoints

POST/v1/reachable-offers

Graph-first product routing. Send person facts plus a product request; receive fresh, evidenced published rates grouped by membership status. MCP: find_reachable_offers.

POST/v1/eligibility/search

Person-based discovery. “Which institutions can THIS person join?” Returns four membership buckets with evidence, without requiring a product request.

GET/v1/eligibility/search

The inverse lookup. “Which institutions’ published membership area reaches this county?” Same path, different question — useful for coverage maps and geo-first product surfaces.

POST/v1/eligibility/check

Batch verdicts against a known set of institutions, for when you already have a shortlist and need it evaluated rather than discovered. Home geography accepts both the original state/zip/county fields and the home_state/home_zip/home_county aliases returned bymissing_facts; conflicting duplicate forms are rejected.

GET/v1/credit-unions/:id/eligibility

The full membership-eligibility record for one institution — every published rule, with its source and evidence quote.

GET/v1/eligibility/coverage

What the whole graph holds: institutions with live rules and their share of the fleet, rules by kind, counties and employers named, verification and freshness — with a dated, quotable headline. Enterprise Routes. MCP: get_eligibility_coverage.

Graph-first product routing

One request evaluates the complete active membership fleet before it asks which graph-positive institutions publish the requested product.

$POST /v1/reachable-offers
curl -X POST "https://api.rateapi.dev/v1/reachable-offers" \
-H "Authorization: Bearer $RATEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"person": {
"home_state": "NC",
"home_county": "Mecklenburg",
"employer": "Atrium Health",
"willing_to_join_association": true
},
"product": {
"product_type": "auto_loan",
"amount": 35000,
"term_months": 60,
"vehicle_condition": "new"
},
"limit": 10
}'
reachable_now
A verified membership path and a fresh, evidenced published rate.
reachable_after_action
A documented membership action remains, such as joining an association, and a fresh evidenced rate is published.
unresolved
A matching rate exists, but membership or rate proof is incomplete, or the membership path is only possible. Unknown is not unavailable.
no_published_offer
No matching fresh evidenced rate was found. This remains unknown, never a product-unavailable claim.
discovery
candidate_scope=active_fleet and candidate_set_truncated=false prove every active credit union was evaluated before result slicing.
as_of
Latest observation timestamp among the returned rate rows; every offer also carries its own as_of and source evidence.
Published pricing is not approval or guaranteed final availability. The endpoint proves the membership path and published rate it uses; the credit union confirms final availability, underwriting, and terms.

Request

Every field is optional. Send what you have.

$POST /v1/eligibility/search
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.
home_city
Census-recognized city. Requires home_state or a recognized home_zip that uniquely identifies one state; unresolved labels are rejected rather than guessed.
work_city
Census-recognized workplace city, paired only with work_state or work_zip.
payroll_city
Census-recognized payroll-processing city, paired only with payroll_state or payroll_zip.
property_city
Census-recognized city where the person owns property, paired only with property_state or property_zip.
facility_city
Census-recognized city where the applicant business maintains a facility, paired only with facility_state or facility_zip.
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.

{}200 OK
{
"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.
There is no ineligible bucket, deliberately. An institution that fails every path is absent from the response rather than listed as a rejection. A false “ineligible” costs a consumer an institution they could have joined, which is a worse error than an honest “unknown” — so the API refuses to make it.

Membership-only discovery

Use this when the question is who the person may join and no product has been named.

$POST /v1/eligibility/search
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
}'
When a product is named, use POST /v1/reachable-offers instead of manually joining membership results to /v1/rates. Use POST /v1/decisions for underwriting-oriented financing analysis beyond membership routing — 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