EUR stablecoin data, as JSON.
Quick start
Subscribe (€49/month), then generate your personal API key from your account — the /api/v1 data endpoints require an active subscription and a key; there is no free API access. Send the key on every request as an Authorization: Bearer <key> or x-api-key header (never in a URL). Every endpoint returns JSON and is CORS-enabled.
curl -H "Authorization: Bearer $ESK_KEY" https://www.eurostablecoins.xyz/api/v1/overview curl -H "x-api-key: $ESK_KEY" https://www.eurostablecoins.xyz/api/v1/supply/eurc curl -H "Authorization: Bearer $ESK_KEY" "https://www.eurostablecoins.xyz/api/v1/history/peg/eurc?period=30d"
Example response
Illustrative example of the /api/v1/supply/{coin_id} response shape. Field names and types match the live endpoint; the amounts and recorded_at are sample values, not a live reading.
{
"coin_id": "eurc",
"ticker": "EURC",
"name": "EURC",
"issuer": "Circle",
"total_supply": 208450000,
"total_onchain_supply": null,
"onchain_supply_by_chain": null,
"circulating_supply": 208450000,
"treasury_held": 0,
"chain_breakdown": {
"ethereum": 121300000,
"base": 62400000,
"solana": 18900000,
"avalanche": 5850000
},
"currency": "EUR",
"recorded_at": "2026-08-06T04:12:00.000Z",
"source": "https://www.eurostablecoins.xyz"
}Concepts
coin_idStable lowercase identifier for a coin. Examples: eurc, eurs, euri, deuro, heuro. Same as the URL slug on coin detail pages. Valid values are listed in the Coin IDs section below and returned by /api/v1.
periodQuery parameter accepted by all /history/* endpoints. Values: 7d · 14d · 30d · 3m · 90d · 6m · 12m · 1y · 2y · all · max. Default: 30d. Alternatively use ?start=YYYY-MM-DD and optionally ?end=YYYY-MM-DD for a custom range.
chainChain key for /supply/{id}/{chain} and /history/supply/{id}/{chain}. Valid values depend on which chains a given coin is deployed on. Common keys: ethereum, polygon, arbitrum, base, optimism, avalanche, gnosis, solana, xrpl, stellar, algorand.
coverage gapMissing rows in a series response are real omissions — they are not zeros. Activity history depth and peg coverage vary by coin. A coin absent from /v1/peg has no tracked public price source.
Coin IDs
All active coin_id values. Use these wherever {id} appears in a path. The machine-readable list is always current at /api/v1 under valid_coin_ids.
aeuraryzeeurbiteurblueurbreurdeurodforceeuxeeureneuretoroxeur0euraeuraueurbeurceurcveurdeureeurieurleurmeuro3eurodeuroeeuropeuroseurpaeurqeurreurseursmeurteurweurxtheuroibeurjeurmykoboeurcparrevolut-eurrseurtempoeurtterraeutveurwseCache & freshness
Authorized responses are Cache-Control: private, no-store — they are never shared or CDN-cached. The underlying data is cached server-side (separate from the collection cadence), so a request may return data that was collected earlier.
| Domain | HTTP cache | Collection cadence |
|---|---|---|
| Supply | private, no-store | Every 4 hours (scheduled 00:05, 04:05, 08:05, 12:05, 16:05, 20:05 UTC; best-effort scheduler — recorded_at is authoritative) |
| Peg | private, no-store | Every 6 hours (00:35, 06:35, 12:35, 18:35 UTC) |
| Activity (mint/burn, transfer) | private, no-store | Daily at 08:30 UTC |
| Holders | private, no-store | Daily at 10:00 UTC |
| CEX markets | private, no-store | Daily at 06:00 UTC |
| DEX markets | private, no-store | Every 6 hours |
| /api/v1 root | private, no-store | — |
Endpoints
API index — base info, endpoint list, valid coin IDs, collection cadence.
| name | string | API name |
| version | string | "v1" |
| base_url | string | https://www.eurostablecoins.xyz/api/v1 |
| docs_page | string | Link to /docs |
| cors | string | "enabled (Access-Control-Allow-Origin: *)" |
| cache | string | Cache policy description |
| endpoints | object | Grouped endpoint list (meta / supply / peg / activity / holders / markets) |
| valid_coin_ids | string[] | All active coin_id values |
| history_period_values | string[] | Accepted ?period values for /history/* endpoints: 7d, 14d, 30d, 3m, 90d, 6m, 12m, 1y, 2y, all, max |
| data_freshness | object | Collection cadence per domain (supply, peg, activity, holders, dex) |
| license | string | Attribution note |
| contact | object | Telegram / Twitter / LinkedIn links |
curl https://www.eurostablecoins.xyz/api/v1
Aggregated market stats — total EUR supply, MiCA breakdown, HHI concentration, dominant coin.
| coin_count | integer | Number of active tracked coins |
| aggregate_coin_count | integer | Coins summed into total_circulating_eur (active minus aggregate-excluded) |
| total_excludes_coins | boolean | true when one or more tracked coins are excluded from the headline aggregate |
| excluded_coins | object[] | Aggregate-excluded coins: [{ id, ticker, reason }] — visible in the universe but not summed into total_circulating_eur |
| total_circulating_eur | number | Sum of circulating supplies in EUR (aggregate-excluded coins are NOT summed) |
| mica_licensed_count | integer | Coins with full MiCA EMT licence |
| mica_breakdown | object | Count per status: { emi_licensed, credit_institution, under_review, not_regulated } |
| dominant | object | { coin_id, ticker, share, note } — coin with highest circulating supply |
| hhi_concentration | number | Herfindahl–Hirschman Index (0–10 000); higher = more concentrated |
| coins | object[] | Per-coin: { coin_id, ticker, issuer, mica_status, total_supply, total_onchain_supply, onchain_supply_by_chain, circulating_supply, chain_count, market_share_pct, aggregate_excluded, aggregate_exclude_reason }. Methodology-unresolved coins have total_supply null and the amount in total_onchain_supply/onchain_supply_by_chain |
| data_as_of | string | ISO 8601 timestamp of the most recent supply snapshot in this response |
| source | string |
curl https://www.eurostablecoins.xyz/api/v1/overview
Data is cached internally for up to 5 minutes via unstable_cache; the HTTP response is private and never shared/CDN-cached (Cache-Control: private, no-store).
Registry index — all active tracked coins with metadata and latest supply state.
| coin_count | integer | Number of active coins returned |
| coins | object[] | Array of coin objects — includes market_status field; see /v1/coins/{id} for full per-coin field schema |
| timestamp | string | ISO 8601 |
| source | string |
curl https://www.eurostablecoins.xyz/api/v1/coins
Registry entry for one coin — metadata, chain list, and latest supply snapshot.
| id | required | Coin identifier (see Coin IDs section) |
| coin_id | string | Stable identifier, e.g. "eurc" |
| ticker | string | Token ticker, e.g. "EURC" |
| name | string | Full token name |
| issuer | string | Short issuer name |
| issuer_full | string | Legal / full issuer name |
| website | string | Issuer website URL |
| mica_status | string | emi_licensed · credit_institution · under_review · not_regulated |
| mica_jurisdiction | string | EU member state of authorisation (when licensed) |
| backing_type | string | "fiat" for all current EUR stablecoins |
| tier | integer | Internal coverage tier (1 = broadest) |
| sunset | boolean | true if asset is deprecated / in wind-down / apparent shutdown |
| market_status | string | market_traded · limited_trading · non_traded_utility · residual_markets_only · legacy_or_wind_down · unknown_or_unverified |
| aggregate_excluded | boolean | true if the coin is excluded from the headline aggregate market supply (still listed here with its own supply) |
| aggregate_exclude_reason | string | Reason the coin is excluded from the aggregate; null unless aggregate_excluded is true |
| operational_status | string | operating · wind_down · apparent_shutdown (apparent_shutdown = issuer appears to have ceased operations without a confirmed legal closure; sunset stays false — e.g. EURS) |
| official_shutdown_confirmation | boolean | false when an apparent shutdown is not legally/formally confirmed; null when not applicable |
| incident | object | null, or { kind, label, url, research_url } for an active incident (e.g. EURS apparent shutdown, EURR security incident) |
| chains | object[] | Per-chain: { chain, chain_type, chain_id, contract, decimals } |
| total_supply | number | Total supply in EUR across all chains. null when the circulating methodology is unresolved — the amount is then in total_onchain_supply |
| total_onchain_supply | number | Combined raw on-chain amount for methodology-unresolved multi-chain coins (e.g. EURW). Not circulating and not summed into any aggregate; null for ordinary coins |
| onchain_supply_by_chain | object | { <chain>: number } — per-chain on-chain amounts for methodology-unresolved coins; null for ordinary coins (which use chain_breakdown) |
| circulating_supply | number | total_supply minus treasury_held; null when the circulating methodology is unresolved or the supply basis is raw/synthetic-nominal |
| nominal_supply | number | Nominal on-chain quantity for collateralized-synthetic assets (e.g. a BitShares smartcoin) — explicitly NOT circulating euros; null otherwise |
| treasury_held | number | EUR held in identified treasury/reserve wallets |
| chain_breakdown | object | { <chain>: number } — flat map of per-chain supply; null for methodology-unresolved coins (see onchain_supply_by_chain) |
| recorded_at | string | ISO 8601 snapshot time |
| source | string | |
| supply_context | object | Optional — present only when supply interpretation requires a caveat |
| provenance | object | Optional — verified on-chain provenance (contract/proxy identity, authority model, source transports) for coins where it has been established (e.g. EURW); null otherwise |
curl https://www.eurostablecoins.xyz/api/v1/coins/eurc
Latest supply snapshot for all active coins.
| coin_count | integer | Number of coins returned |
| aggregate_coin_count | integer | Coins summed into total_circulating_eur (excludes aggregate-excluded coins) |
| total_circulating_eur | number | Sum of circulating supplies in EUR — aggregate-excluded coins are NOT summed |
| total_excludes_coins | boolean | true when one or more coins in coins[] are excluded from the headline total |
| excluded_coins | object[] | Aggregate-excluded coins: [{ coin_id, ticker, reason }] — present in coins[] but not summed |
| currency | string | "EUR" |
| timestamp | string | ISO 8601 |
| source | string | |
| coins | object[] | Per-coin: { coin_id, ticker, name, issuer, total_supply, total_onchain_supply, onchain_supply_by_chain, circulating_supply, treasury_held, chain_breakdown, aggregate_excluded, aggregate_exclude_reason, recorded_at }. For methodology-unresolved coins total_supply/chain_breakdown are null and the amount is in total_onchain_supply/onchain_supply_by_chain |
curl https://www.eurostablecoins.xyz/api/v1/supply
Latest supply snapshot for one coin, summed across all chains.
| id | required | Coin identifier |
| coin_id | string | |
| ticker | string | |
| name | string | |
| issuer | string | |
| total_supply | number | EUR, all chains summed. null when the circulating methodology is unresolved (see total_onchain_supply) |
| total_onchain_supply | number | Combined raw on-chain amount for methodology-unresolved multi-chain coins (e.g. EURW); not circulating, not aggregated; null for ordinary coins |
| onchain_supply_by_chain | object | { <chain>: number } — per-chain on-chain amounts for methodology-unresolved coins; null for ordinary coins |
| circulating_supply | number | total_supply minus treasury_held; null when the circulating methodology is unresolved or the supply basis is raw/synthetic-nominal |
| treasury_held | number | EUR held in identified treasury/reserve wallets |
| chain_breakdown | object | { <chain>: number } — flat map of per-chain supply; null for methodology-unresolved coins (see onchain_supply_by_chain) |
| currency | string | "EUR" |
| recorded_at | string | ISO 8601 snapshot time |
| source | string | |
| supply_context | object | Optional — present when supply interpretation requires a caveat |
curl https://www.eurostablecoins.xyz/api/v1/supply/eurc
Latest supply for one coin on one specific chain.
| id | required | Coin identifier |
| chain | required | Chain key — must be a chain on which this coin is deployed (e.g. ethereum, polygon, solana) |
| coin_id | string | |
| ticker | string | |
| chain | string | Chain key as passed in path |
| chain_name | string | Human-readable chain name |
| chain_type | string | evm · solana · xrpl · stellar · algorand · cosmos |
| chain_id | integer | EVM chain ID; null for non-EVM chains |
| contract | string | Token contract / mint / issuer address |
| decimals | integer | Token decimals |
| supply | number | Supply on this chain in EUR |
| currency | string | "EUR" |
| recorded_at | string | ISO 8601 snapshot time |
| source | string | |
| note | string | Optional — present when supply is zero; explains why |
curl https://www.eurostablecoins.xyz/api/v1/supply/eurs/ethereum
Daily supply history for one coin — total, circulating, treasury, per-chain breakdown.
| id | required | Coin identifier |
| period | optional | 7d · 30d · 90d · 1y · 2y · max (default: 30d) |
| start | optional | YYYY-MM-DD start date (alternative to period) |
| end | optional | YYYY-MM-DD end date (default: today; used with start) |
| coin_id | string | |
| ticker | string | |
| period | string | Effective period value, or "custom" |
| points | integer | Number of data points in series |
| earliest | string | YYYY-MM-DD |
| latest | string | YYYY-MM-DD |
| series | object[] | Daily rows — see series fields below |
| source | string |
| date | string | YYYY-MM-DD |
| total_supply | number | null for methodology-unresolved coins (see total_onchain_supply) |
| total_onchain_supply | number | Combined on-chain amount for methodology-unresolved coins; null for ordinary coins |
| onchain_supply_by_chain | object | { <chain>: supply } for methodology-unresolved coins; null for ordinary coins |
| circulating_supply | number | null when the circulating methodology is unresolved or the supply basis is raw/synthetic-nominal |
| treasury_held | number | |
| chain_breakdown | object | { <chain>: supply }; null for methodology-unresolved coins |
curl "https://www.eurostablecoins.xyz/api/v1/history/supply/eurc?period=30d"
History depth varies by coin. Coverage gaps are real omissions, not zeros.
Daily supply history for one coin on one specific chain.
| id | required | Coin identifier |
| chain | required | Chain key |
| period | optional | 7d · 30d · 90d · 1y · 2y · max |
| coin_id | string | |
| ticker | string | |
| chain | string | |
| chain_name | string | |
| chain_type | string | |
| contract | string | |
| period | string | |
| points | integer | |
| earliest | string | YYYY-MM-DD |
| latest | string | YYYY-MM-DD |
| series | object[] | { date: string, supply: number } |
| source | string |
curl "https://www.eurostablecoins.xyz/api/v1/history/supply/eurc/ethereum?period=30d"
Latest peg metrics for all coins with a tracked price source.
| coin_count | integer | Coins with a price source (not all tracked coins) |
| coins | object[] | Per-coin peg object — see /v1/peg/{id} for field schema |
| data_as_of | string | YYYY-MM-DD date of the most recent observation across returned coins |
| source | string |
curl https://www.eurostablecoins.xyz/api/v1/peg
Coins without an independent price source are omitted.
Latest peg metrics for one coin — EUR price, deviation, rolling averages, depeg events, score.
| id | required | Coin identifier |
| coin_id | string | |
| ticker | string | |
| current_price_eur | number | Latest observed EUR price |
| deviation_bps | number | Deviation from 1.00 EUR in basis points (100 bps = 1%) |
| avg_deviation_bps_7d | number | 7-day rolling average absolute deviation (bps) |
| avg_deviation_bps_30d | number | 30-day rolling average absolute deviation (bps) |
| max_deviation_bps_7d | number | Max absolute deviation in past 7 days (bps) |
| max_deviation_bps_30d | number | Max absolute deviation in past 30 days (bps) |
| time_in_band_10bps_30d | integer | Percentage of past 30 days with deviation ≤10 bps (0–100; 100 = always in band) |
| time_in_band_50bps_30d | integer | Percentage of past 30 days with deviation ≤50 bps (0–100; 100 = always in band) |
| depeg_events_30d | integer | Days in past 30 where deviation exceeded 100 bps |
| peg_score_100 | number | Composite peg quality score (0–100; 100 = perfectly pegged) |
| price_source | string | Price source identifier |
| date | string | YYYY-MM-DD date of latest observation |
| source | string |
curl https://www.eurostablecoins.xyz/api/v1/peg/eurc
Returns 404 if the coin has no tracked price source.
Daily peg history — EUR price and rolling deviation metrics per day.
| id | required | Coin identifier |
| period | optional | 7d · 30d · 90d · 1y · 2y · max |
| coin_id | string | |
| ticker | string | |
| period | string | |
| points | integer | |
| earliest | string | YYYY-MM-DD |
| latest | string | YYYY-MM-DD |
| series | object[] | Daily rows — see series fields below |
| source | string |
| date | string | YYYY-MM-DD |
| price_eur | number | |
| deviation_bps | number | |
| avg_deviation_bps_7d | number | |
| avg_deviation_bps_30d | number | |
| max_deviation_bps_7d | number | |
| max_deviation_bps_30d | number | |
| time_in_band_10bps_30d | integer | |
| time_in_band_50bps_30d | integer | |
| depeg_events_30d | integer | |
| peg_score_100 | number |
curl "https://www.eurostablecoins.xyz/api/v1/history/peg/eurc?period=90d"
Daily mint and burn history — volumes and transaction counts.
| id | required | Coin identifier |
| period | optional | 7d · 30d · 90d · 1y · 2y · max |
| coin_id | string | |
| ticker | string | |
| period | string | |
| points | integer | |
| earliest | string | YYYY-MM-DD |
| latest | string | YYYY-MM-DD |
| series | object[] | Daily rows — see series fields below |
| source | string |
| date | string | YYYY-MM-DD |
| minted | number | EUR minted that day |
| burned | number | EUR burned that day |
| net_issuance | number | minted − burned |
| mint_tx_count | integer | |
| burn_tx_count | integer | |
| method | string | Collection method identifier |
| confidence | string | Data confidence level |
curl "https://www.eurostablecoins.xyz/api/v1/history/mint-burn/eurc?period=30d"
Coverage varies by coin. Some assets have partial history; others have no mint/burn data.
Validated peer-transfer volume for every tracked coin, with market totals, coverage and quality metadata.
| period | optional | 7d · 14d · 30d · 3m · 6m · 12m · all |
| market_volume | number | Gross peer-transfer volume in EUR |
| daily_average | number | Average over calendar days in the selected window |
| coverage | object | Covered and expected canonical deployments |
| coins | object[] | All tracked coins, including unavailable rows |
| series | object[] | Daily aggregate market series |
curl "https://www.eurostablecoins.xyz/api/v1/transfer-volume?period=30d"
Mint, burn and self-transfers are excluded. Mathematically inconsistent and non-canonical rolling-window rows are rejected.
Peer-transfer volume summary and daily series for one coin.
| id | required | Coin identifier |
| period | optional | 7d · 14d · 30d · 3m · 6m · 12m · all |
| volume | number | Validated period peer-transfer volume |
| daily_average | number | Calendar-day average |
| transfer_count | integer | Peer transfers in covered data |
| coverage | object | Covered and missing canonical chains |
| quality | object | Excluded row counts and reasons |
| series | object[] | Validated daily rows |
curl "https://www.eurostablecoins.xyz/api/v1/transfer-volume/eurc?period=30d"
Unavailable or partial coverage is returned explicitly, never converted to zero coverage.
Daily peer-to-peer transfer volume and active address counts (mint/burn excluded).
| id | required | Coin identifier |
| period | optional | 7d · 14d · 30d · 3m · 6m · 12m · all |
| coin_id | string | |
| ticker | string | |
| period | string | |
| points | integer | |
| earliest | string | YYYY-MM-DD |
| latest | string | YYYY-MM-DD |
| series | object[] | Daily rows — see series fields below |
| source | string |
| date | string | YYYY-MM-DD |
| transfer_volume | number | EUR volume of peer-to-peer transfers |
| transfer_count | integer | |
| active_addresses | integer | Unique sender or receiver addresses |
| largest_transfer | number | Largest single transfer in EUR |
| method | string | Collection method identifier |
| confidence | string |
curl "https://www.eurostablecoins.xyz/api/v1/history/transfer-volume/eurc?period=30d"
Transfers are reconstructed from on-chain Transfer events. Mint/burn transfers are excluded. Coverage varies by coin and chain.
Latest holder count snapshot for one coin — unique addresses with a positive balance, summed across all chains.
| id | required | Coin identifier |
| coin_id | string | |
| ticker | string | |
| total_holders | integer | Unique addresses with a positive balance, summed across all chains |
| active_holders_30d | null | Always null — deprecated; removed due to unreliable cross-chain measurement |
| chain_breakdown | object | { <chain>: { total: N } } — stale: true if previous count was preserved; partial: true if enumeration was capped |
| source | string | '+'-delimited source tags (e.g. evm_ethereum+evm_base). Suffix _stale = preserved value; _partial = XRPL page cap reached (floor count) |
| recorded_at | string | ISO 8601 snapshot time |
| note | string | Static note about absence of historical backfill |
curl https://www.eurostablecoins.xyz/api/v1/holders/eurc
No historical holder series is published. Snapshot cadence is daily. The source field encodes data quality per chain.
Top-level markets overview — CEX and DEX summary counts, data timestamps, and endpoint directory.
| generated_at | string | ISO 8601 timestamp of the most recently collected data |
| endpoints | object | Endpoint paths for cex, cex_by_coin, dex, dex_by_coin, combined |
| cex | object | CEX summary: coins_covered, pairs_count, generated_at, source, cadence, note |
| dex | object | DEX summary: pairs_count, coins_covered, chains_covered, generated_at, sources, cadence |
curl https://www.eurostablecoins.xyz/api/v1/markets
All direct CEX market data across all tracked coins — exchange, symbol, price, bid/ask, spread, 24h volume.
| generated_at | string | ISO 8601 time the snapshot was collected |
| fallback_used | boolean | true if response came from the committed static fallback rather than the live DB snapshot |
| source | string | "direct_exchange_api" |
| note | string | Reminder that prices are in each pair's native quote currency |
| pairs_count | integer | Total CEX trading pairs returned |
| coins_covered | integer | Distinct coins with at least one CEX pair |
| markets | object[] | Array of CEX market objects — see markets[] fields below |
| coin_id | string | |
| exchange_id | string | CCXT exchange identifier, e.g. "kraken" |
| exchange_name | string | Display name, e.g. "Kraken" |
| symbol | string | Trading pair symbol, e.g. "EURC/USD" |
| base | string | Base currency, e.g. "EURC" |
| quote | string | Quote currency, e.g. "USD" |
| last | number | Raw last traded price in the pair's native quote currency (transparency only — use eur_price as the coin price) |
| bid | number | Best bid in quote currency |
| ask | number | Best ask in quote currency |
| spread_bps | number | Bid/ask spread in basis points — (ask−bid)/mid × 10 000 |
| base_volume_24h | number | 24h volume in base currency |
| quote_volume_24h | number | 24h volume in quote currency |
| eur_price | number | Orientation-normalised EUR price for the coin; null when not derivable from the pair (coin is the quote side, e.g. BTC/EURC, or a non-EUR quote). Use this — not last — as the coin price. |
| price_orientation | string | eur_quoted · usd_quoted · inverse_eur · quote_side — which side the coin is on and how eur_price was derived |
| price_reliable | boolean | Whether eur_price is safe to present as the coin price (passes the plausibility band) |
| source_type | string | "direct_exchange_api" |
| stale | boolean | true if this venue was not refreshed in the last collection run |
| fetched_at | string | ISO 8601 timestamp of when this row was last fetched |
curl https://www.eurostablecoins.xyz/api/v1/markets/cex
CEX data is collected daily at 06:00 UTC via CCXT direct exchange APIs. Cached server-side for 1 hour. Prices and volumes are in each pair's native quote currency — not USD-normalised.
Direct CEX market data for one coin. Returns 404 for unknown coins. Returns an empty markets array with a note if the coin is tracked but has no CEX coverage.
| id | required | Coin identifier (see Coin IDs section) |
| coin_id | string | |
| ticker | string | |
| generated_at | string | ISO 8601 time the snapshot was collected |
| fallback_used | boolean | |
| source | string | "direct_exchange_api" |
| markets_count | integer | Number of CEX markets for this coin |
| markets | object[] | CEX market rows — same fields as /v1/markets/cex markets[] items |
| note | string | Optional — present when markets_count is 0 |
curl https://www.eurostablecoins.xyz/api/v1/markets/cex/eurc
Latest DEX pool snapshots — price, liquidity, 24h volume, and tx counts across all tracked EUR stablecoin pairs.
| generated_at | string | ISO 8601 time this response was generated |
| sources | string[] | Data source names (e.g. DexScreener, GeckoTerminal) |
| fallback_live_fetch | boolean | true if response was produced by a live fetch rather than a stored snapshot |
| pairs_count | integer | Total DEX pairs returned |
| coins_covered | integer | Distinct coins with at least one DEX pair |
| chains_covered | integer | Distinct chains covered |
| pairs | object[] | Array of DEX pool objects — see pairs[] fields below |
| coin_id | string | |
| ticker | string | |
| chain | string | Chain key |
| dex_id | string | DEX identifier (e.g. "uniswap_v3") |
| dex_label | string | Human-readable DEX name |
| pair_label | string | Trading pair (e.g. "EURC/USDC") |
| pool_address | string | On-chain pool contract address |
| price_usd | number | Current price in USD |
| liquidity_usd | number | Total pool liquidity in USD |
| volume_24h_usd | number | 24-hour trading volume in USD |
| txns_24h | integer | 24-hour transaction count |
| pool_class | string | core_pool · indexed_pool · low_liquidity_pool · stale_pool |
| source | string | Source name for this pool |
| source_url | string | Direct link to pool on source explorer |
| warning_flags | string[] | Data quality warnings, if any |
curl https://www.eurostablecoins.xyz/api/v1/markets/dex
DEX data is collected every 6 hours. Cached server-side for 1 hour. If the stored snapshot is stale the API falls back to a live fetch (fallback_live_fetch: true), which increases response time.
DEX pool data for one coin. Returns 404 for unknown coins. Returns an empty pairs array with a note if the coin has no DEX coverage.
| id | required | Coin identifier (see Coin IDs section) |
| coin_id | string | |
| ticker | string | |
| generated_at | string | ISO 8601 time the snapshot was collected |
| sources | string[] | Data source names |
| fallback_live_fetch | boolean | |
| pairs_count | integer | Number of DEX pairs for this coin |
| pairs | object[] | DEX pair rows — same fields as /v1/markets/dex pairs[] items |
| note | string | Optional — present when pairs_count is 0 |
curl https://www.eurostablecoins.xyz/api/v1/markets/dex/eurc
Combined CEX and DEX market data for one coin in a single response.
| id | required | Coin identifier (see Coin IDs section) |
| coin_id | string | |
| ticker | string | |
| cex | object | { markets_count, generated_at, fallback_used, source, cadence, markets[] } |
| dex | object | { pairs_count, generated_at, sources, fallback_live_fetch, cadence, pairs[] } |
curl https://www.eurostablecoins.xyz/api/v1/markets/eurc
Combines /v1/markets/cex/{id} and /v1/markets/dex/{id} in one call. CEX and DEX keys are always present; inner arrays are empty when no coverage exists for that type.
Attribution
All data is published under CC BY 4.0. An attribution header is requested — not enforced — so we can build a citation map.
Header format: X-Attribution: <app-name>/<version> (<contact>)
If you publish a derived dataset, cite as: “Source: Euro Stablecoins, accessed YYYY-MM-DD.”
Errors
Data-route errors return JSON with an error string; the paid gate returns { error: { code, message } } — 401 (API_KEY_REQUIRED / INVALID / REVOKED / EXPIRED), 403 SUBSCRIPTION_REQUIRED, 429 RATE_LIMITED (with Retry-After), or 503 when authorization can't complete; a key in the URL or conflicting credentials return 400. The per-key rate limit is 120 requests/minute (fair use); authorized responses and the 429 carry X-RateLimit-Limit and X-RateLimit-Remaining, plus X-RateLimit-Reset (delta-seconds until the window resets; 0 when a reset is imminent). Reset is omitted when the limiter cannot read a truthful expiry, and all three may be absent if limiter state is briefly unavailable (fail-open) — in which case Retry-After on a 429 is a conservative fallback, not a measured reset. These are the widely-used de-facto headers, not an RFC. Authorized responses are Cache-Control: private, no-store — cache the underlying data in your client, never the authorized response, and never share a key. The /api/v1 data endpoints require an active €49/month subscription and API key on every request; requests without a valid key return 401. Use is subject to the API Terms of Use.
| Status | Meaning |
|---|---|
| 200 | Success — snapshot or series returned. |
| 400 | Bad request — invalid query parameter (e.g. unrecognised period value or malformed date). |
| 404 | Unknown coin — the coin_id does not resolve to an active tracked coin. Also returned by /peg/{id} when the coin has no price source. |
| 500 | Server error — unexpected failure. Retrying usually succeeds. |
Versioning & deprecation
The current contract is /api/v1, versioned in the URL path. It is stable: no /api/v1 endpoint is deprecated or scheduled for retirement today.
- Additive changes — new endpoints, new response fields, or new optional query parameters — ship in place within
v1. Treat unknown fields leniently and match coins bycoin_id, not array position, so an additive change never breaks your client. - Breaking changes — removing or renaming a field, changing a type, or altering documented semantics — would ship under a new version path (e.g.
/api/v2), so/api/v1keeps working alongside it. There is no in-place breaking change tov1. - How a retirement would be signalled — if a future version ever supersedes
v1, affected responses would carry the standardDeprecation(RFC 9745) andSunset(RFC 8594) headers — which state the deprecation and retirement dates — and the successor and migration steps would be published on this page (aLinkheader would carry the successor URL). These headers are absent today because nothing is deprecated.
Any specific notice period or migration window would be published here before a change takes effect; this policy does not itself promise a fixed notice period. The machine-readable spec is versioned alongside the API at /api/v1/openapi.json.
Known limitations
No holder history — /v1/holders/{id} returns only the latest daily snapshot. There is no backfilled time series.
Peg coverage is a subset — coins not tracked by a public price feed are absent from /v1/peg and /v1/history/peg. A 404 response does not indicate a problem with the coin.
Activity coverage varies — not all coins have mint/burn or transfer history. Early periods may be sparse. A missing row is a real gap, not a zero.
XRPL holder counts may be floor estimates — if EURS pagination on XRPL reaches the page cap, the source field includes _partial and the count is a lower bound.
Snapshots are not real-time — data is collected on cron cadence and cached server-side. The freshness cadence table above shows the worst-case staleness per domain.
Treasury subtraction — circulating_supply subtracts only publicly identifiable treasury wallets. For ordinary coins where no wallets are identified, circulating_supply equals total_supply.
Unresolved circulating methodology — for a few coins the circulating basis is undefined (an unreconciled multi-chain on-chain total, or a collateralized-synthetic nominal). These return circulating_supply: null. For multi-chain totals (e.g. EURW) the combined amount is exposed under total_onchain_supply / onchain_supply_by_chain with total_supply null, and is never summed into the headline aggregate.