Stablecoin Earn Benchmark

The Bitcompare Earn Index — Stablecoin (bei-stable) is the citable market reference for what stablecoin yield pays: the median USDC/USDT lending APY across every servable provider, with CeFi and DeFi splits, a TVL-weighted DeFi variant, day/week/month deltas, and a daily print history that is never rewritten. It is a market number, not a single provider's quote.

Access and plan gating

Plan/benchmarks/stablecoin/benchmarks/stablecoin/history depthinclude=constituents
Anonymous (no key)FullMost recent 90 days (clamped: true if you asked for more)Silently omitted
FreeFull90 days, clampedSilently omitted
StarterFull90 days, clampedSilently omitted
GrowthFull90 days, clampedSilently omitted
ProFullFull depth, back to the first printReturned
EnterpriseFullFull depth, back to the first printReturned

Nothing on this page returns 403. The tier shows up as the clamped flag and the presence or absence of constituents. Pass your key as a Bearer token (see Authentication) to lift the clamp; issue one from your dashboard or compare plans at pro.bitcompare.net/pricing.


Methodology in brief

Methodology v1.0. The full specification lives on the methodology page; the points you need to read the numbers are:

  • Constituent grain — one (provider, symbol) pair is one vote. A provider offering both USDC and USDT contributes two constituents.
  • Median is the headline. It is robust to a single outlier promo rate. Mean, min, max, p25 and p75 are published alongside on every history print.
  • Segmentsoverall (every constituent, including hybrid platforms), cefi, and defi. Hybrid platforms count in overall only.
  • Minimum constituents — 5 for overall, 3 for each split. Below that, no print is published for that segment that day: a gap is the honest signal, never a thin number.
  • TVL-weighted rate — the defi segment only, and only when at least 60% of the segment's constituents (and at least 3) carry on-chain TVL. CeFi has no TVL, and an "overall" TVL weight would be a DeFi-only number wearing the overall label, so tvlWeightedRate is null for cefi and overall.
  • Backfill is labelled. Prints before live daily computation began are reconstructed from historical rate data and carry methodologyVersion: "v1.0-backfill" and backfilled: true. The Coverage endpoint reports how many print days are live versus backfilled.
  • Provider attestation is activating. As providers attest to their terms through Bitcompare, their attested rates enter the constituent set with provider_confirmed provenance; coverage.providers.attesting tracks the count.

GET/api/v1/benchmarks/stablecoin

Headline

The latest print per segment, with deltas and a 30-point sparkline. Anonymous, no parameters, Cache-Control: public, max-age=300, s-maxage=900, stale-while-revalidate=3600.

Response properties

  • Name
    benchmarkKey
    Type
    string
    Description

    Always "bei-stable".

  • Name
    name
    Type
    string
    Description

    Human-readable index name.

  • Name
    methodologyVersion
    Type
    string
    Description

    Methodology the latest live print was computed under, e.g. "v1.0".

  • Name
    methodologyUrl
    Type
    string
    Description

    Public methodology page to cite alongside the number.

  • Name
    segments
    Type
    array
    Description

    One entry each for overall, cefi, defi (a segment is absent on a day it did not print).

  • Name
    updatedAt
    Type
    string
    Description

    ISO 8601 instant this response was assembled.

Segment properties

  • Name
    segment
    Type
    string
    Description

    overall, cefi, or defi.

  • Name
    day
    Type
    string
    Description

    YYYY-MM-DD of the latest print.

  • Name
    medianRate
    Type
    number
    Description

    The headline: median APY in percent.

  • Name
    tvlWeightedRate
    Type
    number | null
    Description

    TVL-weighted APY; defi only, null otherwise or when coverage is too thin.

  • Name
    constituentCount
    Type
    integer
    Description

    Number of (provider, symbol) votes in the print.

  • Name
    providerCount
    Type
    integer
    Description

    Distinct providers among the constituents.

  • Name
    dayChange
    Type
    number | null
    Description

    medianRate minus the print one day earlier, in percentage points. null when no comparable print exists.

  • Name
    weekChange
    Type
    number | null
    Description

    Same, versus seven days earlier.

  • Name
    monthChange
    Type
    number | null
    Description

    Same, versus thirty days earlier.

  • Name
    sparkline
    Type
    array
    Description

    The last 30 daily prints as { day, medianRate, backfilled }, oldest first.

