Catálogo de errores

Cada respuesta de error trae un código estable en error.code. Tu cliente debe ramificar sobre ese: busca por código, filtra por dominio, o abre cualquier fila para ver la explicación completa y cómo resolverlo.

52 códigos documentados

401AUTH_REQUIREDNo se envió un token Bearer y cada llamada lo requiere.

No vimos un token Bearer en tu petición. Cada llamada a la API v6 necesita una API key en el header Authorization: sin ella no podemos saber qué organización está consultando.

Cómo resolverlo

Envía Authorization: Bearer hk_TU_API_KEY en cada petición. El esquema Bearer es la única forma aceptada de autenticarse: los estilos antiguos que mandaban la key en la URL o en el cuerpo ya no se aceptan.

Código v5 40002#auth-required
401AUTH_INVALID_KEYLa API key no se reconoce: formato equivocado, revocada o vencida.

La API key que enviaste no se reconoce. Tres situaciones producen este código: una key con el formato equivocado, una key que fue rotada o revocada, o una key que ya pasó su fecha de vencimiento.

Cómo resolverlo

Verifica que tu cliente esté usando exactamente el valor que se mostró cuando la key se creó: las keys se muestran una sola vez. Si rotaste keys hace poco, asegúrate de estar usando la nueva. Si la key venció, emite una nueva desde el portal de clientes.

Código v5 40003#auth-invalid-key
401AUTH_COST_CENTER_DISABLEDEl centro de costo asociado a la key está deshabilitado.

Cada API key está asociada a un centro de costo para que el uso se facture y se reporte correctamente. El centro de costo de esta key está deshabilitado.

Cómo resolverlo

Reactiva el centro de costo desde el portal de clientes, o emite una nueva key asociada a uno activo.

403AUTH_SERVICE_NOT_ALLOWEDLa key no tiene permitido el servicio detrás de este endpoint.

Esta key no tiene permitido llamar al servicio detrás de este endpoint. Las keys se pueden restringir a servicios específicos para que una key filtrada o mal usada solo pueda hacer aquello que se le permitió.

Cómo resolverlo

Emite una nueva key con el servicio correcto habilitado, o cambia a una que ya lo tenga. Los endpoints de diagnóstico bajo /api/v6/utilities/ siempre están disponibles, sin importar el alcance de la key.

403AUTH_CAPABILITY_NOT_ALLOWEDLa key tiene el servicio, pero no la capacidad que exige este endpoint.

Algunos endpoints exigen, además del servicio, una capacidad concedida de forma explícita. En el acortador, crear, editar, borrar y restaurar enlaces exige urlshortener.write: una key con el servicio urlshortener y sin esa capacidad lista y consulta enlaces, estadísticas, el resumen, los dominios y la tarifa, y al intentar escribir recibe este código. Los endpoints de cuenta y de organización exigen account o directory, y ahí el mensaje es otro: «This API key lacks the capability required for this endpoint. Capabilities are set when a key is issued and cannot be added later: use a key that has it, or issue a new one that includes it from the customer portal (Developers -> API keys).»

Cómo resolverlo

Las capacidades se fijan al crear la key y no se le pueden añadir después: usa una key que la tenga, o emite una nueva que la incluya y revoca la anterior. urlshortener.write solo la concede un propietario o un administrador de tu organización: si tu rol no alcanza, pídele a uno de ellos una key que pueda crear y editar enlaces. account y directory las concede cualquiera que pueda crear keys, desde el portal de clientes (Desarrolladores → Claves API).

403AUTH_IP_NOT_ALLOWEDLa key solo funciona desde ciertas redes y tu IP no está entre ellas.

Esta key tiene una lista de redes permitidas (IPs sueltas o bloques CIDR, IPv4 o IPv6) y la petición llegó desde una IP que no está en ninguna. La key es válida y tu organización está activa: lo único que no coincide es el origen. La IP con la que te vimos viene en meta.clientIp de la misma respuesta.

Cómo resolverlo

Compara meta.clientIp con las redes de la key: si llamas detrás de un NAT, un proxy o una nube, la IP de salida suele no ser la que esperas. Llama desde una red permitida, o usa una key que permita esa IP. La lista se fija al crear la key, así que para cambiarla hay que emitir una key nueva.

