Cuotas y límites de frecuencia
Kaleidr limita el uso de dos maneras distintas y ambas devuelven el estado HTTP 429:
- Cuota es la cantidad que puede utilizar tu organización durante un período de facturación. Si se agota, tendrás que esperar a que se restablezca el período o ampliar la cuota.
- Límites de frecuencia indican a qué velocidad puedes realizar llamadas. Si los alcanzas, debes reducir la velocidad durante unos segundos.
El cuerpo de la respuesta indica qué límite has alcanzado. Esta página muestra los formatos de respuesta, cuánto se cobra por cada llamada y cómo gestionar cada caso.
Los dos fondos de uso
El uso se contabiliza por organización en dos fondos.
| Fondo | Qué lo consume | Free | Pro | Enterprise |
|---|---|---|---|---|
| Créditos de IA | Respuestas del chat, consultas de lugares, búsqueda de direcciones y análisis de diseño | 500,000 por período | 5,000,000 por período | Personalizado, según el contrato |
| Cargas de mapas | Cada sesión de Tile y cada visualización de un mapa publicado o integrado | 50,000 por período | 50,000 por período | La misma asignación base; los volúmenes superiores se acuerdan en el contrato |
Hay tres aspectos de estos fondos que suelen prestarse a confusión:
- Los créditos de IA forman un único fondo para toda la organización. Tus claves de API consumen los mismos créditos de IA que utiliza tu equipo en las aplicaciones de Kaleidr. No existe un presupuesto independiente para la API y todas las claves comparten el fondo.
- El período es el de facturación. En una suscripción de pago, corresponde al ciclo mensual que comienza el día de la suscripción. Sin suscripción, corresponde al mes natural. Los períodos se renuevan a medianoche, hora del este de Estados Unidos.
- Los paquetes aumentan el límite. Los paquetes de créditos de IA y cargas de mapas adquiridos se suman a la asignación del plan; el campo
limitde las respuestas incluye esas cantidades.
Los cambios de plan se aplican a las claves existentes en pocos minutos. No hace falta crear claves nuevas.
Qué se cobra por cada llamada
| Llamada | Fondo | Cargo |
|---|---|---|
POST /chat/control/stream, /chat/summary/stream, /chat/button/stream, /spot/overview/stream | Créditos de IA | Los tokens utilizados por la respuesta, tanto de entrada como de salida. Consulta Cómo se cobra un flujo. |
POST /chat/control/route | ninguno | Sin cargo. Se realiza una reserva mientras se calcula la ruta y siempre se libera después. |
POST /spot | Créditos de IA | Tarifa fija por llamada, se encuentre o no algo: la tarifa de /retrieval/poi/enrich si want incluye content o photos y el contenido se obtiene para esta llamada; de lo contrario, la tarifa de /retrieval/geocode/forward si incluye address. El contenido ya obtenido para una solicitud anterior no tiene coste. Una consulta que solo solicite lugares, regiones y contornos es gratuita. |
GET /retrieval/poi/enrich | Créditos de IA | Tarifa fija por llamada, incluso si no se encuentra contenido. |
GET /retrieval/geocode/forward | Créditos de IA | Tarifa fija inferior por llamada, aunque no haya resultados. No se cobra si falla la propia búsqueda. |
POST /design/analyze | Créditos de IA | Tarifa fija por llamada realizada correctamente. Sin cargo si falla. |
POST /design/apply-direct, GET /design/styles, /design/samples, /design/themes | ninguno | Sin cargo. |
POST /sdk/sessions para chat, editor, viewer | ninguno | Sin cargo. |
POST /sdk/sessions para tile | Cargas de mapas | Una carga de mapa por intercambio de sesión. |
POST /sdk/share-sessions | ninguno | Sin cargo. Las llamadas de chat realizadas con esa sesión se cobran al propietario del mapa. |
POST /inference-api/vendor/mapping/propose, la propuesta de asignación de la API para subir datos empresariales | Créditos de IA | Los tokens utilizados por la propuesta. Se llama con una sesión de cuenta, no con una clave de API. Si se agotan los créditos, responde con 429 quota_exceeded. También tiene un límite de 30 propuestas por cuenta y hora, y las dos respuestas 429 tienen formatos distintos. Subir, publicar, retirar la publicación y eliminar datos no tiene costo. |
Puedes consultar el uso y los límites actuales en kaleidr.com/billing.
Cómo se cobra un flujo
El costo de una llamada de transmisión no se conoce hasta que termina, por lo que se cobra en dos pasos:
- Reserva. Al admitir la solicitud, se reserva una cantidad fija de créditos del fondo. Si el fondo no puede cubrirla, la solicitud se rechaza con
quota_exceededantes de producir respuesta alguna. Por tanto, una llamada necesita cierta disponibilidad en el fondo para comenzar, aunque su costo final pudiera ser menor. - Liquidación. Cuando termina el flujo, la reserva se sustituye por el cargo real: los tokens utilizados en la respuesta. El cargo puede ser mayor o menor que la reserva.
Si interrumpes un flujo o falla antes de completar la respuesta, se desconoce el número de tokens y el cargo se calcula mediante una estimación:
| Flujo | Cargo si termina sin completarse |
|---|---|
/chat/control/stream | Se toma el mayor valor entre la estimación de la conversación enviada (los mensajes user y assistant de la solicitud) y la estimación del texto ya transmitido, cuyo cálculo llega hasta la reserva. Puede superar el importe reservado. |
/chat/summary/stream, /chat/button/stream, /spot/overview/stream | Estimación del texto ya transmitido, nunca superior a la reserva. |
Cerrar anticipadamente un flujo de chat no hace gratuita una conversación larga: se cobra al menos por el tamaño de la propia solicitud, por muy poco texto de respuesta que leas. Mantén las solicitudes pequeñas y envía solo los turnos necesarios para la siguiente respuesta. Consulta Lectura del flujo.
Alcanzar un límite mientras se ejecuta un flujo no lo interrumpe. La comprobación se realiza al admitir las solicitudes: la que se rechaza es la siguiente.
Las solicitudes rechazadas no se cobran. Una solicitud rechazada antes de procesarse (por límites de frecuencia o concurrencia, errores de validación o tamaño excesivo del cuerpo) no deja créditos de IA ni espacios de concurrencia reservados. Puedes volver a intentarlo sin haber pagado por el rechazo.
Límite para una clave concreta
Una clave puede tener un límite mensual (monthly_cap_tokens, configurado mediante la API de gestión de claves). Esto limita los créditos de IA que esa clave puede consumir del fondo de la organización durante un período. El fondo de la organización sigue siendo el límite global.
Una solicitud que hiciera superar el límite de una clave se rechaza con el mismo cuerpo quota_exceeded. En ese caso, limit y used muestran los valores de la clave en lugar de los del fondo.
Cuota agotada
HTTP/1.1 429 Too Many Requests
Retry-After: 1296000
Content-Type: application/json
{
"error": "quota_exceeded",
"detail": "Usage limit reached. Please try again later.",
"product": "b2b",
"meter": "b2b.tokens",
"tier": "pro",
"limit": 5000000,
"used": 4999100,
"remaining": 900,
"reset_at": "2026-11-01T04:00:00+00:00",
"period": "month",
"reset_in_seconds": 1296000
}
| Campo | Significado |
|---|---|
error | Siempre quota_exceeded en este caso. Utiliza este campo para determinar qué lógica ejecutar. |
detail | Una frase destinada a una persona. No la analices mediante código. |
product, meter | Identifican el contador de créditos de IA de la API. Para las claves de plataforma, siempre b2b y b2b.tokens. |
tier | El plan de tu organización. |
limit, used, remaining | Las cantidades de créditos del fondo compartido, o las de la clave cuando se rechaza la llamada por un límite propio de esa clave. remaining puede ser mayor que cero: la llamada se rechazó porque la reserva provisional no cabía en el saldo. |
reset_at | El momento de finalización del período, como marca de tiempo ISO 8601 con desfase horario. Utiliza este valor para informar al usuario de cuándo se reanudará el servicio. |
period | month. |
reset_in_seconds | Segundos hasta reset_at, que marca el final del período en que se restablece el fondo de créditos (tu ciclo de suscripción o, si no tienes uno, el mes natural). La cabecera Retry-After contiene el mismo número. |
El cuerpo tiene una estructura plana: los campos están en el nivel superior, no dentro de un objeto detail.
Con un token de sesión
El cuerpo anterior es el que recibe una clave de servidor o una clave heredada. Una solicitud realizada con un token de sesión se ejecuta en el navegador de un visitante. Por eso, el rechazo no revela el plan, el uso ni el límite de la organización. Esto se aplica tanto a sesiones obtenidas de una clave publicable como a sesiones de visitantes de mapas publicados.
{
"error": "quota_exceeded",
"detail": "Usage limit reached. Please try again later.",
"meter": "b2b.tokens",
"reset_at": "2026-11-01T04:00:00+00:00",
"reset_in_seconds": 1296000
}
| Campo | Clave de servidor o heredada | Token de sesión |
|---|---|---|
error, detail | Sí | Sí |
meter | Sí | Sí |
reset_at, reset_in_seconds | Sí | Sí |
product, period | Sí | No |
tier | Sí | No |
limit, used, remaining | Sí | No |
El estado, la cabecera Retry-After y su significado son los mismos. En el código del navegador, comprueba error y muestra reset_at; no intentes leer limit, used ni remaining. Para mostrar datos de uso, consúltalos desde tu backend con una clave de servidor o en kaleidr.com/billing.
Si el cuerpo indica used: 0 aunque sabes que la organización ha tenido actividad, significa que la API no pudo leer el uso y rechazó la solicitud por precaución. Vuelve a intentarlo en unos segundos en vez de esperar a reset_at.
Límites de frecuencia y concurrencia
Antes de cada llamada en tiempo de ejecución se aplican tres límites. Las solicitudes excedentes se rechazan de inmediato; no se ponen en cola.
| Límite | Se cuenta por | Qué incluye |
|---|---|---|
| Solicitudes por minuto | Clave | Ventana móvil de 60 segundos para todas las llamadas en tiempo de ejecución realizadas con la clave y con todas las sesiones obtenidas de ella. Todos los visitantes de un sitio que utiliza la misma clave publicable comparten este presupuesto. |
| Intercambios de sesión por minuto | Clave | Llamadas a POST /sdk/sessions. Tiene un presupuesto independiente, por lo que montar integraciones no consume llamadas en tiempo de ejecución. |
| Solicitudes simultáneas | Organización | Las llamadas que se ejecutan al mismo tiempo con cualquier clave de la organización. Un flujo cuenta mientras permanezca abierto. |
El valor de solicitudes por minuto de una clave no puede modificarse desde la página de claves de API ni desde la API de gestión de claves. Si necesitas una frecuencia mayor para tu tráfico, ponte en contacto con nosotros.
Todos estos rechazos tienen el mismo formato y la misma cabecera:
HTTP/1.1 429 Too Many Requests
Retry-After: 5
Content-Type: application/json
{ "error": "rate_limited", "detail": "API key rate limit exceeded. Slow down." }
error | Significado | Qué hacer |
|---|---|---|
rate_limited | Se agotó el presupuesto de solicitudes por minuto o de intercambios de sesión de la clave. | Espera los segundos indicados en Retry-After y vuelve a intentar la llamada. Añade una variación aleatoria a la espera. |
org_overloaded | Tu organización tiene demasiadas llamadas en curso. | Espera a que termine alguna y vuelve a intentarlo. Cierra los flujos que ya no necesites. |
b2b_overloaded | La API alcanzó su capacidad para todos los usuarios. | Espera los segundos de Retry-After y reintenta con pausas progresivamente mayores. |
limiter_unavailable | El sistema de límites de frecuencia no pudo responder. | Vuelve a intentarlo en breve. Reducir la frecuencia no ayuda, porque el problema no es tu ritmo de llamadas. |
visitor_limit_reached | Un visitante del chat de un mapa publicado ha realizado demasiadas solicitudes por minuto o por día. | Muestra al visitante un mensaje para que vuelva a intentarlo más tarde. Consulta Chat en un mapa publicado. |
Las solicitudes también están sujetas a límites de frecuencia en el perímetro de la red, por dirección IP y credencial. Una solicitud bloqueada allí no lleva ninguno de los cuerpos JSON mostrados en esta página. Trata una respuesta 4xx sin cuerpo de Kaleidr como una indicación de reducir la frecuencia y volver a intentarlo después.
Cargas de mapas
Se cuenta una carga de mapa cada vez que un mapa de Kaleidr se inicia para un visitante:
- cada intercambio de sesión de
product: "tile", incluida la renovación del SDK y cada nuevo montaje del elemento; - cada visualización de un mapa publicado o integrado.
El intercambio de sesión del Editor integrado no cuenta como carga de mapa. En su lugar, las solicitudes de mapa base que incluyen tu clave publicable (estilo, sprites y fuentes) se contabilizan en bloques: cada 20 solicitudes que tu organización haga en una hora añaden una carga de mapa a posteriori. Estas solicitudes nunca se rechazan por el límite de cargas. Los datos de las propias teselas no se contabilizan.
Todos los planes se detienen al agotar la asignación. Cuando se acaba el fondo, la siguiente carga se rechaza y no se cuenta. No existe un margen adicional en los planes de pago; comprar un paquete de cargas de mapas aumenta el límite de inmediato.
En el intercambio de sesión, el rechazo se presenta así:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{ "detail": "map_load_quota_exceeded" }
A diferencia del cuerpo plano de cuota anterior, este cuerpo se encapsula en detail y no tiene cabecera Retry-After. Reintentarlo no sirve hasta que se restablezca el período o se añada un paquete. En la página, el módulo Tile integrado no puede iniciarse y el SDK registra kaleidr session exchange failed (429).
Solicitudes directas de teselas
El servidor de teselas del mapa base no es una API pública de teselas. Para mostrar un mapa base de Kaleidr se debe utilizar el producto Tile. Se rechaza toda solicitud a tile.kaleidr.com que no proceda de una integración de Kaleidr con una clave publicable válida desde un origen permitido:
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
Cache-Control: no-store
Content-Type: application/json
{
"error": "tile_access_restricted",
"message": "Direct access to tile.kaleidr.com requires a Kaleidr publishable key. Mint a free one at kaleidr.com/api-keys and pass it as ?key= from an allowed origin. Kaleidr-hosted maps and embeds are unaffected.",
"docs": "https://docs.kaleidr.com/get-an-api-key"
}
Esta respuesta proviene del servidor de teselas, no de la API de plataforma; por eso utiliza message donde la API emplea detail. Una clave recién creada o modificada puede tardar unos minutos en obtener acceso a las teselas.
El evento quota en un flujo
Un flujo de chat informa del saldo después de que se haya cobrado. El evento quota es el último del flujo y se envía después de end o error:
event: quota
data: {"type": "quota", "product": "b2b", "meter": "b2b.tokens", "tier": "pro", "used": 184223, "limit": 5000000, "reset_at": "2026-11-01T04:00:00+00:00", "period": "month"}
Ese es el evento de un flujo leído con una clave de servidor o una clave heredada. En un flujo leído con un token de sesión (obtenido de una clave publicable o de una sesión de visitante de un mapa publicado), el evento no contiene el plan ni cifras de uso:
event: quota
data: {"type": "quota", "meter": "b2b.tokens", "reset_at": "2026-11-01T04:00:00+00:00"}
| Campo | Clave de servidor o heredada | Token de sesión |
|---|---|---|
type, meter, reset_at | Sí | Sí |
product, period | Sí | No |
tier | Sí | No |
used, limit | Sí | No |
Con una clave de servidor, puedes usar este evento para actualizar un indicador de uso sin hacer una segunda solicitud. Hay tres restricciones:
- No contiene el campo
remaining. Calculalimit - used. - Se envía cuando es posible. Un flujo puede terminar sin incluirlo, así que no esperes a recibirlo.
- Informa del consumo, pero no advierte de antemano. Nunca llega en mitad de una respuesta y no puede detener un flujo.
Para recibirlo, sigue leyendo hasta que se cierre el cuerpo de la respuesta. Un cliente que deja de leer al recibir end lo pierde.
Cómo gestionar 429 en el código
Lee el cuerpo antes de decidir. El código de estado por sí solo no indica si debes reintentar la llamada.
| Respuesta recibida | ¿Reintentar? | Cuándo |
|---|---|---|
error: "quota_exceeded" | No | Después de reset_at, tras añadir créditos o aumentar el límite de la clave. Indica al usuario que se alcanzó el límite. |
error: "rate_limited", "org_overloaded", "b2b_overloaded", "limiter_unavailable" | Sí | Tras los segundos indicados en Retry-After, con variación aleatoria, y como máximo unas pocas veces. |
error: "visitor_limit_reached" | No | Más adelante; informa al visitante. |
detail: "map_load_quota_exceeded" | No | Una vez restablecido el período o añadido un paquete de cargas de mapas. |
error: "tile_access_restricted" | No | Corrige la integración: utiliza el producto Tile con una clave publicable en un origen permitido. |
const RETRYABLE = new Set(['rate_limited', 'org_overloaded', 'b2b_overloaded', 'limiter_unavailable']);
async function callKaleidr(url, init, attempt = 0) {
const res = await fetch(url, init);
if (res.status !== 429) return res;
const body = await res.json().catch(() => ({}));
if (RETRYABLE.has(body.error) && attempt < 3) {
const seconds = Number(res.headers.get('retry-after')) || 5;
await new Promise((resolve) => setTimeout(resolve, (seconds + Math.random()) * 1000));
return callKaleidr(url, init, attempt + 1);
}
const error = new Error(body.error || body.detail || 'rate limited');
error.status = 429;
error.code = body.error || body.detail;
error.resetAt = body.reset_at; // present for quota_exceeded
throw error;
}
En el navegador, JavaScript puede leer la cabecera Retry-After de las respuestas de la API de plataforma.
Temas relacionados
- Errores: todos los estados y códigos.
- Contrato SSE: dónde se sitúa el evento
quotaen un flujo. - Lectura del flujo: clientes completos con reintentos y gestión de tiempos de espera.
- Obtener una clave de API: qué incluye cada plan.