Request

GET
/api/v1/benchmarks/stablecoin
curl https://api.bitcompare.net/api/v1/benchmarks/stablecoin

Response (captured 2026-09-16, sparklines trimmed)

{
  "data": {
    "benchmarkKey": "bei-stable",
    "name": "Bitcompare Earn Index — Stablecoin (BEI-Stable)",
    "methodologyVersion": "v1.0",
    "methodologyUrl": "https://bitcompare.net/stablecoin-earn-benchmark",
    "segments": [
      {
        "segment": "overall",
        "day": "2026-09-15",
        "medianRate": 5.00427767,
        "tvlWeightedRate": null,
        "constituentCount": 33,
        "providerCount": 19,
        "dayChange": 0.04820470999999937,
        "weekChange": 0.22427766999999932,
        "monthChange": null,
        "sparkline": [
          { "day": "2026-08-17", "medianRate": 4.25, "backfilled": false },
          { "day": "2026-08-18", "medianRate": 4.5753355, "backfilled": false },
          { "day": "2026-08-19", "medianRate": 4.80378808, "backfilled": false },
          "… 30 daily points, oldest first …",
          { "day": "2026-09-15", "medianRate": 5.00427767, "backfilled": false }
        ]
      },
      {
        "segment": "cefi",
        "day": "2026-09-15",
        "medianRate": 11.5,
        "tvlWeightedRate": null,
        "constituentCount": 13,
        "providerCount": 8,
        "dayChange": 0,
        "weekChange": 0,
        "monthChange": null,
        "sparkline": [
          { "day": "2026-08-17", "medianRate": 10.22, "backfilled": false },
          { "day": "2026-08-18", "medianRate": 10.5, "backfilled": false },
          { "day": "2026-08-19", "medianRate": 10.95, "backfilled": false },
          "… 30 daily points, oldest first …",
          { "day": "2026-09-15", "medianRate": 11.5, "backfilled": false }
        ]
      },
      {
        "segment": "defi",
        "day": "2026-09-15",
        "medianRate": 4.50033326,
        "tvlWeightedRate": 17.977598863526225,
        "constituentCount": 20,
        "providerCount": 11,
        "dayChange": 0.31202529499999976,
        "weekChange": 0.9057847599999995,
        "monthChange": null,
        "sparkline": [
          { "day": "2026-08-17", "medianRate": 3.3763116, "backfilled": false },
          { "day": "2026-08-18", "medianRate": 3.362756465, "backfilled": false },
          { "day": "2026-08-19", "medianRate": 3.95733107, "backfilled": false },
          "… 30 daily points, oldest first …",
          { "day": "2026-09-15", "medianRate": 4.50033326, "backfilled": false }
        ]
      }
    ],
    "updatedAt": "2026-09-16T02:37:51.135Z"
  }
}

GET/api/v1/benchmarks/stablecoin/history

History

The daily print series for one segment, oldest first. Without a key, or on Free/Starter/Growth, the window is clamped to the most recent 90 days counted from today — not from to — so the archive cannot be paged in 90-day steps. Pro and Enterprise keys get the full series back to the first print.

Optional attributes

  • Name
    segment
    Type
    string
    Description

    overall (default), cefi, or defi.

  • Name
    from
    Type
    string
    Description

    YYYY-MM-DD start day, inclusive. Defaults to 90 days before to. Clamped on non-Intelligence plans.

  • Name
    to
    Type
    string
    Description

    YYYY-MM-DD end day, inclusive. Defaults to today.

  • Name
    include
    Type
    string
    Description

    constituents to attach each print's frozen constituent list. Intelligence tier only; silently ignored otherwise.

Response properties

  • Name
    benchmarkKey
    Type
    string
    Description

    Always "bei-stable".

  • Name
    segment
    Type
    string
    Description

    The segment you asked for.

  • Name
    prints
    Type
    array
    Description

    One print per day, ascending. Each carries day, methodologyVersion, medianRate, tvlWeightedRate, meanRate, minRate, maxRate, p25Rate, p75Rate, constituentCount, providerCount, tvlCoveredCount, backfilled, and — on the Intelligence tier with include=constituentsconstituents.

  • Name
    count
    Type
    integer
    Description

    Number of prints returned.

  • Name
    clamped
    Type
    boolean
    Description

    true when your from was moved forward to the 90-day floor. If you see this on a paid key, the key's plan does not include Earn Intelligence.