400AUTH_SOURCE_IP_UNKNOWNReservado: solo como puente desde v5.

Código reservado, se mantiene como puente para quienes vienen migrando desde v5. La API v6 no usa el mecanismo de sustitución de IP de origen que producía este error, así que no deberías verlo en tráfico v6.

Código v5 40015#auth-source-ip-unknown
403ACCOUNT_NOT_ACTIVETu organización está suspendida o cerrada.

Tu organización no está en estado activo, normalmente porque fue suspendida o cerrada. Mientras siga así, todos los endpoints rechazan las llamadas, incluso los de diagnóstico.

Cómo resolverlo

Contacta a soporte para revisar la situación y restaurar la organización. El estado no se puede levantar desde la API.

403ACCOUNT_BLOCKEDHay un bloqueo total activo: cada llamada se rechaza.

Tu organización tiene un bloqueo total. Cada llamada se rechaza, incluidas las de solo lectura, hasta que se retire el bloqueo.

Cómo resolverlo

Abre un ticket de soporte para revisar el caso. Los bloqueos se retiran una vez resuelto el motivo de fondo.

403ACCOUNT_READ_ONLYModo solo lectura: solo pasan GET, HEAD y OPTIONS.

Tu organización está en modo solo lectura. Las peticiones que solo consultan información (GET, HEAD, OPTIONS) siguen funcionando, pero cualquier llamada que cree o modifique datos se rechaza.

Cómo resolverlo

Hasta que se levante el bloqueo, pausa el código que modifica datos. Contacta a soporte para saber por qué está activo y qué se necesita para retirarlo.

403ACCOUNT_CONFIG_NOT_FOUNDNo pudimos cargar la organización de tu key.

Tu API key se autenticó bien, pero no pudimos cargar la organización a la que apunta. Es un problema de datos de nuestro lado, no de tu petición.

Cómo resolverlo

Contacta a soporte e incluye el meta.requestId de la respuesta: con ese id rastreamos la consulta exacta que falló.

429RATE_DDOS_EXCEEDEDVolumen inusualmente alto desde tu IP de origen.

La protección por IP de origen se disparó, por una de dos razones. La primera: tu IP produjo un volumen inusualmente alto de peticiones en el último minuto; las integraciones legítimas rara vez se acercan al límite. La segunda: desde tu IP llegaron 60 API keys distintas que no autentican en un minuto (que no existen, o que fueron revocadas o vencieron), que es la huella de quien prueba keys al azar; entonces la IP queda cortada 15 minutos y en ese tiempo recibe este 429, aunque la key que envíes sea válida. Las dos cuentan las direcciones IPv6 por su bloque /64: todas las direcciones de un mismo /64 comparten el tope y el corte.

Cómo resolverlo

Espera los segundos que indique Retry-After antes de reintentar: en el corte por keys que no autentican son los que le quedan a los 15 minutos. Si tu integración rota entre varias keys, revisa que ninguna esté mal copiada o revocada: cada key inválida distinta cuenta. Si eres un llamante legítimo detrás de una IP compartida y chocas con esto de forma consistente, contacta a soporte para revisar tu patrón de tráfico.

Código v5 40001#rate-ddos-exceeded
429RATE_TPS_EXCEEDEDExcediste el cupo de tu organización para este endpoint.

Enviaste más peticiones a este endpoint de las que permite el cupo de tu organización en la ventana actual. Cada endpoint tiene su propio cupo: chocar con la pared en uno no afecta a los demás. En el resumen y las estadísticas del acortador hay además un cupo por costo: cada consulta gasta unidades según los días y las secciones que pide, y el resumen se calcula como mucho dos veces a la vez por organización. Y el alta en lote del acortador tiene un límite por enlaces (2.100 por minuto por organización): un lote que no cabe se rechaza entero, sin crear ni cobrar nada.

Cómo resolverlo

Pausa tu cliente los segundos que indique Retry-After y vuelve a empezar. Para no llegar siquiera a tocarla, revisa los headers RateLimit-Remaining y RateLimit-Reset que vienen en cada respuesta y ajusta el ritmo. La guía de límites de uso lo explica en detalle.

