Bitculator

Changelog

API changelog

Every change to the Data API and its contract, newest first. Version numbers follow the versioning and deprecation policy.

  1. v1.3.3 Changed

    Creating and testing webhooks limited to 5 requests a minute

    POST /webhooks and POST /webhooks/{id}/test now share a limit of 5 requests a minute per account, on top of the plan's burst limit. Requests over it get 429 rate_limited with Retry-After. A test event is now sent once, without retries; other deliveries are still attempted up to 3 times, with backoff between attempts. This is an abuse limit and leaves every plan's monthly quota and burst limit unchanged. The versioning and deprecation policy changed the same day so that such limits can apply at once; until then, lowering any rate limit a plan had followed the six-month deprecation timeline. On these two endpoints the X-RateLimit-* headers report whichever of the two limits has fewer requests left.

  2. v1.3.3 Changed

    Webhook hostnames resolved at delivery, not on creation

    POST /webhooks no longer looks up the hostname in the URL. It still returns 422 when the URL is not https, carries credentials or has a non-public IP address as its host. A hostname that does not resolve, or resolves to a non-public address, used to get 422; it is now accepted with 201 and counts toward the limit of 5 endpoints per account. Every delivery to such an endpoint then fails without a retry, error on GET /webhooks/{id}/deliveries gives the reason, and 10 failed deliveries in a row disable the endpoint. After creating an endpoint, send it a test event with POST /webhooks/{id}/test and check its delivery log to confirm it is reachable.

  3. v1.3.3 Changed

    Usage breakdown lists route templates, not paths

    endpoints[].endpoint on GET /usage now names the route template instead of the requested path - api/v1/coins/{slug} rather than api/v1/coins/bitcoin - so each endpoint has one row instead of one per slug or id. Requests recorded earlier in the current billing period keep their path, so both forms can appear until the period ends.

  4. v1.3.2 Fixed

    Exchange profile and trust score fixed

    GET /exchanges/{slug} and GET /exchanges/{slug}/trust-score had failed with 500 for every exchange since the Data API launched. Both now answer; parameters and response fields are unchanged, and an exchange without a rank returns score and breakdown as null.

  5. v1.3.2 Changed

    Contract types corrected

    The published OpenAPI contract now marks every field that can be null as nullable and types fractional values as numbers (for example invested on GET /calculators/dca and indicator values); the shared logo, last_updated and pagination from/to fields are nullable on every endpoint, and the coin name and price on every coin list and price endpoint. It also types the DCA series as an array, documents the responses of GET /coins/{slug}/markets, GET /coins/losers, GET /global/history/{metric} and GET /sentiment/altseason, documents days on GET /sentiment/altseason as 1–365 (0 was always rejected; omit it for the current reading), and lists the endpoint_unavailable (503) and http_error codes in the error schema. No request or response changed - only how it is described.

  6. v1.3.1 Changed

    Failed authentication throttled per key

    Failed authentication used to be capped at 30 attempts a minute per IP, after which every key behind that IP got 429. Now one key may fail 30 times a minute from one IP and one IP 300 times, keys that authenticated in roughly the last 15 minutes are not blocked by the IP cap, and a request without a key returns 401 without counting. Blocked requests get 429 rate_limited with Retry-After.

  7. v1.3.1 Changed

    Non-canonical URLs redirect

    GET and HEAD requests whose path has a trailing slash, a doubled slash or a leading /index.php now get a 301 to the clean URL instead of being served - for example /api/v1/coins/ to /api/v1/coins. Other methods are unaffected.

  8. v1.3.1 Fixed

    Partial compounding periods counted exactly

    GET /calculators/compound-interest rounded the duration to whole compounding periods, so a duration that ended mid-period was simulated too long or too short: 6 months compounded annually ran a full year (12 deposits and a full year of interest), and 5 months ran no period at all (no deposits, no interest). Whole periods now run as before, the final partial period earns interest pro rata (simple interest for the fraction), and every deposit within the duration is counted. Results are unchanged whenever the duration is a whole number of compounding periods; parameters and response fields are unchanged.

  9. v1.3.0 Changed

    Compound-interest rate is annual, not per period

    The API and its documentation treated rate as the rate per compounding period, while the website calculator and its how-to used an annual rate. GET /calculators/compound-interest applied rate in full to every compounding period, so 5% compounded monthly grew like 5% a month. rate is now the annual nominal rate: each period earns rate divided by the periods per year (5% compounded monthly earns 5/12% a month), as meta.note now states. Parameters and response fields are unchanged; results change for every compounding frequency except annually. Separately, when contribution_frequency and compound_frequency are both daily or both weekly, deposits are no longer delayed or dropped through floating-point rounding, so total_contributions can be one deposit higher with duration_unit=months. This changes the meaning of an existing parameter: to reproduce earlier results, multiply your rate by the compounding periods per year.

  10. v1.2.0 Added

    Fear & Greed index (0–100) next to the raw score

    Every Fear & Greed reading now carries index next to score: the 0–100 Fear & Greed index exactly as shown on Bitculator (0–19 extreme fear, 20–39 fear, 40–59 neutral, 60–79 greed, 80–100 extreme greed) — use it for display. score is unchanged: the raw −100…+100 composite that index is derived from. Applies to GET /sentiment/fear-greed (the headline reading and every entry in intervals), fear_greed on GET /global and meta.fear_greed on GET /global/heatmap. Additive; no existing field changed.

  11. v1.1.2 Fixed

    Unknown fully diluted valuation is null

    GET /coins/{slug} returned fully_diluted_valuation as 0 for coins without a max supply (for example Solana and Ethereum, whose supply is uncapped). It now falls back to the total supply and is null when neither is known, as the OpenAPI contract already documented.

  12. v1.1.2 Fixed

    Fear & Greed without enough data is null

    A Fear & Greed reading that had no score yet was reported as score: 0. It is now null on GET /sentiment/fear-greed, and so are fear_greed on GET /global and meta.fear_greed on GET /global/heatmap.

  13. v1.1.1 Fixed

    Null figures, sorting and movers corrected

    marketcap and dominance can be null for a coin without circulating supply, and the trust-score score and breakdown are null for an unranked exchange. POST /alarms returns 422 when the coin has no current value for the chosen metric. /coins/recently-added and /wallets/timeline now honour sort. /coins/gainers and /coins/losers are ordered by the change itself (previously effectively by marketcap), and losers exclude coins at 0.00. Ascending sorts return null values last. /prices resolves an ambiguous symbol to the highest-ranked active coin. The OpenAPI contract marks the nullable market fields and types 24h volume as a number.

  14. v1.1.1 Added

    Insights say they are AI-written

    Every insight on GET /insights, GET /insights/{id} and GET /coins/{slug}/insights now carries generated_by: "ai" and the model that wrote it. Additive; no existing field changed.

  15. v1.1.1 Changed

    Huobi is now HTX; CoinEx inactive

    The Huobi exchange was renamed HTX and its slug changed from huobi to htx; the API does not follow slug redirects, so /exchanges/huobi now returns 404. CoinEx was set inactive and is no longer returned.

  16. v1.1.1 Fixed

    Stale 24h and 7d changes are null

    change_24h and change_7d are now null when a coin's changes have not been recomputed for 15 minutes, instead of showing an outdated move. Since 18 September the same applies to change_rank_24h and change_rank_7d.

  17. v1.1.0 Changed

    OpenAPI contract enriched

    The published contract now carries examples at media-type level, one shared error schema referenced from every 4xx/5xx response, the 401, 429 and 500 responses every keyed call can return, the X-RateLimit-* and X-Quota-* headers on every success response, the alarm.triggered delivery as a callback on POST /webhooks, and contact, licence and terms metadata. No request or response changed - only how it is described.

  18. v1.1.0 Added

    Machine-readable discovery

    New: /apis.json, /.well-known/api-catalog (RFC 9727), /.well-known/security.txt (RFC 9116), a JSON Schema bundle of the shared response shapes, a public status page with a JSON twin, this changelog, and the versioning and deprecation policy.

  19. v1.0.1 Changed

    Data API quota no longer shared with MCP

    MCP tool calls stopped counting against the Data API plan's monthly quota and burst limit; the MCP server has its own keys and plans since this day. tokens[].kind on GET /usage can now be mcp, and the over-quota 429 message reads "Your Data API plan has reached its monthly request limit." (it used to say embed plan).

  20. v1.0.1 Changed

    Verified email required to create keys

    Creating or rotating a Data API key in the developer console now requires a verified email address; accounts without an email, such as wallet sign-ins, are exempt. Key creation is limited to 10 a minute. Existing keys keep working.

  21. v1.0.1 Fixed

    Ticker volumes keep their cents

    volume_usd on GET /tickers, GET /pairs, GET /pairs/{id}, GET /coins/{slug}/markets and GET /exchanges/{slug}/tickers was stored as a whole number, so cents were lost and markets under $0.50 showed 0. Volumes now keep two decimals, and the totals built from them no longer inherit the rounding.

  22. v1.0.1 Changed

    Sparkline change is a percent for every period

    change on GET /coins/{slug}/sparkline and GET /exchanges/{slug}/sparkline was a fraction for 30d to 365d (0.05 meant +5%) but a percent for 24h and 7d. It is now a percent for every period (1.25 means +1.25%), so values for the longer periods are 100 times larger than before, and moves under 0.5% no longer round to 0.

  23. v1.0.1 Fixed

    Sparkline low and high match the series

    On both sparkline endpoints, low and high came from a summary built over a different window and could contradict points - for example a low above prices in the series. They are now the true extremes of the period points is sampled from.

  24. v1.0.1 Changed

    Vaporware wallets are listed

    GET /wallets, /wallets/timeline, /wallets/compare, /wallets/{slug} and /wallets/{slug}/assets now also return wallets with the vaporware status, so status can carry that value.

  25. v1.0.1 Fixed

    Insight source text decoded

    Source title and excerpt inside insights no longer contain raw HTML entities such as í.

  26. v1.0.1 Fixed

    Article updated_at shows the last edit

    For an article that was never edited, updated_at on GET /articles and GET /articles/{slug} showed the last time the record changed for any reason, such as a view count or a vote. It now shows the last editorial edit, falling back to the publish date, and POST /articles/{slug}/feedback no longer moves it.

  27. v1.0.1 Added

    Insight sentiment

    Insights now include sentiment: bullish, bearish, sheepish, or null when not classified.

  28. v1.0.1 Added

    Eight official SDKs

    TypeScript, Python, PHP, Go, Rust, Java, C# and C++ clients, each covering every endpoint on the same transport core: Bearer auth, envelope unwrapping, X-Quota-* capture, retries on 429 and 5xx, typed errors and paging.

  29. v1.0.1 Changed

    Plan-gated endpoints

    Endpoints can now require a plan. At introduction, GET /sentiment/indicators required Pro, and GET /sentiment/bull-bear, GET /sentiment/altseason, GET /global, GET /global/heatmap and GET /global/history/{metric} required Starter. A call outside your plan returns 403 plan_required with details.required_plan naming the plan that unlocks it, and does not consume quota.

  30. v1.0.1 Changed

    Liquidation endpoints switched off

    The six /liquidations endpoints were switched off on every plan: they return 503 endpoint_unavailable ("This endpoint is temporarily unavailable.") and do not consume quota.

  31. v1.0.1 Changed

    Pro quota lowered to 250,000

    The Pro plan's monthly quota went from 500,000 to 250,000 requests.

  32. v1.0.1 Changed

    One endpoint per indicator

    The generic GET /coins/{slug}/indicators/{family} became 13 separately documented endpoints at the same paths: rsi, stoch-rsi, sma, cci, mfi, williams-r, price-volatility, volume-volatility, macd, obv, adx, vwap and cmf. Existing calls are unchanged; an unknown indicator name now gets a plain 404 without the list of valid names.

  33. v1.0.1 Changed

    Data API plans and quota of its own

    At launch, Data API calls and embed-widget requests drew from one monthly pool tied to the embed plan. The Data API now has its own Free, Starter and Pro plans, subscription and monthly quota, with its own billing period: the calendar month in UTC on Free, anchored to the renewal day on paid plans. GET /ping and GET /usage report the Data API plan, and /usage counts only Data API calls. Limits were unchanged at the split.

  34. v1.0.1 Changed

    Documentation URLs moved

    The reference moved from /{locale}/documentation to /{locale}/documentation/api/v1, and the Postman collection and OpenAPI YAML from /documentation.postman and /documentation.openapi to /documentation/api/v1.postman and /documentation/api/v1.openapi. The old paths were removed without redirects; /api/v1/openapi.json is unchanged.

  35. v1.0.0 Added

    Data API v1

    Launch: 73 operations across 15 groups - coins, prices, markets, exchanges, wallets, global, sentiment, indicators, liquidations, conversion, calculators, editorial, alarms, webhooks and meta. Bearer keys with the data-api ability, the { data, meta } envelope, decimal-string precision, X-Quota-* headers and signed webhooks. Data API calls and embed-widget requests shared one monthly quota under the embed plan, and longer indicator windows required Starter.

Stay informed

Deprecations are announced here and by email to every key owner at least six months before removal - see the deprecation policy. The machine-readable index at /apis.json carries the date of the newest entry as its modified stamp.