Responses carry Vary: Authorization, and Cache-Control is public, max-age=900 for clamped tiers and private, max-age=300 for the Intelligence tier.

Request

GET
/api/v1/benchmarks/stablecoin/history
curl -G https://api.bitcompare.net/api/v1/benchmarks/stablecoin/history \
  -d segment=overall \
  -d from=2026-01-01

Response (anonymous, captured 2026-09-16, prints trimmed)

{
  "data": {
    "benchmarkKey": "bei-stable",
    "segment": "overall",
    "prints": [
      {
        "day": "2026-06-18",
        "benchmarkKey": "bei-stable",
        "segment": "overall",
        "methodologyVersion": "v1.0-backfill",
        "medianRate": 4.7406498599999995,
        "tvlWeightedRate": null,
        "meanRate": 5.5568166346153856,
        "minRate": 0.01,
        "maxRate": 12,
        "p25Rate": 3.121655,
        "p75Rate": 8.4778,
        "constituentCount": 26,
        "providerCount": 16,
        "tvlCoveredCount": 0,
        "backfilled": true
      },
      "… 89 prints, oldest first …",
      {
        "day": "2026-09-15",
        "benchmarkKey": "bei-stable",
        "segment": "overall",
        "methodologyVersion": "v1.0",
        "medianRate": 5.00427767,
        "tvlWeightedRate": null,
        "meanRate": 10.140602731212121,
        "minRate": 0.01,
        "maxRate": 73.99068834,
        "p25Rate": 3.89749917,
        "p75Rate": 12,
        "constituentCount": 33,
        "providerCount": 19,
        "tvlCoveredCount": 13,
        "backfilled": false
      }
    ],
    "count": 89,
    "clamped": true
  }
}

Constituents

Every print freezes the exact list of (provider, symbol) rates that went into it, so any published number can be reproduced. On the Intelligence tier, include=constituents attaches that list to each print in the history response. The list is served as frozen — later corrections to a provider's rate do not alter a past print.

Constituent properties

  • Name
    provider
    Type
    string
    Description

    Provider slug.

  • Name
    symbol
    Type
    string
    Description

    USDC or USDT.

  • Name
    rate
    Type
    number
    Description

    The lending APY that constituent contributed, in percent.

  • Name
    platformType
    Type
    string
    Description

    cefi, defi, or hybrid.

  • Name
    tvlUsd
    Type
    number | null
    Description

    On-chain TVL in USD at print time; null for CeFi.

  • Name
    source
    Type
    string
    Description

    Where the rate came from — a collection method such as pull_api, onchain, or provider_confirmed.

A print with constituents (shape)

{
  "day": "2026-09-15",
  "benchmarkKey": "bei-stable",
  "segment": "defi",
  "methodologyVersion": "v1.0",
  "medianRate": 4.50033326,
  "tvlWeightedRate": 17.977598863526225,
  "meanRate": 9.87,
  "minRate": 0.01,
  "maxRate": 73.99068834,
  "p25Rate": 2.41,
  "p75Rate": 8.9,
  "constituentCount": 20,
  "providerCount": 11,
  "tvlCoveredCount": 13,
  "backfilled": false,
  "constituents": [
    {
      "provider": "aave-v3",
      "symbol": "USDC",
      "rate": 4.81,
      "platformType": "defi",
      "tvlUsd": 812340000,
      "source": "onchain"
    },
    {
      "provider": "morpho",
      "symbol": "USDT",
      "rate": 5.62,
      "platformType": "defi",
      "tvlUsd": 143900000,
      "source": "onchain"
    }
  ]
}

Errors

  • Name
    422 VALIDATION_ERROR
    Description

    from/to not YYYY-MM-DD, an impossible calendar date, an unknown segment, or an include value other than constituents.

  • Name
    429 RATE_LIMIT_EXCEEDED
    Description

    Anonymous calls share the per-IP Free budget (30 req/min). Pass a key to use your plan's budget. See Rate Limiting.

There is no 403 on these endpoints — a non-Intelligence caller gets the clamped series instead. The full error envelope is described on the Errors page.

422 VALIDATION_ERROR

{
  "error": {
    "message": "from/to must be real calendar dates (YYYY-MM-DD)",
    "code": "VALIDATION_ERROR"
  }
}

See also

Was this page helpful?