---
title: "Discover evidence-backed access across explicit loan and deposit products"
method: POST
path: "/v1/access-catalog"
tags: ["Primary - Decisions"]
---

# Discover evidence-backed access across explicit loan and deposit products

`POST /v1/access-catalog`

## Request

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

Evaluates one person's confirmed membership facts once against the complete active credit-union fleet, then composes the existing reachable-offers rules across 1-19 unique explicit product selectors. Membership, published product availability, product suitability, published pricing, underwriting, and approval are separate response layers. Published prices are not quotes, underwriting results, preapprovals, commitments, or guarantees of final availability. Unknown is never ineligible. The initial implementation performs one eligibility discovery followed by one rate query per selector and reports that strategy in completeness.

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

## Request body

- object
  - `person` Person, required (unresolved $ref)
  - `products` Product[], required: Unique explicit product selectors. Omitted scenario facts remain unresolved; the API never invents an amount, balance, term, intent, audience, vehicle condition, or occupancy. (unresolved $ref)
  - `limit_per_product` integer: Maximum detail rows returned for each selector, subject to the total cap and plan cap.
  - `total_limit` integer: Maximum detail rows returned across all selectors.

## Response `200`

Multi-product, positive-evidence-only personal access catalog.

- AccessCatalogResponse: One-snapshot, multi-product personal access catalog with explicit semantic layers and bounded details.
  - `catalog_version` 'access_catalog_v1', required: Stable response-contract version.
  - `products` object[], required: One result in request order for every explicit product selector.
    - `request` Product, required (unresolved $ref)
    - `ranking_basis` string, required: Published-price ordering used within this selector.
    - `ranking` object, required: Explicit declaration of the decision layers this ranking does not perform.
      - `personalized_underwriting` false, required: Always false; catalog ranking is not underwriting.
      - `approval_evaluated` false, required: Always false; RateAPI does not make approval decisions.
    - `counts` Counts, required (unresolved $ref)
    - `reachable_now` AccessCatalogRow[], required: Rows with proven present membership access, satisfied published constraints, and evidenced pricing.
      - `credit_union_id` string, required: Stable credit-union identifier.
      - `institution` object, required: Institution name, state, and published URL where available.
      - `membership` object, required: Positive-evidence-only membership verdict and active-publication proof.
      - `product_availability` object, required: Whether matching fresh evidenced published pricing was found; unknown never means unavailable.
      - `product_suitability` object: Evaluation of only the explicit published constraints and supplied scenario facts.
      - `published_price` object: Fresh, rankable published price with explicitly published APY for deposits and published APR or clearly labeled nominal rate for lending, plus source evidence and per-row as_of. APR and nominal rate are never treated as interchangeable.
      - `underwriting` object, required: Explicit statement that creditworthiness and underwriting were not evaluated.
        - `status` 'not_evaluated', required: Catalog underwriting status; always not_evaluated.
        - `reason` string, required: Why no underwriting conclusion may be drawn.
      - `approval` object, required: Explicit statement that RateAPI did not evaluate or grant approval.
        - `status` 'not_evaluated_by_rateapi', required: Approval status; always not_evaluated_by_rateapi.
        - `reason` string, required: Why only the institution can approve and confirm final terms.
    - `reachable_after_action` AccessCatalogRow[], required: Rows requiring a source-proven membership action before access.
      - `credit_union_id` string, required: Stable credit-union identifier.
      - `institution` object, required: Institution name, state, and published URL where available.
      - `membership` object, required: Positive-evidence-only membership verdict and active-publication proof.
      - `product_availability` object, required: Whether matching fresh evidenced published pricing was found; unknown never means unavailable.
      - `product_suitability` object: Evaluation of only the explicit published constraints and supplied scenario facts.
      - `published_price` object: Fresh, rankable published price with explicitly published APY for deposits and published APR or clearly labeled nominal rate for lending, plus source evidence and per-row as_of. APR and nominal rate are never treated as interchangeable.
      - `underwriting` object, required: Explicit statement that creditworthiness and underwriting were not evaluated.
        - `status` 'not_evaluated', required: Catalog underwriting status; always not_evaluated.
        - `reason` string, required: Why no underwriting conclusion may be drawn.
      - `approval` object, required: Explicit statement that RateAPI did not evaluate or grant approval.
        - `status` 'not_evaluated_by_rateapi', required: Approval status; always not_evaluated_by_rateapi.
        - `reason` string, required: Why only the institution can approve and confirm final terms.
    - `unresolved` AccessCatalogRow[], required: Rows that cannot be promoted because membership proof or product suitability remains unresolved.
      - `credit_union_id` string, required: Stable credit-union identifier.
      - `institution` object, required: Institution name, state, and published URL where available.
      - `membership` object, required: Positive-evidence-only membership verdict and active-publication proof.
      - `product_availability` object, required: Whether matching fresh evidenced published pricing was found; unknown never means unavailable.
      - `product_suitability` object: Evaluation of only the explicit published constraints and supplied scenario facts.
      - `published_price` object: Fresh, rankable published price with explicitly published APY for deposits and published APR or clearly labeled nominal rate for lending, plus source evidence and per-row as_of. APR and nominal rate are never treated as interchangeable.
      - `underwriting` object, required: Explicit statement that creditworthiness and underwriting were not evaluated.
        - `status` 'not_evaluated', required: Catalog underwriting status; always not_evaluated.
        - `reason` string, required: Why no underwriting conclusion may be drawn.
      - `approval` object, required: Explicit statement that RateAPI did not evaluate or grant approval.
        - `status` 'not_evaluated_by_rateapi', required: Approval status; always not_evaluated_by_rateapi.
        - `reason` string, required: Why only the institution can approve and confirm final terms.
    - `no_published_price` AccessCatalogRow[], required: Graph-positive institutions with no matching fresh, rankable, evidenced published price; absence is not unavailability.
      - `credit_union_id` string, required: Stable credit-union identifier.
      - `institution` object, required: Institution name, state, and published URL where available.
      - `membership` object, required: Positive-evidence-only membership verdict and active-publication proof.
      - `product_availability` object, required: Whether matching fresh evidenced published pricing was found; unknown never means unavailable.
      - `product_suitability` object: Evaluation of only the explicit published constraints and supplied scenario facts.
      - `published_price` object: Fresh, rankable published price with explicitly published APY for deposits and published APR or clearly labeled nominal rate for lending, plus source evidence and per-row as_of. APR and nominal rate are never treated as interchangeable.
      - `underwriting` object, required: Explicit statement that creditworthiness and underwriting were not evaluated.
        - `status` 'not_evaluated', required: Catalog underwriting status; always not_evaluated.
        - `reason` string, required: Why no underwriting conclusion may be drawn.
      - `approval` object, required: Explicit statement that RateAPI did not evaluate or grant approval.
        - `status` 'not_evaluated_by_rateapi', required: Approval status; always not_evaluated_by_rateapi.
        - `reason` string, required: Why only the institution can approve and confirm final terms.
    - `questions` object[], required: Product-aware missing-fact questions that may clarify reachability.
    - `completeness` object, required: Exact counts and bounded-detail disclosure for this selector.
      - `active_fleet_evaluated` true, required: True only when eligibility evaluated the complete active fleet.
      - `counts_exact` true, required: Whether bucket counts were computed before detail caps.
      - `detail_limit` integer, required: Detail-row allowance remaining for this selector after global caps.
      - `details_returned` integer, required: Detail rows actually returned for this selector.
      - `details_truncated` boolean, required: Whether exact bucket counts exceed returned detail rows.
  - `questions` object, required: Membership questions shared across all selectors.
  - `snapshot` object, required: Eligibility generation boundary, returned-price observation range, and response generation time.
  - `completeness` object, required: Request-wide fleet, selector, cap, truncation, and execution-strategy disclosure.
    - `active_fleet_evaluated` true, required: True only when the complete active eligibility fleet was evaluated.
    - `candidate_set_truncated` false, required: Always false; rate intersection uses every graph-positive candidate.
    - `selector_count` integer, required: Number of explicit product selectors evaluated.
    - `selectors_explicit` true, required: Always true; RateAPI does not silently expand product families.
    - `evaluation_strategy` 'one_eligibility_discovery_then_one_batched_rate_query', required: One exhaustive eligibility evaluation followed by one semantics-preserving batched rate statement.
    - `rate_query_count` integer, required: Rate-corpus statements executed; zero when the eligibility result contains no rate candidates.
    - `proof_strategy` 'one_shared_current_publication_query', required: Eligibility proof is hydrated once against current publication lineage and shared across selectors.
    - `limit_per_product` integer, required: Maximum detail rows allocated to any selector before the request-wide cap.
    - `total_detail_limit` integer, required: Request-wide returned-detail cap; exact counts are computed before this cap.
    - `details_truncated` boolean, required: Whether any exact selector count exceeds its returned detail rows.
  - `semantics` 'positive_evidence_only', required: Interpretation contract: missing or unknown evidence never proves a negative.
  - `disclosure` string, required: Required consumer-facing distinction between access, pricing, underwriting, and 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)
