---
title: "Credit-union deposit APYs (savings, cd, money_market, share_certificate) — list or benchmark"
method: POST
path: "/v1/deposit-rates"
tags: ["Data & Analytics"]
---

# Credit-union deposit APYs (savings, cd, money_market, share_certificate) — list or benchmark

`POST /v1/deposit-rates`

## Request

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

Deposit-side rate exposure: credit-union deposit APYs across savings, CD, share-certificate, money-market, IRA-CD/IRA, and share-savings products. `mode='list'` (default) returns deposit catalog rows with pagination; `mode='benchmark'` returns a per-CU roster ranked DESC by explicitly published APY plus the market min/median/max. Generic savings benchmarks compare tiers applicable at the disclosed $10,000 representative balance; restricted-audience and specialty/seasonal offers remain visible in list mode but cannot rank. APY is read only from an explicitly published yield, never inferred from the nominal interest/dividend rate. List rows expose `apy` (nullable), `apy_published`, separate `interest_rate`, `ranking_eligible`, stable `id` and `credit_union_id`, `constraints`, source `evidence`, and observed `as_of`. Missing APY remains null and cannot rank. CDs/share-certificates include `term_months`. Catalog and benchmark data are not a person's membership or product-suitability decision; use `/v1/reachable-offers` with confirmed facts for personalized offers. Current + recent data; history is retention-bounded. The MCP `get_deposit_benchmarks` tool and the consumer app call this route.

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

## Request body

- object
  - `product_category` 'savings' | 'cd' | 'share_certificate' | 'money_market' | 'ira_cd' | 'ira' | 'share_savings': Deposit product (maps to savings_type). Use the exact enum spelling; money market accounts are `money_market`, not `mma` or `money-market`. Omit for all deposit types.
  - `state` string: 2-letter US state code; omit for nationwide.
  - `lender` string: Case-insensitive substring match on credit-union name.
  - `term_months` number: For CD/share_certificate/ira_cd: filter to a specific term (savings_term_months).
  - `min_apy` number: Minimum explicitly published APY filter; nominal-only rows do not match.
  - `max_apy` number: Maximum explicitly published APY filter; nominal-only rows do not match.
  - `mode` 'list' | 'benchmark': list (default) = raw rows; benchmark = ranked per-CU roster.
  - `sort` 'apy_asc' | 'apy_desc' | 'term_asc' | 'updated_desc': List-mode sort (default apy_desc).
  - `limit` integer: List: default 50, max 500. Benchmark: default 10, clamp 1..50.
  - `offset` integer: List-mode pagination offset (default 0).

## Response `200`

Deposit rows (list mode) or ranked deposit benchmark (benchmark mode).

- object: Shape depends on `mode`. Benchmark mode shown below.
  - `state` string, nullable: Two-letter US state code.
  - `product_category` string, nullable: Broad category the product classifies into.
  - `benchmark_balance` number, nullable: Representative balance used for generic savings tier comparisons; 10000 for product_category=savings, otherwise null.
  - `term_months` number, nullable: Loan term in months.
  - `count` integer: Rows returned in the table.
  - `total_credit_unions` integer: Distinct credit unions represented in the table.
  - `as_of` string, nullable: When the underlying rates were published.
  - `best` object, nullable: The highest-yielding row, or null when nothing matched.
    - `lender` string: Name of the credit union offering this rate.
    - `apy` number, nullable: Annual percentage yield on a deposit product.
    - `term_months` number, nullable: Loan term in months.
  - `market` object: APY spread across the matching offers.
    - `min_apy` number, nullable: Lowest APY among the matching offers, or null when none matched.
    - `median_apy` number, nullable: Median APY among the matching offers, or null when none matched.
    - `max_apy` number, nullable: Highest APY among the matching offers, or null when none matched.
    - `count` integer: How many offers the comparison was made against.
  - `table` object[]: The matching deposit offers, highest APY first.
    - `position` integer: Position in the table, 1 being best.
    - `lender` string: Name of the credit union offering this rate.
    - `apy` number, nullable: Annual percentage yield on a deposit product.
    - `term_months` number, nullable: Loan term in months.
    - `savings_subtype` string, nullable: Which kind of savings product this is, or null when the product is not a savings account.
    - `bps_below_leader` integer, nullable: How far this offer sits below the leading APY, in basis points. Zero for the leader, null when it could not be computed.
    - `best` boolean: True for the highest-yielding row.
  - `note` string: Plain-language explanation of what this result means.

## Other responses

- `400`: A request field failed validation. Enum failures include canonical values and a corrected request that can be retried directly.
- `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`.
- `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)
