---
title: "Find the best evidence-backed offers this person can reach"
method: POST
path: "/v1/reachable-offers"
tags: ["Primary - Decisions"]
---

# Find the best evidence-backed offers this person can reach

`POST /v1/reachable-offers`

## Request

- Base URL: `https://api.rateapi.dev`
- URL: `https://api.rateapi.dev/v1/reachable-offers`
- Auth: API key in header `X-API-Key`

The graph-first routing operation. It evaluates every active US credit union before querying rates, then restricts rate retrieval to graph-positive institutions. `reachable_now` requires a verified membership path and a fresh, evidenced published rate; `reachable_after_action` requires the same rate proof plus a documented membership action. Every rate includes source evidence and `as_of`, and every routed membership result preserves active-publication lineage and exact source proof. The caller's visible result cap is applied only after the exhaustive graph/rate intersection. Absence is never an ineligibility or product-unavailability verdict, and published pricing is not approval or guaranteed final availability.

**Authentication required**: Pass your API key in the `X-API-Key` header.

## Request body

- object
  - `person` object, required: Person facts accepted by POST /v1/eligibility/search, excluding its public per-bucket limit. Home, work, payroll, property and facility geography are independent facts.
    - `home_zip` HomeZip (unresolved $ref)
    - `home_state` HomeState (unresolved $ref)
    - `home_county` HomeCounty (unresolved $ref)
    - `home_city` HomeCity (unresolved $ref)
    - `work_zip` WorkZip (unresolved $ref)
    - `work_state` WorkState (unresolved $ref)
    - `work_county` WorkCounty (unresolved $ref)
    - `work_city` WorkCity (unresolved $ref)
    - `payroll_zip` PayrollZip (unresolved $ref)
    - `payroll_state` PayrollState (unresolved $ref)
    - `payroll_county` PayrollCounty (unresolved $ref)
    - `payroll_city` PayrollCity (unresolved $ref)
    - `occupation` Occupation (unresolved $ref)
    - `employer` Employer (unresolved $ref)
    - `employer_org_ids` EmployerOrgIds (unresolved $ref)
    - `school` School (unresolved $ref)
    - `school_org_ids` SchoolOrgIds (unresolved $ref)
    - `school_relationship` SchoolRelationship (unresolved $ref)
    - `associations` Associations (unresolved $ref)
    - `association_org_ids` AssociationOrgIds (unresolved $ref)
    - `military_status` MilitaryStatus (unresolved $ref)
    - `worship` Worship (unresolved $ref)
    - `worship_org_ids` WorshipOrgIds (unresolved $ref)
    - `family_relation` FamilyRelation (unresolved $ref)
    - `relative_employers` RelativeEmployers (unresolved $ref)
    - `relative_employer_org_ids` RelativeEmployerOrgIds (unresolved $ref)
    - `relative_schools` RelativeSchools (unresolved $ref)
    - `relative_school_org_ids` RelativeSchoolOrgIds (unresolved $ref)
    - `relative_associations` RelativeAssociations (unresolved $ref)
    - `relative_association_org_ids` RelativeAssociationOrgIds (unresolved $ref)
    - `relative_memberships` RelativeMemberships (unresolved $ref)
    - `willing_to_join_association` WillingToJoinAssociation (unresolved $ref)
    - `property_zip` PropertyZip (unresolved $ref)
    - `property_state` PropertyState (unresolved $ref)
    - `property_county` PropertyCounty (unresolved $ref)
    - `property_city` PropertyCity (unresolved $ref)
    - `facility_zip` FacilityZip (unresolved $ref)
    - `facility_state` FacilityState (unresolved $ref)
    - `facility_county` FacilityCounty (unresolved $ref)
    - `facility_city` FacilityCity (unresolved $ref)
    - `applicant_kind` ApplicantKind (unresolved $ref)
    - `military_service_state` MilitaryServiceState (unresolved $ref)
    - `asserted_org_qualifiers` AssertedOrgQualifiers (unresolved $ref)
  - `product` object, required: Product family and optional attributes used to select the best matching published rate at each graph-positive institution.
    - `product_type` 'mortgage' | 'mortgage_arm' | 'auto_loan' | 'rv' | 'boat' | 'motorcycle' | 'powersports' | 'heloc' | 'personal_loan' | 'student_loan' | 'equipment_loan' | 'credit_card' | 'savings' | 'cd' | 'share_certificate' | 'money_market' | 'ira_cd' | 'ira' | 'share_savings', required: Canonical loan or deposit product family.
    - `intent` 'purchase' | 'refinance' | 'cash_out' | 'balance_transfer' | 'new_credit': Transaction intent when it changes rate-row matching.
    - `amount` number: Requested loan or credit amount in USD.
    - `balance` number: Expected deposit balance in USD for tier matching.
    - `term_months` integer: Requested product term in months.
    - `vehicle_condition` 'new' | 'used' | 'certified_pre_owned' | 'any': Vehicle condition for auto-loan matching.
    - `audience` 'business' | 'consumer': Business or consumer product audience.
    - `occupancy` 'primary' | 'secondary' | 'investment': Property occupancy for mortgage matching.
  - `limit` integer: Visible rows per result bucket. The graph/rate intersection happens before this cap.

