Журнал изменений
Каждое изменение Data API и его контракта, сначала новые. Номера версий следуют политике версионирования и устаревания.
POST /webhooks и POST /webhooks/{id}/test теперь используют общий лимит 5 запросов в минуту на аккаунт - в дополнение к минутному лимиту тарифа. Запросы сверх него получают 429 rate_limited с Retry-After. Тестовое событие теперь отправляется один раз, без повторов; для остальных доставок по-прежнему делается до 3 попыток, с задержкой между попытками. Это лимит против злоупотреблений, и он не меняет месячную квоту и минутный лимит ни одного тарифа. Политика версионирования и устаревания была изменена в тот же день, чтобы такие лимиты могли вступать в силу сразу; до тех пор снижение любого лимита запросов, который был у тарифа, следовало шестимесячным срокам устаревания. На этих двух эндпоинтах заголовки X-RateLimit-* показывают тот из двух лимитов, по которому осталось меньше запросов.
POST /webhooks больше не ищет имя хоста из URL в DNS. Он по-прежнему возвращает 422, если URL не использует https, содержит учётные данные или указывает в качестве хоста непубличный IP-адрес. Имя хоста, которое не удаётся найти в DNS или которое указывает на непубличный адрес, раньше получало 422; теперь оно принимается с 201 и учитывается в лимите 5 эндпоинтов на аккаунт. Каждая доставка на такой эндпоинт тогда завершается ошибкой без повторов, поле error в GET /webhooks/{id}/deliveries называет причину, а 10 неудачных доставок подряд отключают эндпоинт. После создания эндпоинта отправьте на него тестовое событие через POST /webhooks/{id}/test и проверьте в журнале доставки, что он доступен.
endpoints[].endpoint в GET /usage теперь содержит шаблон маршрута вместо запрошенного пути: api/v1/coins/{slug} вместо api/v1/coins/bitcoin. Так у каждого эндпоинта одна строка, а не по одной на каждый slug или id. Запросы, учтённые раньше в текущем расчётном периоде, сохраняют свой путь, поэтому до конца периода могут встречаться обе формы.
GET /exchanges/{slug} и GET /exchanges/{slug}/trust-score с момента запуска Data API завершались ошибкой 500 для каждой биржи. Теперь оба отвечают; параметры и поля ответа не изменились, а для биржи без ранга score и breakdown возвращаются как null.
Опубликованный контракт OpenAPI теперь помечает как nullable каждое поле, которое может быть null, и типизирует дробные значения как числа (например, invested в GET /calculators/dca и значения индикаторов); общие поля logo, last_updated и поля пагинации from/to помечены как nullable во всех эндпоинтах, а name и price монеты - во всех эндпоинтах списков монет и цен. Кроме того, он типизирует series в DCA как массив, документирует ответы GET /coins/{slug}/markets, GET /coins/losers, GET /global/history/{metric} и GET /sentiment/altseason, документирует для days в GET /sentiment/altseason диапазон 1–365 (0 всегда отклонялся; чтобы получить текущее значение, не передавайте этот параметр) и перечисляет в схеме ошибки коды endpoint_unavailable (503) и http_error. Ни один запрос или ответ не изменился - только то, как они описаны.
Раньше неудачная аутентификация ограничивалась 30 попытками в минуту на IP, после чего каждый ключ за этим IP получал 429. Теперь один ключ может ошибиться 30 раз в минуту с одного IP, а один IP - 300 раз; ключи, успешно прошедшие аутентификацию примерно за последние 15 минут, не блокируются лимитом по IP, а запрос без ключа возвращает 401 и не учитывается. Заблокированные запросы получают 429 rate_limited с Retry-After.
Запросы GET и HEAD, путь которых содержит завершающий слеш, двойной слеш или начальный /index.php, теперь получают 301 на чистый URL, а не обслуживаются как есть - например, с /api/v1/coins/ на /api/v1/coins. Другие методы это не затрагивает.
GET /calculators/compound-interest округлял срок до целого числа периодов капитализации, поэтому срок, заканчивающийся посреди периода, моделировался слишком длинным или слишком коротким: 6 месяцев при капитализации annually считались полным годом (12 взносов и проценты за весь год), а 5 месяцев не давали ни одного периода (ни взносов, ни процентов). Теперь целые периоды рассчитываются как прежде, последний неполный период приносит проценты пропорционально (простые проценты за его долю), а каждый взнос в пределах срока учитывается. Если срок равен целому числу периодов капитализации, результаты не меняются; параметры и поля ответа не изменились.
API и его документация трактовали rate как ставку за период капитализации, тогда как калькулятор на сайте и инструкция к нему использовали годовую ставку. GET /calculators/compound-interest применял rate целиком к каждому периоду капитализации, поэтому 5% при ежемесячной капитализации росли как 5% в месяц. Теперь rate - номинальная годовая ставка: каждый период приносит rate, делённую на число периодов в году (5% при ежемесячной капитализации дают 5/12% в месяц), о чём теперь сообщает meta.note. Параметры и поля ответа не меняются; результаты меняются для всех частот капитализации, кроме annually. Кроме того, если contribution_frequency и compound_frequency обе равны daily или обе равны weekly, взносы больше не задерживаются и не теряются из-за округления чисел с плавающей запятой, поэтому total_contributions при duration_unit=months может быть больше на один взнос. Это меняет смысл существующего параметра: чтобы воспроизвести прежние результаты, умножьте rate на число периодов капитализации в году.
Каждое значение Fear & Greed теперь содержит index рядом с score: индекс Fear & Greed от 0 до 100 в точности как на Bitculator (0–19 крайний страх, 20–39 страх, 40–59 нейтрально, 60–79 жадность, 80–100 крайняя жадность) — используйте его для отображения. score не изменился: это исходный составной показатель −100…+100, из которого выводится index. Относится к GET /sentiment/fear-greed (основное значение и каждая запись в intervals), fear_greed в GET /global и meta.fear_greed в GET /global/heatmap. Только добавление; существующие поля не изменены.
GET /coins/{slug} возвращал fully_diluted_valuation равным 0 для монет без максимального предложения (например, Solana и Ethereum, предложение которых не ограничено). Теперь используется общее предложение, а если неизвестно ни одно, значение равно null, как уже было описано в контракте OpenAPI.
Значение Fear & Greed, у которого ещё не было оценки, возвращалось как score: 0. Теперь в GET /sentiment/fear-greed это null, как и fear_greed в GET /global и meta.fear_greed в GET /global/heatmap.
marketcap и dominance могут быть null для монеты без циркулирующего предложения, а score и breakdown рейтинга доверия равны null для биржи без ранга. POST /alarms возвращает 422, если у монеты нет текущего значения выбранной метрики. /coins/recently-added и /wallets/timeline теперь учитывают sort. /coins/gainers и /coins/losers сортируются по самому изменению (раньше фактически по рыночной капитализации), а losers исключают монеты с 0.00. Сортировка по возрастанию возвращает null-значения последними. /prices сопоставляет неоднозначный символ с активной монетой с самым высоким рейтингом. Контракт OpenAPI помечает рыночные поля, которые могут быть null, и типизирует объём за 24 ч как число.
Каждый материал аналитики в GET /insights, GET /insights/{id} и GET /coins/{slug}/insights теперь содержит generated_by: "ai" и model, которая его написала. Только добавление; существующие поля не изменены.
Биржа Huobi переименована в HTX, и её slug изменился с huobi на htx; API не следует перенаправлениям slug, поэтому /exchanges/huobi теперь возвращает 404. CoinEx переведена в неактивные и больше не возвращается.
change_24h и change_7d теперь равны null, если изменения монеты не пересчитывались 15 минут, а не показывают устаревшее движение. С 18 сентября то же относится к change_rank_24h и change_rank_7d.
Опубликованный контракт теперь содержит примеры на уровне media-type, одну общую схему ошибки, на которую ссылается каждый ответ 4xx/5xx, ответы 401, 429 и 500, которые может вернуть любой вызов с ключом, заголовки X-RateLimit-* и X-Quota-* в каждом успешном ответе, доставку alarm.triggered как callback на POST /webhooks, а также метаданные контакта, лицензии и условий. Ни один запрос или ответ не изменился - только то, как они описаны.
Новое: /apis.json, /.well-known/api-catalog (RFC 9727), /.well-known/security.txt (RFC 9116), бандл JSON Schema с общими формами ответов, публичная страница статуса с JSON-двойником, этот журнал изменений и политика версионирования и устаревания.
Вызовы MCP-инструментов перестали расходовать месячную квоту и минутный лимит тарифа Data API; с этого дня у MCP-сервера собственные ключи и тарифы. tokens[].kind в GET /usage теперь может быть mcp, а сообщение 429 о превышении квоты гласит «Your Data API plan has reached its monthly request limit.» (раньше в нём упоминался тариф встраивания).
Создание или ротация ключа Data API в консоли разработчика теперь требует подтверждённого адреса электронной почты; аккаунты без email, например созданные через вход с кошельком, освобождены от этого требования. Создание ключей ограничено 10 в минуту. Существующие ключи продолжают работать.
volume_usd в GET /tickers, GET /pairs, GET /pairs/{id}, GET /coins/{slug}/markets и GET /exchanges/{slug}/tickers хранился как целое число, поэтому центы терялись, а рынки с объёмом меньше $0,50 показывали 0. Теперь объёмы сохраняют два знака после запятой, и построенные из них итоги больше не наследуют округление.
change в GET /coins/{slug}/sparkline и GET /exchanges/{slug}/sparkline был долей для периодов от 30d до 365d (0,05 означало +5%), но процентом для 24h и 7d. Теперь это процент для каждого периода (1.25 означает +1,25%), поэтому значения для более длинных периодов в 100 раз больше прежних, а движения меньше 0,5% больше не округляются до 0.
В обоих эндпоинтах спарклайнов low и high брались из сводки, построенной по другому окну, и могли противоречить points - например, low выше цен в ряду. Теперь это истинные экстремумы периода, из которого выбираются points.
GET /wallets, /wallets/timeline, /wallets/compare, /wallets/{slug} и /wallets/{slug}/assets теперь также возвращают кошельки со статусом vaporware, поэтому status может принимать это значение.
title и excerpt источников внутри аналитики больше не содержат необработанных HTML-сущностей, таких как í.
Для статьи, которую ни разу не редактировали, updated_at в GET /articles и GET /articles/{slug} показывал время последнего изменения записи по любой причине, например из-за счётчика просмотров или голоса. Теперь он показывает последнюю редакционную правку, а при её отсутствии - дату публикации, и POST /articles/{slug}/feedback его больше не сдвигает.
Аналитика теперь включает sentiment: bullish, bearish, sheepish или null, если настроение не классифицировано.
Клиенты для TypeScript, Python, PHP, Go, Rust, Java, C# и C++, каждый покрывает все эндпоинты на общем транспортном ядре: Bearer-аутентификация, распаковка оболочки, захват X-Quota-*, повторы при 429 и 5xx, типизированные ошибки и постраничная навигация.
Эндпоинты теперь могут требовать определённого тарифа. На момент введения GET /sentiment/indicators требовал Pro, а GET /sentiment/bull-bear, GET /sentiment/altseason, GET /global, GET /global/heatmap и GET /global/history/{metric} - Starter. Вызов вне вашего тарифа возвращает 403 plan_required, где details.required_plan называет тариф, который его открывает, и не расходует квоту.
Шесть эндпоинтов /liquidations отключены на всех тарифах: они возвращают 503 endpoint_unavailable («This endpoint is temporarily unavailable.») и не расходуют квоту.
Месячная квота тарифа Pro снижена с 500 000 до 250 000 запросов.
Общий GET /coins/{slug}/indicators/{family} превратился в 13 отдельно задокументированных эндпоинтов по тем же путям: rsi, stoch-rsi, sma, cci, mfi, williams-r, price-volatility, volume-volatility, macd, obv, adx, vwap и cmf. Существующие вызовы не изменились; на неизвестное имя индикатора теперь возвращается простой 404 без списка допустимых имён.
При запуске вызовы Data API и запросы виджетов расходовали один месячный пул, привязанный к тарифу встраивания. Теперь у Data API собственные тарифы Free, Starter и Pro, подписка и месячная квота с собственным расчётным периодом: календарный месяц по UTC на Free и период с привязкой ко дню продления на платных тарифах. GET /ping и GET /usage сообщают тариф Data API, а /usage считает только вызовы Data API. При разделении лимиты не изменились.
Справочник переехал с /{locale}/documentation на /{locale}/documentation/api/v1, а коллекция Postman и OpenAPI YAML - с /documentation.postman и /documentation.openapi на /documentation/api/v1.postman и /documentation/api/v1.openapi. Старые пути удалены без перенаправлений; /api/v1/openapi.json не изменился.
Запуск: 73 операции в 15 группах - монеты, цены, рынки, биржи, кошельки, глобальные данные, настроения, индикаторы, ликвидации, конвертация, калькуляторы, редакционные материалы, оповещения, вебхуки и мета. Bearer-ключи с правом data-api, оболочка { data, meta }, точность десятичных строк, заголовки X-Quota-* и подписанные вебхуки. Вызовы Data API и запросы виджетов делили одну месячную квоту в рамках тарифа встраивания, а более длинные окна индикаторов требовали Starter.
Об устаревании объявляется здесь и по электронной почте каждому владельцу ключа не позднее чем за шесть месяцев до удаления - см. политику устаревания. Машиночитаемый индекс /apis.json несёт дату самой новой записи в своей метке modified.