Registro de cambios
Todos los cambios de la Data API y de su contrato, primero los más recientes. Los números de versión siguen la política de versionado y obsolescencia.
POST /webhooks y POST /webhooks/{id}/test comparten ahora un límite de 5 peticiones por minuto por cuenta, además del límite de ráfaga del plan. Las peticiones que lo superan reciben 429 rate_limited con Retry-After. Un evento de prueba se envía ahora una sola vez, sin reintentos; las demás entregas se siguen intentando hasta 3 veces, con backoff entre intentos. Es un límite contra el abuso y deja sin cambios la cuota mensual y el límite de ráfaga de cada plan. La política de versionado y obsolescencia se modificó ese mismo día para que este tipo de límites pueda aplicarse de inmediato; hasta entonces, reducir cualquier límite de tasa que tuviera un plan seguía el calendario de obsolescencia de seis meses. En estos dos endpoints, las cabeceras X-RateLimit-* indican cuál de los dos límites tiene menos peticiones restantes.
POST /webhooks ya no resuelve el nombre de host de la URL. Sigue devolviendo 422 cuando la URL no usa https, lleva credenciales o tiene como host una dirección IP no pública. Un nombre de host que no se resuelve, o que se resuelve a una dirección no pública, recibía hasta ahora 422; ahora se acepta con 201 y cuenta para el límite de 5 endpoints por cuenta. Cada entrega a ese endpoint falla entonces sin reintentos, error en GET /webhooks/{id}/deliveries indica el motivo, y 10 entregas fallidas seguidas desactivan el endpoint. Después de crear un endpoint, envíele un evento de prueba con POST /webhooks/{id}/test y revise el registro de entregas para comprobar que es accesible.
endpoints[].endpoint en GET /usage indica ahora la plantilla de ruta en lugar de la ruta solicitada, es decir, api/v1/coins/{slug} en lugar de api/v1/coins/bitcoin, así que cada endpoint tiene una sola fila en lugar de una por slug o id. Las peticiones registradas antes en el periodo de facturación en curso conservan su ruta, por lo que ambas formas pueden aparecer hasta que termine el periodo.
GET /exchanges/{slug} y GET /exchanges/{slug}/trust-score fallaban con un error 500 para cada exchange desde el lanzamiento de la Data API. Ahora ambos responden; los parámetros y los campos de respuesta no cambian, y un exchange sin ranking devuelve score y breakdown como null.
El contrato OpenAPI publicado ahora marca como nullable todo campo que puede ser null y tipa los valores fraccionarios como números (por ejemplo invested en GET /calculators/dca y los valores de los indicadores); los campos comunes logo, last_updated y from/to de paginación se marcan como nullable en todos los endpoints, al igual que el name y el price de las monedas en todos los endpoints de listas de monedas y de precios. Además, tipa la series del DCA como array, documenta las respuestas de GET /coins/{slug}/markets, GET /coins/losers, GET /global/history/{metric} y GET /sentiment/altseason, documenta el rango 1–365 de days en GET /sentiment/altseason (el 0 siempre se ha rechazado; omítelo para obtener la lectura actual) y enumera los códigos endpoint_unavailable (503) y http_error en el esquema de error. Ninguna petición ni respuesta ha cambiado - solo cómo se describen.
Los intentos de autenticación fallidos estaban limitados a 30 por minuto por IP, y a partir de ahí todas las claves detrás de esa IP recibían 429. Ahora una clave puede fallar 30 veces por minuto desde una IP y una IP 300 veces, las claves que se autenticaron aproximadamente en los últimos 15 minutos no quedan bloqueadas por el límite por IP, y una petición sin clave devuelve 401 sin contar. Las peticiones bloqueadas reciben 429 rate_limited con Retry-After.
Las peticiones GET y HEAD cuya ruta tiene una barra final, una barra doble o un /index.php inicial ahora reciben un 301 a la URL limpia en lugar de servirse - por ejemplo, de /api/v1/coins/ a /api/v1/coins. Los demás métodos no se ven afectados.
GET /calculators/compound-interest redondeaba la duración a periodos de capitalización completos, por lo que una duración que terminaba a mitad de un periodo se simulaba demasiado larga o demasiado corta: 6 meses con capitalización annually abarcaban un año completo (12 aportaciones y un año entero de intereses) y 5 meses no abarcaban ningún periodo (ni aportaciones ni intereses). Ahora los periodos completos se calculan como antes, el último periodo parcial genera intereses a prorrata (interés simple sobre la fracción) y se cuenta cada aportación dentro de la duración. Los resultados no cambian cuando la duración es un número entero de periodos de capitalización; los parámetros y los campos de respuesta no cambian.
La API y su documentación trataban rate como la tasa por periodo de capitalización, mientras que la calculadora del sitio web y su guía usaban una tasa anual. GET /calculators/compound-interest aplicaba rate completa a cada periodo de capitalización, de modo que un 5 % con capitalización mensual crecía como un 5 % al mes. rate es ahora la tasa nominal anual: cada periodo genera rate dividida entre el número de periodos por año (un 5 % con capitalización mensual genera un 5/12 % al mes), como indica ahora meta.note. Los parámetros y los campos de la respuesta no cambian; los resultados cambian con todas las frecuencias de capitalización salvo annually. Por otra parte, cuando contribution_frequency y compound_frequency son ambas daily o ambas weekly, los depósitos ya no se retrasan ni se pierden por el redondeo de coma flotante, por lo que total_contributions puede incluir un depósito más con duration_unit=months. Esto cambia el significado de un parámetro existente: para reproducir los resultados anteriores, multiplique su rate por el número de periodos de capitalización por año.
Cada lectura de Fear & Greed incluye ahora index junto a score: el índice Fear & Greed de 0 a 100 exactamente como se muestra en Bitculator (0–19 miedo extremo, 20–39 miedo, 40–59 neutral, 60–79 codicia, 80–100 codicia extrema); úselo para mostrar el valor. score no cambia: es el compuesto bruto de −100…+100 del que se deriva index. Se aplica a GET /sentiment/fear-greed (la lectura principal y cada entrada de intervals), a fear_greed en GET /global y a meta.fear_greed en GET /global/heatmap. Solo se añade; ningún campo existente cambia.
GET /coins/{slug} devolvía fully_diluted_valuation como 0 para monedas sin suministro máximo (por ejemplo Solana y Ethereum, cuyo suministro no tiene límite). Ahora recurre al suministro total y es null cuando no se conoce ninguno, como ya documentaba el contrato OpenAPI.
Una lectura de Fear & Greed que aún no tenía score se devolvía como score: 0. Ahora es null en GET /sentiment/fear-greed, y también lo son fear_greed en GET /global y meta.fear_greed en GET /global/heatmap.
marketcap y dominance pueden ser null para una moneda sin suministro circulante, y el score y el breakdown del trust score son null para un exchange sin ranking. POST /alarms devuelve 422 cuando la moneda no tiene un valor actual para la métrica elegida. /coins/recently-added y /wallets/timeline ahora respetan sort. /coins/gainers y /coins/losers se ordenan por la propia variación (antes, en la práctica, por capitalización de mercado), y los losers excluyen las monedas en 0.00. Las ordenaciones ascendentes devuelven los valores nulos al final. /prices resuelve un símbolo ambiguo a la moneda activa mejor clasificada. El contrato OpenAPI marca los campos de mercado que admiten null y tipa el volumen 24h como número.
Cada perspectiva de GET /insights, GET /insights/{id} y GET /coins/{slug}/insights incluye ahora generated_by: "ai" y el model que la escribió. Solo se añade; ningún campo existente cambia.
El exchange Huobi pasó a llamarse HTX y su slug cambió de huobi a htx; la API no sigue las redirecciones de slug, así que /exchanges/huobi ahora devuelve 404. CoinEx se marcó como inactivo y ya no se devuelve.
change_24h y change_7d ahora son null cuando las variaciones de una moneda no se han recalculado durante 15 minutos, en lugar de mostrar un movimiento desactualizado. Desde el 18 de septiembre, lo mismo se aplica a change_rank_24h y change_rank_7d.
El contrato publicado ahora incluye ejemplos a nivel de media type, un único esquema de error compartido referenciado desde cada respuesta 4xx/5xx, las respuestas 401, 429 y 500 que puede devolver cualquier llamada con clave, las cabeceras X-RateLimit-* y X-Quota-* en cada respuesta correcta, la entrega alarm.triggered como callback de POST /webhooks, y los metadatos de contacto, licencia y términos. Ninguna petición ni respuesta ha cambiado - solo cómo se describen.
Nuevo: /apis.json, /.well-known/api-catalog (RFC 9727), /.well-known/security.txt (RFC 9116), un paquete JSON Schema con las formas de respuesta compartidas, una página de estado pública con su gemelo JSON, este registro de cambios y la política de versionado y obsolescencia.
Las llamadas a herramientas MCP dejaron de contar contra la cuota mensual y el límite de ráfaga del plan de la Data API; el servidor MCP tiene sus propias claves y planes desde ese día. tokens[].kind en GET /usage ahora puede ser mcp, y el mensaje del 429 por exceso de cuota dice «Your Data API plan has reached its monthly request limit.» (antes mencionaba el plan de embed).
Crear o rotar una clave de la Data API en la consola de desarrollador ahora requiere una dirección de correo electrónico verificada; las cuentas sin correo, como los inicios de sesión con wallet, están exentas. La creación de claves está limitada a 10 por minuto. Las claves existentes siguen funcionando.
volume_usd en GET /tickers, GET /pairs, GET /pairs/{id}, GET /coins/{slug}/markets y GET /exchanges/{slug}/tickers se almacenaba como número entero, así que se perdían los céntimos y los mercados por debajo de $0,50 mostraban 0. Ahora los volúmenes conservan dos decimales, y los totales calculados a partir de ellos ya no heredan el redondeo.
change en GET /coins/{slug}/sparkline y GET /exchanges/{slug}/sparkline era una fracción de 30d a 365d (0,05 significaba +5 %) pero un porcentaje para 24h y 7d. Ahora es un porcentaje en todos los periodos (1.25 significa +1,25 %), por lo que los valores de los periodos más largos son 100 veces mayores que antes, y los movimientos inferiores al 0,5 % ya no se redondean a 0.
En ambos endpoints de sparkline, low y high procedían de un resumen calculado sobre otra ventana y podían contradecir points - por ejemplo, un low por encima de precios de la serie. Ahora son los extremos reales del periodo del que se muestrea points.
GET /wallets, /wallets/timeline, /wallets/compare, /wallets/{slug} y /wallets/{slug}/assets ahora también devuelven wallets con el estado vaporware, por lo que status puede tener ese valor.
Los campos title y excerpt de las fuentes dentro de las perspectivas ya no contienen entidades HTML sin procesar como í.
En un artículo que nunca se había editado, updated_at en GET /articles y GET /articles/{slug} mostraba la última vez que el registro cambió por cualquier motivo, como un contador de visitas o un voto. Ahora muestra la última edición editorial, con la fecha de publicación como alternativa, y POST /articles/{slug}/feedback ya no lo modifica.
Las perspectivas incluyen ahora sentiment: bullish, bearish, sheepish o null cuando no están clasificadas.
Clientes para TypeScript, Python, PHP, Go, Rust, Java, C# y C++, cada uno cubriendo todos los endpoints sobre el mismo núcleo de transporte: autenticación Bearer, desempaquetado del sobre, captura de X-Quota-*, reintentos ante 429 y 5xx, errores tipados y paginación.
Los endpoints ahora pueden requerir un plan. Al introducirse, GET /sentiment/indicators requería Pro, y GET /sentiment/bull-bear, GET /sentiment/altseason, GET /global, GET /global/heatmap y GET /global/history/{metric} requerían Starter. Una llamada fuera de tu plan devuelve 403 plan_required con details.required_plan indicando el plan que la desbloquea, y no consume cuota.
Los seis endpoints /liquidations se desactivaron en todos los planes: devuelven 503 endpoint_unavailable («This endpoint is temporarily unavailable.») y no consumen cuota.
La cuota mensual del plan Pro pasó de 500.000 a 250.000 peticiones.
El GET /coins/{slug}/indicators/{family} genérico se convirtió en 13 endpoints documentados por separado en las mismas rutas: rsi, stoch-rsi, sma, cci, mfi, williams-r, price-volatility, volume-volatility, macd, obv, adx, vwap y cmf. Las llamadas existentes no cambian; un nombre de indicador desconocido recibe ahora un 404 simple sin la lista de nombres válidos.
En el lanzamiento, las llamadas a la Data API y las peticiones de los widgets embebibles consumían de un mismo fondo mensual vinculado al plan de embed. La Data API tiene ahora sus propios planes Free, Starter y Pro, su propia suscripción y su propia cuota mensual, con su propio periodo de facturación: el mes natural en UTC en Free, anclado al día de renovación en los planes de pago. GET /ping y GET /usage informan del plan de la Data API, y /usage solo cuenta las llamadas a la Data API. Los límites no cambiaron con la separación.
La referencia pasó de /{locale}/documentation a /{locale}/documentation/api/v1, y la colección de Postman y el YAML de OpenAPI, de /documentation.postman y /documentation.openapi a /documentation/api/v1.postman y /documentation/api/v1.openapi. Las rutas antiguas se eliminaron sin redirecciones; /api/v1/openapi.json no cambia.
Lanzamiento: 73 operaciones en 15 grupos - coins, precios, mercados, exchanges, wallets, global, sentimiento, indicadores, liquidaciones, conversión, calculadoras, editorial, alarmas, webhooks y meta. Claves Bearer con la habilidad data-api, el sobre { data, meta }, precisión en cadenas decimales, cabeceras X-Quota-* y webhooks firmados. Las llamadas a la Data API y las peticiones de los widgets embebibles compartían una única cuota mensual bajo el plan de embed, y las ventanas de indicadores más largas requerían Starter.
Cualquier obsolescencia se anuncia aquí y por correo electrónico a cada titular de clave al menos seis meses antes de la eliminación - consulta la política de obsolescencia. El índice legible por máquina en /apis.json lleva la fecha de la entrada más reciente como su marca modified.