## Response `200`

Graph-first, evidence-backed routing result.

- ReachableOffersResponse: Evidence-backed results from exhaustive graph-first membership discovery followed by fresh published-rate intersection.
  - `product` object, required: Normalized product request used for matching.
  - `ranking_basis` string, required: Price direction and membership-cost tie-breaker used to rank results. Deposits use published APY. Lending ranks published APR rows first, then a separately labeled nominal-rate group; APR and nominal rate are never numerically compared.
  - `counts` object, required: Full pre-display-cap counts for each reachability bucket.
    - `reachable_now` integer, required: Offers with at least one verified membership OR-path and a fresh, evidenced published rate.
    - `reachable_after_action` integer, required: Offers with a documented membership action and a fresh, evidenced published rate.
    - `unresolved` integer, required: Published-rate matches with no verified membership path, incomplete rate proof, possible-only membership, or unresolved product suitability.
    - `no_published_offer` integer, required: Graph-positive institutions for which no matching fresh evidenced rate was found. This is unknown, not unavailable.
  - `reachable_now` ReachableOfferResult[], required: The person has a verified membership path and the institution publishes a fresh, evidenced matching rate.
    - `credit_union_id` string, required: Canonical credit-union identifier.
    - `institution` object, required: Display name, state, and available institution links.
    - `membership` object, required: Deterministic membership verdict and publication lineage. `paths` contains only source-proven winning OR alternatives; `unproven_paths` preserves other claimed winning alternatives without making them actionable.
      - `paths` EligibilityGraphPath[]: Winning membership OR-paths proven by exact-publication confirmations. One proven path is sufficient for the membership decision.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `unproven_paths` EligibilityGraphPath[]: Other winning OR alternatives lacking exact-publication proof. They remain diagnostic and are never presented as actionable proof.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `proof_completeness` object: Counts exact-current-publication proof across the winning membership OR alternatives without treating an unproven alternative as actionable evidence.
        - `used_path_count` integer, required: Number of winning OR alternatives claimed by the eligibility verdict.
        - `proven_path_count` integer, required: Number of winning alternatives with exact-current-publication source proof.
        - `decision_proven` boolean, required: True when at least one winning OR alternative is fully proven.
        - `complete` boolean, required: True when every claimed winning alternative is proven; this may be false while decision_proven is true.
    - `product_availability` object, required: Whether a fresh, rankable, evidence-backed matching rate was found.
    - `product_suitability` object: A separate check of the supplied product dimensions against published facts, including balance, audience, term, intent, vehicle condition, and occupancy when applicable. Unknown or mismatched exact dimensions keep an offer unresolved instead of implying the product fits.
    - `offer` object: Best matching fresh rate for this institution, preserving exact product_name, constraints, source evidence, and observation time. Deposit `apy` is present only when the source explicitly published APY; nominal dividend/interest is never relabeled as yield. Lending `apr` is present only when published as APR; otherwise `rate` remains a clearly distinct nominal rate. Absent when no matching evidenced rate is held.
  - `reachable_after_action` ReachableOfferResult[], required: A documented membership action remains and the institution publishes a fresh, evidenced matching rate.
    - `credit_union_id` string, required: Canonical credit-union identifier.
    - `institution` object, required: Display name, state, and available institution links.
    - `membership` object, required: Deterministic membership verdict and publication lineage. `paths` contains only source-proven winning OR alternatives; `unproven_paths` preserves other claimed winning alternatives without making them actionable.
      - `paths` EligibilityGraphPath[]: Winning membership OR-paths proven by exact-publication confirmations. One proven path is sufficient for the membership decision.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `unproven_paths` EligibilityGraphPath[]: Other winning OR alternatives lacking exact-publication proof. They remain diagnostic and are never presented as actionable proof.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `proof_completeness` object: Counts exact-current-publication proof across the winning membership OR alternatives without treating an unproven alternative as actionable evidence.
        - `used_path_count` integer, required: Number of winning OR alternatives claimed by the eligibility verdict.
        - `proven_path_count` integer, required: Number of winning alternatives with exact-current-publication source proof.
        - `decision_proven` boolean, required: True when at least one winning OR alternative is fully proven.
        - `complete` boolean, required: True when every claimed winning alternative is proven; this may be false while decision_proven is true.
    - `product_availability` object, required: Whether a fresh, rankable, evidence-backed matching rate was found.
    - `product_suitability` object: A separate check of the supplied product dimensions against published facts, including balance, audience, term, intent, vehicle condition, and occupancy when applicable. Unknown or mismatched exact dimensions keep an offer unresolved instead of implying the product fits.
    - `offer` object: Best matching fresh rate for this institution, preserving exact product_name, constraints, source evidence, and observation time. Deposit `apy` is present only when the source explicitly published APY; nominal dividend/interest is never relabeled as yield. Lending `apr` is present only when published as APR; otherwise `rate` remains a clearly distinct nominal rate. Absent when no matching evidenced rate is held.
  - `unresolved` ReachableOfferResult[], required: A matching rate was found, but the membership or rate proof is incomplete, or the membership path is only possible. Unknown is not unavailable.
    - `credit_union_id` string, required: Canonical credit-union identifier.
    - `institution` object, required: Display name, state, and available institution links.
    - `membership` object, required: Deterministic membership verdict and publication lineage. `paths` contains only source-proven winning OR alternatives; `unproven_paths` preserves other claimed winning alternatives without making them actionable.
      - `paths` EligibilityGraphPath[]: Winning membership OR-paths proven by exact-publication confirmations. One proven path is sufficient for the membership decision.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `unproven_paths` EligibilityGraphPath[]: Other winning OR alternatives lacking exact-publication proof. They remain diagnostic and are never presented as actionable proof.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `proof_completeness` object: Counts exact-current-publication proof across the winning membership OR alternatives without treating an unproven alternative as actionable evidence.
        - `used_path_count` integer, required: Number of winning OR alternatives claimed by the eligibility verdict.
        - `proven_path_count` integer, required: Number of winning alternatives with exact-current-publication source proof.
        - `decision_proven` boolean, required: True when at least one winning OR alternative is fully proven.
        - `complete` boolean, required: True when every claimed winning alternative is proven; this may be false while decision_proven is true.
    - `product_availability` object, required: Whether a fresh, rankable, evidence-backed matching rate was found.
    - `product_suitability` object: A separate check of the supplied product dimensions against published facts, including balance, audience, term, intent, vehicle condition, and occupancy when applicable. Unknown or mismatched exact dimensions keep an offer unresolved instead of implying the product fits.
    - `offer` object: Best matching fresh rate for this institution, preserving exact product_name, constraints, source evidence, and observation time. Deposit `apy` is present only when the source explicitly published APY; nominal dividend/interest is never relabeled as yield. Lending `apr` is present only when published as APR; otherwise `rate` remains a clearly distinct nominal rate. Absent when no matching evidenced rate is held.
  - `no_published_offer` ReachableOfferResult[], required: No matching fresh evidenced rate is held. Absence is not an unavailability claim.
    - `credit_union_id` string, required: Canonical credit-union identifier.
    - `institution` object, required: Display name, state, and available institution links.
    - `membership` object, required: Deterministic membership verdict and publication lineage. `paths` contains only source-proven winning OR alternatives; `unproven_paths` preserves other claimed winning alternatives without making them actionable.
      - `paths` EligibilityGraphPath[]: Winning membership OR-paths proven by exact-publication confirmations. One proven path is sufficient for the membership decision.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `unproven_paths` EligibilityGraphPath[]: Other winning OR alternatives lacking exact-publication proof. They remain diagnostic and are never presented as actionable proof.
        - `rule_id` integer, required: Id of the published rule this path came from.
        - `kind` string, required: Rule family (e.g. community_geo, employer, association, military, school, worship, family).
        - `reason` string, required: Deterministic sentence describing the path.
        - `conditions_matched` string[], required: Canonical condition ids the supplied facts satisfied.
        - `conditions_unknown` string[]: Condition ids left unresolved — what to supply to decide this path.
        - `status` 'eligible' | 'conditionally_eligible' | 'possibly_eligible' | 'ineligible' | 'unknown': Set on non-positive paths so callers can explain the gap. `ineligible` is reserved for compatibility; current customer-safe projections normalize unattested path negatives to `unknown`.
        - `conditional_on` object: The one further step that would make this path apply.
          - `type` 'join_association' | 'family_link' | 'deposit_or_donation': The kind of action the borrower must take to satisfy this path.
          - `org_id` string: Identifier of the association, employer, or organization the borrower must join or link to.
          - `cost_usd` number: Up-front cost of the step, when published.
          - `join_url` string, uri: Page where the borrower can complete the joining step.
      - `proof_completeness` object: Counts exact-current-publication proof across the winning membership OR alternatives without treating an unproven alternative as actionable evidence.
        - `used_path_count` integer, required: Number of winning OR alternatives claimed by the eligibility verdict.
        - `proven_path_count` integer, required: Number of winning alternatives with exact-current-publication source proof.
        - `decision_proven` boolean, required: True when at least one winning OR alternative is fully proven.
        - `complete` boolean, required: True when every claimed winning alternative is proven; this may be false while decision_proven is true.
    - `product_availability` object, required: Whether a fresh, rankable, evidence-backed matching rate was found.
    - `product_suitability` object: A separate check of the supplied product dimensions against published facts, including balance, audience, term, intent, vehicle condition, and occupancy when applicable. Unknown or mismatched exact dimensions keep an offer unresolved instead of implying the product fits.
    - `offer` object: Best matching fresh rate for this institution, preserving exact product_name, constraints, source evidence, and observation time. Deposit `apy` is present only when the source explicitly published APY; nominal dividend/interest is never relabeled as yield. Lending `apr` is present only when published as APR; otherwise `rate` remains a clearly distinct nominal rate. Absent when no matching evidenced rate is held.
  - `discovery` object, required: Graph discovery telemetry. `candidate_scope` is `active_fleet`, `candidate_set_truncated` is false, and every active US credit union was evaluated before result slicing.
  - `completeness` object, required: Honest evaluation, proof-lineage, and response-cap metadata for this routing result.
    - `active_fleet_evaluated` boolean, required: True only when membership evaluation covered the active US credit-union fleet.
    - `candidate_set_truncated` boolean, required: Whether candidates were truncated before the rate intersection.
    - `membership_evidence` 'winning_paths_current_publication_only', required: Declares that exposed proof is limited to winning verdict paths and confirmations from the exact current active publication.
    - `result_limit_per_bucket` integer, required: Maximum number of detailed results returned in each bucket.
    - `no_published_offer_details_truncated` boolean, required: True when the count exceeds the visible no_published_offer detail list.
  - `as_of` string, date-time, nullable, required: Most recent observation timestamp among the matching rates, or null when no rate matched.
  - `eligibility_snapshot` object: Immutable eligibility graph generation and pinned rules clock used for this result. Present when snapshot serving is available.
    - `generation` string, required: Opaque immutable serving-snapshot generation identifier.
    - `rules_now` string, date-time, required: Pinned eligibility rules clock used throughout the request.
  - `semantics` 'positive_evidence_only', required: Declares that absence and unknown states are never interpreted as ineligibility.
  - `disclosure` string, required: Required distinction between evidence-backed routing, published pricing, final availability, and credit approval.

## Other responses

- `400`: The request was malformed — a missing required field, an unparseable body, or a parameter outside its allowed range. The `error` field names what was wrong; retrying the identical request will fail identically.
- `401`: No API key, or a key that is unknown or disabled. Send it in the `X-API-Key` header. Free keys are issued instantly by POST /keys with an email address. The response carries `WWW-Authenticate` pointing at this host's protected-resource metadata, and the `RateLimit-*` headers describing the Free-tier budget a key issued now would carry (scope `anonymous`) — a rejected request spends none of it, so `Remaining` equals `Limit`.
- `402`: The key is valid, but RateAPI Routes is available only on Enterprise. The response includes `required_plan`, `upgrade_url`, and a `Link` header with `rel="upgrade"`; the rejected request does not consume quota.
- `429`: Quota exhausted for the current window. `Retry-After` gives the seconds to wait; `upgradeInfo` explains how to lift the cap. Retrying before the reset will fail again and still counts as a request.

---

[API](https://skmtc.dev/rateapi/apis/rate-api.md) · [All operations](https://skmtc.dev/rateapi/apis/rate-api/llms.txt) · [OpenAPI document](https://skmtc.dev/rateapi/apis/rate-api/revisions/06a6db76995f?raw)