Código v5 40001#rate-tps-exceeded
400IDEMPOTENCY_KEY_INVALIDLa llave de idempotencia no cumple el formato.

La Idempotency-Key es demasiado larga o trae caracteres fuera del conjunto permitido. Se aceptan de 1 a 255 caracteres de A-Z a-z 0-9 _ -. No se hizo nada: ni se creó ni se cobró.

Cómo resolverlo

Genera la llave con un UUID v4 o cualquier valor aleatorio dentro del conjunto permitido. Ver la guía de idempotencia.

409IDEMPOTENCY_IN_PROGRESSLa primera petición con esa llave sigue en proceso.

Enviaste la misma llave de idempotencia mientras la petición original todavía se está procesando. No se ejecuta dos veces: la segunda espera.

Cómo resolverlo

Espera lo que indique Retry-After y reintenta con la misma llave.

422IDEMPOTENCY_KEY_REUSEDLa llave ya existe, pero con un cuerpo distinto.

Usaste una llave de idempotencia que tu organización ya usó, con un cuerpo diferente. No se creó nada nuevo ni se cobró. Casi siempre es un error del cliente: una llave identifica una operación, no varias.

Cómo resolverlo

Usa una llave nueva para la operación nueva. No reintentes en bucle: el resultado no va a cambiar.

400URL_INVALIDLa URL de destino está mal formada.

