How to find which credit unions a user can join.

Send what you know about the user to POST /v1/eligibility/search and you get back credit unions in four buckets: ones they can join now, ones they can join after one small step, ones that plausibly apply, and ones we cannot judge yet. A ZIP code alone is enough to start.

Last updated 2026-08-21Working codeFree tier: 20 requests/month

Why you cannot just look this up

A credit union may only serve its field of membership — the group its charter defines. That rule is set per institution and published as prose on thousands of separate websites. There is no registry that answers “can this person join?”, which is why the usual first attempt is a hand-maintained spreadsheet, and why the usual second attempt is this API.

The rules also move — charters expand, employer lists change, community areas are redrawn. A snapshot taken today is wrong within months. See field of membership explained for developers for the domain model.

The implementation

  1. Ask one question, then call

    ZIP is the highest-value single field: it resolves server-side to county and state, and community charters are the most common kind. Do not build a five-question form before the first call.

    JSFirst call
    // 1. One question is enough to start: their ZIP.
    const response = await fetch("https://api.rateapi.dev/v1/eligibility/search", {
    method: "POST",
    headers: {
    Authorization: `Bearer ${process.env.RATEAPI_KEY}`,
    "Content-Type": "application/json",
    },
    body: JSON.stringify({
    home_zip: "28202",
    // The highest-leverage field on the whole request. Without it, credit
    // unions reachable via an affiliated association are held back.
    willing_to_join_association: true,
    }),
    });
    const result = await response.json();
    console.log(result.counts);
    // { eligible: 13, conditionally_eligible: 2, possibly_eligible: 0, unknown: 20 }
  2. Render the two actionable buckets — with reasons

    Show eligible and conditionally_eligible. Always render the reason: “you qualify because you live in Mecklenburg County” is the difference between a list and an answer, and it is already in the response.

    JSRendering verdicts
    // 2. Render the two buckets that are actionable, and say WHY each qualifies.
    for (const cu of result.eligible) {
    console.log(cu.name, "—", cu.reasons[0]);
    // Charlotte Metro Credit Union — You appear to be eligible to join.
    // Qualifies: Live or work in Mecklenburg County
    }
    for (const cu of result.conditionally_eligible) {
    console.log(cu.name, "— one step:", cu.reasons[0], `($${cu.join_cost_usd ?? "?"})`);
    }
  3. Refine with facts you learn later

    Same endpoint, more fields. Employers are resolved against an alias index, so you can pass what the user typed rather than a canonical id.

    JSRefining
    // 3. Refine with what you learn later. Same endpoint, more facts.
    const refined = await rateapi("/v1/eligibility/search", {
    home_zip: user.zip,
    employer: user.employer, // resolved against an alias index
    school: user.school,
    school_relationship: "alumni",
    military_status: user.isVeteran ? "veteran" : undefined,
    associations: user.groups, // up to 20
    willing_to_join_association: true,
    limit: 50,
    });
  4. Price what they can reach

    A credit union they can join is only interesting if its products are good. Filter rates to the reachable set — a cheaper rate somewhere they cannot join is not an offer.

    JSEligibility-filtered rates
    // 4. Eligibility alone is half an answer. Price what they can reach.
    const rates = await rateapi("/v1/rates", {
    product_type: "auto_loan",
    state: user.state,
    sort: "apr_asc",
    limit: 50,
    });
    const reachable = new Set(
    [...refined.eligible, ...refined.conditionally_eligible].map((c) => c.credit_union_id)
    );
    // Only show rates at institutions this person can actually join.
    const offers = rates.rates.filter((row) => reachable.has(row.credit_union_id));

The four buckets, and what to do with each

eligible
Show these first, with the reason. A published rule matched the facts you sent.
conditionally_eligible
Show these second, with the step and its cost. Often a few dollars to join an association — frequently the best rates in the whole set.
possibly_eligible
Use these to drive your next question. A rule plausibly applies; one more fact usually resolves it.
unknown
Do not show as results and do not treat as ineligible. Surface as a count with a link out, or hold silently.
Never present a verdict as an approval. Eligibility here is guidance from public data; the institution makes the final determination, and every response carries that disclosure. It is also unrelated to credit approval for a specific loan.

Frequently asked