Skip to content

Latest commit

 

History

History
20 lines (18 loc) · 5.3 KB

File metadata and controls

20 lines (18 loc) · 5.3 KB

Feedback for the CoinMarketCap API team

From building Nemea (Markets and Trading Tools) on a Basic key, 21 September 2026. Every item was hit against the live API; the receipts are in docs/evidence/.

  1. Historical depth depends on the interval, and the error does not say so. v3/cryptocurrency/quotes/historical with interval=hourly for a range older than a month returns HTTP 400 "Your plan allows 1 months of historical access". The same range with interval=daily returns 200, all the way back to exactly 12 months ("Your plan allows 12 months of historical access" on the 13th month). Either the plan table or the message should say that daily data goes further back than hourly, and by how much.
  2. price-performance-stats is not in the Basic column of the pricing matrix, but it is a natural fit for a free plan. All-time low and high are the first thing a "how far from the bottom" alert wants. Basic gets HTTP 403 "Your API Key subscription plan doesn't support this endpoint". Nemea falls back to a labelled 365-day low from daily history.
  3. v2/cryptocurrency/info by contract address fails the whole call. One unknown address in a batch gives HTTP 500 even with skip_invalid=true, and checksum-cased addresses give 400 or 500 (lowercase works). Wallet tokens are therefore matched through info?symbol= and then by contract_address[].
  4. info by address can return another chain's platform.token_address. Matching on platform is wrong for a multi-chain token; matching on the contract_address[] list by (chain, address) is right. The docs do not say which field is authoritative.
  5. A quotes/latest request whose ids are all invalid is HTTP 400 ("No data found", credit_count 0), while a mixed request silently drops the invalid ids. A partial answer and an error for the same mistake makes retry logic guess.
  6. status.error_code is a string on some endpoints and a number on others. Every client needs to normalise it.
  7. Tags are not ordered by relevance. Bitcoin's first tag that matches a category is "Coinbase Ventures Portfolio" and Chainlink's is "Cosmos Ecosystem". About 65 of 359 categories are investor, regulatory or estate buckets. tag-groups helps, but a "primary category" field would remove a heuristic every consumer has to write.
  8. Category last_updated is a metadata date, not a freshness time. 348 of 359 were older than 30 days while the averages were live. A freshness timestamp for the averages would let clients tell stale from live.
  9. No liquidity or order-book depth in the basic data. "Sudden liquidity drop" has to be approximated by a volume dry-up, and Nemea says so.
  10. The one-minute peg check does not fit the free plan. 15,000 credits a month against about 43,200 minute-polls. /v1/key/info made it possible to plan the cadence from the real limits, which is the part that worked well.
  11. interval=1d bars are anchored to the query's time_start, not to UTC midnight. Two identical-looking requests for "10 to 13 October 2025", one starting at 00:00:00Z and one at 14:05:00Z, return different closing prices for what a user would call the same date: Dogecoin's "11 October" close was $0.1931 in the first and $0.1911 in the second. Anyone backtesting against "daily" data needs to know to fix time_start to midnight themselves; nothing in the docs says the bar boundary depends on when you happen to ask.
  12. An unrouted /v3/... path answers HTTP 200 with error_code 500 and "The system is busy, please try again later!" /v3/banana/not-real and /v3/rwa/listings/latest return byte-identical responses, while /v3/cryptocurrency/quotes/latest works normally in the same second. A wrong path is therefore indistinguishable from a real outage, and a client with retries will sit in a loop against a path that will never exist. A 404 would have saved an afternoon here. This cost us real time: we nearly published the conclusion that RWA is unavailable on Basic, when in fact we were knocking on a door that was never there.
  13. The RWA family is under /v5/real-world-assets/, which is not guessable from any sibling. Every other family this project touches is v1, v2 or v3. Nothing in the endpoint-overview page carries the /v5 prefix, so the only way to learn it is the reference page itself.
  14. real-world-assets/quotes/latest rejects the whole batch when one asset has no tokens. rwa_id=61..120 returns HTTP 400 "Invalid parameter" because eight of those assets (64, 67, 72, 77, 79, 98, 99, 113) carry no wrapper; the same sixty ids minus those eight return 200. There is no skip_invalid here as there is on cryptocurrency/quotes/latest, so every caller must first read map and filter on has_tokens. Since map is free that is workable, but it is a required step nothing documents.
  15. real-world-assets/map caps limit at 100. 300 and above return "Invalid parameter" rather than clamping. Paging 7,942 assets therefore takes 80 calls, which is free but slow.
  16. Wrappers of the same asset are denominated in different units, and nothing in the response says so. average_tokenized_price for SILVER is per troy ounce, but GRAMS is priced per gram (-93% against the average) and XAGX reads +112%. Any consumer comparing a wrapper to the asset average has to guess a sanity band; a unit or ratio field would remove the guess.