La URL de destino no es una URL absoluta válida (no pudimos extraer un esquema y un host), o trae algo que haría que quien la lea vea un destino distinto del real: un usuario o una clave antes del dominio (https://banco.com@otro.com), un dominio con tildes, eñes o letras de otros alfabetos —también escrito en xn--—, o caracteres invisibles. El message dice cuál de estos fue.

Cómo resolverlo

Envía una URL absoluta http o https incluyendo el host, por ejemplo https://example.com/path, copiada de la barra de direcciones, sin usuario antes del dominio y con el dominio escrito solo con letras sin tilde, números y guiones.

400URL_SCHEME_NOT_ALLOWEDSolo se admiten destinos http y https.

El destino usa un esquema que no acortamos (por ejemplo javascript:, data:, ftp: o file:).

Cómo resolverlo

Solo se aceptan destinos http y https.

400URL_TOO_LONGLa URL de destino supera el largo máximo.

La URL de destino es más larga que el máximo de 2048 caracteres.

Cómo resolverlo

Acorta el destino (quita parámetros de consulta innecesarios) para que entre en 2048 caracteres.

400URL_BLOCKED_HOSTEl host de destino es privado o reservado.

El destino apunta a una dirección privada o reservada, o a un nombre de host interno (por ejemplo 127.0.0.1, 10.0.0.0/8 o localhost), o ya es un enlace corto: uno de nuestros dominios o un acortador como bit.ly, tinyurl.com o t.co. Los bloqueamos para que los enlaces cortos no sirvan para alcanzar destinos internos ni para esconder el destino final detrás de una cadena de saltos.

Cómo resolverlo

Apunta el enlace a un host alcanzable públicamente y a la dirección final a la que quieres llevar a las personas.

400ALIAS_INVALIDEl alias no cumple el formato permitido.

El alias no tiene entre 3 y 32 caracteres de minúsculas, dígitos, guion o guion bajo.

Cómo resolverlo

Usa un valor que cumpla ^[a-z0-9_-]{3,32}$, u omite alias para que la API genere el código.

409ALIAS_TAKENEl alias ya se usó en este dominio.

Ese alias ya lo usó otro enlace del mismo dominio, exista hoy o no: los enlaces eliminados o vencidos hace 90 días o más se archivan, y su código sigue reservado para siempre. Los códigos son únicos por dominio y no se liberan nunca.

Cómo resolverlo

Elige otro alias, usa un dominio distinto, u omite alias para recibir un código generado.

409ALIAS_RESERVEDEl alias es una palabra reservada.

El alias choca con una palabra reservada (por ejemplo api, stats, admin o docs), o —en un dominio de la plataforma, que comparten todas las organizaciones— se parece al nombre de una marca, un banco, un medio de pago o una entidad pública (bancolombia-seguro, pago-pse, dian). Un solo enlace de suplantación en un dominio compartido hace que los filtros de seguridad lo marquen, y entonces dejan de abrir los enlaces de todos.

Cómo resolverlo

Elige un alias que no esté reservado. Si la marca es tuya, usa tu propio dominio verificado.

400EXPIRES_AT_INVALID`expiresAt` debe ser una fecha ISO futura.

expiresAt no se pudo interpretar como fecha y hora ISO-8601, o está en el pasado.

Cómo resolverlo

Envía un valor ISO-8601 futuro, por ejemplo 2026-12-31T23:59:59Z, u omítelo para un enlace que no expira.

400NOTHING_TO_UPDATENo se envió ningún campo actualizable.

El cuerpo del PATCH no traía ninguno de los campos actualizables (longUrl, status, expiresAt).

Cómo resolverlo

Envía al menos un campo actualizable.

500CODE_GENERATION_FAILEDNo se pudo asignar un código único.

No pudimos asignar un código aleatorio único después de varios intentos. Es poco frecuente.

Cómo resolverlo

Reintenta la petición. Si persiste, cita el meta.requestId en un ticket de soporte.

400STATS_RANGE_INVALIDEl rango o la granularidad de estadísticas son inválidos.

La ventana de estadísticas no es válida: from o to no tienen la forma AAAA-MM-DD, from es posterior a to, la ventana supera el tope (366 días con day, 31 días con hour) o la granularidad no es day ni hour.

Cómo resolverlo

Envía from y to como días AAAA-MM-DD (hora de Colombia) con from anterior o igual a to, y mantén las consultas por hora dentro de 31 días.

400DOMAIN_NOT_ALLOWEDEl dominio elegido no está disponible para tu cuenta.

El domain que pediste no es un dominio global de la plataforma ni uno de tu cuenta, o tu cuenta no tiene un dominio predeterminado configurado.

Cómo resolverlo

Llama a GET /api/v6/urlshortener/domains para ver los dominios que puedes usar, u omite domain para usar el predeterminado.

409DOMAIN_NOT_VERIFIEDTu dominio todavía no está verificado.

El domain es uno propio de tu organización, pero todavía no está verificado. Mientras no lo esté no sirve para crear enlaces: podría no apuntar aún a la plataforma, y el enlace nacería roto.

Cómo resolverlo

Usa otro dominio de GET /api/v6/urlshortener/domains, u omite domain para usar el predeterminado. Para verificar el tuyo, escríbenos.

409ALIAS_RETIREDEl alias es de un enlace tuyo que eliminaste.

Ese alias ya lo usaste en un enlace que eliminaste. El código de un enlace eliminado no se libera nunca —una URL corta que ya repartiste no puede reaparecer con otro destino—, así que no se puede crear otro enlace con él. Pero ese enlace se puede restaurar durante 90 días desde que lo eliminaste; después se archiva y el alias responde ALIAS_TAKEN.

Cómo resolverlo

Restáuralo con POST /api/v6/urlshortener/links/{domain}/{code}/restore y, si hace falta, cámbiale el destino. O elige otro alias.

400URLSHORTENER_BATCH_TOO_LARGEEl lote trae más enlaces de los que admite una petición.

El alta en lote admite hasta 1.000 enlaces por petición, y el que mandaste trae más. No se creó ninguno ni se cobró nada.

Cómo resolverlo

Parte el lote en peticiones de 1.000 enlaces o menos, cada una con su propia Idempotency-Key.

402URLSHORTENER_INSUFFICIENT_FUNDSTu organización no tiene saldo para crear el enlace.

Crear un enlace se cobra al crearlo, y tu organización no tiene saldo disponible para cubrirlo (o alcanzó un tope de gasto que ella misma configuró). El enlace no se creó. En el alta en lote se reserva el precio de todos los enlaces válidos a la vez: sin saldo para todos, no se crea ninguno.

Cómo resolverlo

Recarga saldo o revisa tus topes de gasto en el portal de clientes y vuelve a intentarlo. Consulta el precio con GET /api/v6/urlshortener/pricing.

402URLSHORTENER_SPEND_LIMIT_REACHEDSe alcanzó un tope de gasto que tu organización configuró.

Tu organización tiene saldo, pero crear este enlace superaría un tope de gasto que ella misma configuró: para toda la organización, para el acortador, para un centro de costo, para un usuario o para esta clave de API. El enlace no se creó.

Cómo resolverlo

Revisa los topes de gasto de tu organización en el portal de clientes y ajusta el que corresponda. Recargar saldo no lo resuelve: el límite es tuyo, no de tu saldo.

409URLSHORTENER_NOT_PRICEDEl acortador no tiene precio configurado para tu moneda.

No encontramos una tarifa del acortador para la moneda de tu organización, así que no podemos cobrar la operación y no la hacemos. Es un problema de configuración de nuestro lado, no de tu petición.

Cómo resolverlo

No reintentes: la respuesta no va a cambiar sola. Contacta a soporte e incluye el meta.requestId de la respuesta.

409URLSHORTENER_CURRENCY_UNDEFINEDTu organización todavía no tiene moneda definida.

La moneda de una organización se elige una sola vez, al terminar de configurarla, y todo lo que consume se cobra en ella. Mientras no la tenga, no podemos ponerle precio a la operación y no la hacemos.

Cómo resolverlo

Termina de configurar la organización en el portal de clientes y vuelve a intentarlo.

404COUNTRY_NOT_FOUNDNo existe un país con ese código.

El código enviado a GET /api/v6/tools/countries/{code} no corresponde a ningún país del catálogo. El parámetro espera un ISO 3166-1 alpha-2 de dos letras.

Cómo resolverlo

Verifica el código contra GET /api/v6/tools/countries, que devuelve el catálogo completo.

503INFRA_DB_CONNECTION_ERRORUn servicio interno estuvo momentáneamente inalcanzable.

Uno de los servicios de los que dependemos estaba temporalmente inalcanzable cuando llegó tu petición. Es un problema de nuestro lado, no de lo que enviaste.

Cómo resolverlo

Reintenta tras los segundos que indique Retry-After, idealmente con un pequeño margen aleatorio. Si persiste más de un par de minutos, revisa la página de estado o abre un ticket de soporte.

503INFRA_CACHE_UNAVAILABLEUn componente interno está temporalmente no disponible.

Mismo escenario que el anterior, con otra pieza interna. La falla es transitoria y se recupera de nuestro lado sin cambios del tuyo.

Cómo resolverlo

Reintenta tras Retry-After con un pequeño margen aleatorio. Si lo sigues viendo, la página de estado suele dar el panorama.

504INFRA_DB_QUERY_TIMEOUTUna consulta interna tardó demasiado y se cortó.

Una consulta interna tomó más tiempo del que permitimos antes de devolver una respuesta, así que la cortamos en vez de dejar a tu cliente esperando de forma indefinida. En el acortador (la lista de enlaces, sus estadísticas y el resumen) la corta la propia base de datos, y pasa con consultas muy grandes para organizaciones con muchos enlaces: un rango largo, muchas secciones o una búsqueda amplia.

Cómo resolverlo

Si la consulta pide mucho, acótala —menos días, menos secciones, más filtros—: repetirla igual no ayuda. Si pasa con consultas pequeñas, abre un ticket de soporte citando el meta.requestId.

400VALIDATION_INVALID_PARAMETERUn parámetro o un campo del cuerpo no es válido.

Un parámetro de la consulta tiene un valor que no existe, o el cuerpo trae un campo desconocido, un tipo equivocado o no es JSON. El message dice cuál y qué valores acepta.

Cómo resolverlo

Corrige el parámetro o el campo que nombra el message, con los valores que documenta la referencia del endpoint.

400BAD_REQUESTNo pudimos interpretar tu petición.

No pudimos interpretar tu petición. Las causas más comunes son JSON mal formado en el cuerpo, un header Content-Type que no coincide con el contenido, o una ruta con caracteres inválidos.

Cómo resolverlo

Revisa el contenido crudo que está enviando tu cliente. Validar el JSON localmente antes de la llamada suele revelar el problema de inmediato.

401UNAUTHORIZED401 genérico: prefiere los códigos `AUTH_*` cuando estén.

401 genérico devuelto antes de que la lógica de autenticación pudiera darte un código más específico. Cuando ves este código, la petición se rechazó en una capa anterior a la validación de la API key.

403FORBIDDEN403 genérico: alternativa cuando no aplica un `ACCOUNT_*`.

La petición se autenticó bien, pero no tiene permitido acceder a este recurso. Cuando la causa es un estado conocido de la organización recibes un código ACCOUNT_*; este genérico es la alternativa.

404NOT_FOUNDLa ruta que pediste no existe en esta API.

La ruta que pediste no existe en esta API. También devolvemos este código, de forma deliberadamente indistinguible de un 404 normal, para peticiones cuyo header Host no está en nuestra lista permitida, así la superficie de la API no se puede sondear adivinando nombres de host.

Cómo resolverlo

Compara la ruta contra la referencia. Atención con la barra final y con las mayúsculas: las rutas distinguen mayúsculas de minúsculas.

405METHOD_NOT_ALLOWEDLa ruta existe pero no acepta este método HTTP.

La ruta existe pero no acepta el método HTTP que usaste, por ejemplo un POST a un endpoint de solo lectura. La respuesta incluye un header Allow con los métodos válidos.

429TOO_MANY_REQUESTS429 genérico: prefiere los códigos `RATE_*` cuando estén.

429 genérico. Cuando el límite que tocaste es uno nuestro devolvemos RATE_DDOS_EXCEEDED o RATE_TPS_EXCEEDED, que traen más contexto. Ramifica sobre los específicos cuando estén presentes.

500INTERNAL_SERVER_ERRORAlgo salió mal de nuestro lado.

Algo salió mal de forma inesperada mientras procesábamos tu petición. La traza completa queda guardada contra el mismo meta.requestId que te devolvimos, así podemos investigar sin que tengas que reproducir la falla.

Cómo resolverlo

Reintenta una vez con un pequeño retroceso. Si lo sigues viendo, abre un ticket de soporte e incluye el requestId.

503SERVICE_UNAVAILABLE503 genérico: un servicio del que dependemos no responde.

Un servicio del que dependemos no está respondiendo, o está atendiendo demasiadas peticiones a la vez: cada servicio tiene su propio cupo de peticiones simultáneas en el borde, y cuando se llena la petición se rechaza al instante con Retry-After en vez de quedarse esperando. Los códigos INFRA_* son más específicos cuando podemos nombrar el componente que falló; este es la alternativa cuando no.

Cómo resolverlo

Reintenta tras Retry-After con un pequeño margen aleatorio. Si ocurre de forma persistente, revisa la página de estado.

504GATEWAY_TIMEOUT504 genérico: un servicio del que dependemos tardó demasiado.

Un servicio del que dependemos tardó demasiado en responder. Cuando el componente lento fue la base de datos verás INFRA_DB_QUERY_TIMEOUT, que significa lo mismo con más contexto.

Cómo resolverlo

Reintenta con retroceso exponencial. Varios seguidos suelen indicar una degradación más amplia: abre un ticket de soporte con el requestId.

Cómo se estructura el código numérico

Cada error.legacyCode es un número de seis dígitos: los dos primeros identifican el dominio del error y los cuatro restantes la condición concreta. Solo aparece cuando hay puente desde la v5; los códigos nuevos de v6 lo omiten.

PrefijoDominioCubre
01xxxxAUTHAPI key, tokens, IP de origen, identidad.
02xxxxRATEProtección por IP y cupos por endpoint.
03xxxxVALIDATIONForma de la petición, JSON, parámetros, tipos.
04xxxxACCOUNTInformación de la organización, estado, bloqueos.
05xxxxBILLINGSaldo, pagos, moneda, tasa de cambio.
06xxxxSMSErrores específicos del servicio de SMS.
07xxxxWHATSAPPServicio de WhatsApp.
08xxxxEMAILServicio de correo.
09xxxxCALLBLASTINGServicio de llamadas.
10xxxxURL_SHORTENERAcortador de URLs.
11xxxxUTILITIESPing y otros endpoints de diagnóstico.
12xxxxTOOLSCatálogos y utilidades.
90xxxxINFRADependencias internas y disponibilidad.
99xxxxINTERNALExcepciones no controladas.

Los prefijos 13xxxx a 89xxxx quedan reservados para servicios futuros, para no renumerar.