Códigos de error
Cada respuesta de error identifica su causa con un code estable. Esta página es el inventario completo: 830 códigos, de los cuales 722 los emite la API y el resto están registrados para traducción.
La forma del documento de error y la razón por la que se ramifica sobre code y no sobre detail están en el contrato de errores.
Códigos documentados
Admin (operación interna)
Autenticación y sesión
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
account_deleted | 401 | La cuenta fue soft-deleted. | Contactar soporte. |
account_suspended | 401 / 403 | La cuenta del caller está suspendida. | Contactar soporte. |
api_key_decryption_failed | 401 | Falla criptográfica al descifrar la API key. | Regenerar la key. |
auth_header_empty | 401 | El header Authorization está vacío. | Adjuntar Authorization: Bearer .... |
auth_method_denied | 403 | El endpoint no acepta el método de autenticación con el que llegaste. | Usar el método de auth correcto — ver Autenticación. |
forbidden | 403 | Permiso denegado por RBAC. | Pedir el permiso al admin de tu cuenta. |
invalid_api_key | 401 | El prefijo o el formato de la API key es inválido. | Regenerar la key desde /usage o POST /v1/users/me/api-key/regenerate. |
invalid_credentials | 401 | Email o contraseña incorrectos. | Mostrar mensaje genérico al usuario — no revelar cuál falló. |
invalid_encrypted_api_key | 401 | La API key no descifra contra el secret server-side (rotación de claves o key falsificada). | Regenerar la key. |
registration_disabled | 403 | El flag global registration.enabled está OFF. | Esperar a que se reactive. |
unauthorized | 401 | Credenciales ausentes, inválidas o vencidas. | Volver a autenticarse, o renovar la API key. |
unrecognized_auth_format | 401 | El header Authorization no parsea como Bearer <token>. | Usar Bearer veriko_..., con la API key. |
Beneficiarios
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
account_number_invalid_type | — | account_number llega con un tipo distinto de cadena de texto (número, arreglo, …). | Enviar account_number como string. |
account_number_required | — | Falta account_number en el cuerpo. | Agregar el campo. |
beneficiary_already_registered | 422 | La cuenta ya está en tus beneficiarios. | Reutilizar el existente. |
beneficiary_not_found_for_account | 404 | No hay beneficiario asociado a esa cuenta. | Crearlo. |
label_invalid_type | — | label llega con un tipo distinto de cadena de texto (número, arreglo, …). | Enviar label como string. |
query_param_account_required | 400 | Falta ?account= en la query. | Agregar el parámetro. |
Códigos terminales async de validaciones
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
bank_code_unresolvable_for_phone | 422 | No. | — |
banxico_error | 502 / 503 | No. | — |
intra_bank_no_cep | 422 | No. | — |
ocr_error | 502 | No. | — |
preflight_failed | 422 | No. | — |
Finanzas
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
csv_stream_failed | 500 | El stream CSV falló. | Reintentar. |
invalid_export_format | 400 | Formato pedido fuera de json/csv/xlsx/pdf. | Elegir uno soportado. |
invalid_month | 400 | Param month ausente o no YYYY-MM. | Pasar YYYY-MM. |
invalid_period | 400 | Param period no matchea convención. | Corregir. |
invalid_range | 400 | Range from/to incoherente. | Corregir. |
no_ceps | 404 | No hay CEPs disponibles en el rango. | Ajustar rango. |
pdf_render_failed | 500 | dompdf falló al renderizar. | Reintentar; reportar si persiste. |
range_required | 400 | Falta range o from/to. | Pasar uno. |
xlsx_render_failed | 500 | PhpSpreadsheet falló. | Reintentar. |
Idempotencia
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
idempotency_key_in_progress | 409 | Hay otra request en vuelo con la misma key. | Esperar Retry-After segundos y reintentar. |
idempotency_key_reused | 422 | La misma clave se usó antes con un cuerpo distinto. | Generar una clave nueva o reusar el cuerpo exacto. |
invalid_idempotency_key | 400 | El header Idempotency-Key no cumple el formato [A-Za-z0-9_-]{1,255}. | Generar key nueva con caracteres válidos. |
Importes masivos (validations + beneficiaries)
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
fecha_invalid | — | Fecha no parsea. | Corregir. |
field_too_long | 422 | Al corregir una fila, parsed_clave_rastreo o parsed_referencia_numerica exceden 64 caracteres (el ancho de la columna). | Acortar el valor. |
file_required | 422 | El upload no incluye archivo. | Adjuntar el archivo. |
job_not_editable | 422 | Querés editar una importación en estado terminal. | La importación ya fue confirmada. |
monto_invalid | — | Monto no parsea. | Corregir. |
multi_upload_not_allowed_for_text | 422 | Multi-select pero los archivos son texto plano. | Subir uno por uno o usar imágenes/ZIP. |
no_valid_fields | 422 | El cuerpo de la edición no trae campos válidos. | Incluir al menos un campo. |
no_valid_test_files | 422 | Ningún archivo del upload es procesable. | Revisar el set. |
row_persist_failed | 422 | Una fila de importación tiene un valor que no cupo en su columna ni fila por fila (red final); o, en el PATCH de una fila, una combinación de longitudes válidas por separado sigue sin caber. | Volver a capturar cuenta, clave, monto y fecha de esa fila. |
zip_pack_failed | 422 | Falló el repacking de un ZIP de imágenes. | Reintentar con ZIP estándar. |
OTP, 2FA y verificación
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
confirmation_token_already_used | 409 | El token ya fue consumido (single-use). | Re-solicitar uno nuevo. |
confirmation_token_invalid | 422 | Token de confirmación malformado. | Re-solicitar el token. |
confirmation_token_malformed | 400 | Variante: el token no tiene la estructura esperada. | Re-solicitar. |
confirmation_token_mismatch | 422 | El token corresponde a otra acción distinta. | Re-solicitar para la acción correcta. |
confirmation_token_missing | 422 | Falta el confirmation_token en una operación de step-up. | Agregar confirmation_token. |
confirmation_token_slug_mismatch | 422 | El token fue emitido para otro plan/slug. | Re-emitir para el slug correcto. |
free_plan_already_claimed | 409 | El plan gratuito ya fue reclamado por esta cuenta. | Continuar al flujo normal; no hay nada que reclamar. |
invalid_intent | 422 | intent de POST /v1/users/me/phone/confirm-verify no es verify ni claim. | Enviar uno de los dos valores, u omitir el campo (default verify). |
invalid_otp_parameters | 422 | El cuerpo del OTP está incompleto. | Revisar los campos requeridos. |
invalid_reset_context | 400 | El contexto del reset (purpose, audience, expiry) no coincide. | Reiniciar el flujo. |
invalid_verification_token | 400 | El token de un flujo de verificación es inválido o malformado. | Reiniciar el flujo de verificación. |
missing_otp_id | 400 | Falta el otp_id en el cuerpo. | Agregar otp_id. |
otp_already_used | 400 | El OTP ya fue consumido. | Solicitar otro. |
otp_expired | 400 | El OTP venció antes de ser usado. | Re-solicitar OTP. |
otp_invalid_code | 400 | El código OTP enviado es incorrecto. | Reingresarlo (máximo N intentos). |
otp_max_attempts | 400 | Se agotaron los intentos para ese OTP. | Re-solicitar un OTP nuevo. |
otp_not_found | 404 | No hay OTP activo para esa combinación user+purpose. | Re-solicitar OTP. |
phone_already_verified | 422 | El teléfono ya está verificado — no hay nada que hacer. | Continuar al flujo normal. |
phone_not_verified | — | El teléfono no está verificado. Ya no lo lanza el login (v1.58.0): iniciar sesión no exige teléfono verificado. | Verificar con POST /v1/users/me/phone/request-verify. |
phone_verification_required | 409 / 422 | La acción exige un teléfono verificado y la cuenta no lo tiene. meta.masked_phone indica a qué número irá el código (null si aún no hay teléfono) y meta.needs_phone si hay que pedirlo primero. | Abrir el flujo de verificación (POST /v1/users/me/phone/request-verify) y reintentar. |
purpose_mismatch | 400 | El OTP fue generado para otro propósito (ej. login vs. password reset). | Solicitar OTP con el purpose correcto. |
twofa_action_mismatch | 400 | El challenge resuelto no corresponde a la acción solicitada. | Re-iniciar el step-up. |
twofa_already_disabled | 422 | Se pidió disable de 2FA pero ya está disabled. | Ignorar — estado correcto. |
twofa_already_enabled | 422 | Se pidió enable de 2FA pero ya está enabled. | Ignorar — estado correcto. |
twofa_invalid_challenge | 400 | El código del challenge 2FA es incorrecto. | Reingresarlo. |
twofa_invalid_context | 400 | El contexto 2FA (purpose / audience) no matchea. | Reiniciar el flujo. |
twofa_method_same | 422 | Se pidió cambiar a un método 2FA igual al actual. | Elegir un método distinto. |
twofa_method_unsupported | 422 | El método 2FA pedido no está soportado. | Usar sms o email. |
twofa_not_enabled | 422 | Intentaste verificar 2FA pero el usuario no lo tiene activo. | Habilitar 2FA primero. |
twofa_required | 401 | El usuario tiene 2FA activo — necesitas resolver el challenge. | Disparar POST /v1/auth/2fa/verify-challenge. |
Perfil
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
language_invalid_type | — | language llega con un tipo distinto de cadena de texto. | Enviar language como string. |
name_empty | — | name queda vacío después de sanitizar (strip_tags + trim). | Mandar un nombre no vacío. |
name_invalid_type | — | name llega con un tipo distinto de cadena de texto. | Enviar name como string. |
name_too_long | — | name excede los 100 caracteres del límite de columna. | Acortar el nombre. |
timezone_invalid_type | — | timezone llega con un tipo distinto de cadena de texto. | Enviar timezone como string. |
timezone_unsupported | — | timezone no es un identificador IANA válido soportado. | Enviar un identificador IANA soportado. |
Plan y facturación
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
activation_operation_mismatch | 422 | operation_id de POST /v1/users/me/phone/confirm-verify (intent=claim) pertenece a otra cuenta, o a una intención distinta. | Generar un operation_id nuevo (UUID) para este intento. |
activation_prompt_not_reached | 422 | POST /v1/users/me/activation/prompts con action=presented para un nivel que el servidor todavía no confirma como alcanzado. | Consultar GET /v1/users/me/activation y usar su pending_prompt. |
admin_grant_failed | 422 | Falló el grant de plan admin-side. | Revisar el detalle. |
billing_disabled | 503 | El módulo de billing está desactivado en este deploy. | Esperar a que se active. |
billing_invalid_interval | 422 | El interval no es month ni year. | Usar uno permitido. |
billing_invalid_kind | 422 | El kind del precio no es base ni metered. | Usar uno permitido. |
billing_plan_is_free | 422 | Intentas subscribir a un plan free vía Stripe checkout. | El plan free se asigna sin Stripe. |
billing_plan_not_found | 404 | Variante: el slug no resuelve a un plan activo. | Revisar el slug. |
billing_plan_not_self_service | 403 | Plan no asignable vía self-service. | Contactar soporte. |
billing_plan_slug_invalid | 422 | El slug no cumple ^[a-z0-9-]+$. | Corregir. |
billing_plan_slug_required | 422 | Falta plan_slug en el cuerpo. | Agregar el campo. |
billing_plan_slug_too_long | 422 | El slug supera el max. | Acortar. |
comp_amount_invalid | 422 | Monto de compensación inválido. | Corregir. |
comp_user_missing | 422 | Falta target user en comp. | Agregar. |
comp_user_not_found | 404 | El user de comp no existe. | Verificar. |
invalid_activation_prompt_action | 422 | action de POST /v1/users/me/activation/prompts no es presented, dismissed ni cta. | Enviar uno de los tres valores. |
invalid_activation_prompt_level | 422 | level de POST /v1/users/me/activation/prompts no es one_left, exhausted ni blocked. | Enviar uno de los tres valores. |
no_active_subscription | 404 | El usuario no tiene suscripción activa. | Iniciar checkout. |
overage_not_applicable | 422 | El plan actual no soporta overage. | Upgradear plan. |
overage_update_failed | 422 | Falló el toggle de overage. | Reintentar. |
plan_not_found | 404 | El plan referenciado no existe. | Listar planes con GET /v1/plans/public. |
price_already_in_catalog | 409 | El stripe_price_id ya está usado por otro precio. | Reutilizar el existente. |
price_combo_already_exists | 409 / 422 | Combinación (plan, interval, currency, kind) duplicada. | Editar el existente. |
price_local_id_required | 422 | Falta price_local_id. | Agregar. |
price_not_active | 422 | El precio está archived. | Activar primero. |
price_not_found | 404 | El precio local no existe. | Verificar el ID. |
price_plan_mismatch | 422 | El precio referenciado no pertenece a ese plan. | Usar el plan correcto. |
refund_amount_invalid | 422 | Monto de refund inválido (negativo o > invoice). | Corregir. |
refund_invoice_not_found | 404 | El invoice referenciado no existe en Stripe. | Verificar el invoice_id. |
source_price_id_required | 422 | Falta source_price_id en migrate. | Agregar. |
stripe_cancel_failed | 502 | Stripe rechazó el cancel. | Reintentar. |
stripe_checkout_failed | 502 | Stripe rechazó la creación de session. | Reintentar. |
stripe_invoice_malformed | 500 | El invoice de Stripe llegó incompleto en el webhook. | (logged y resync). |
stripe_meter_lookup_failed | 502 | Stripe meter lookup falló. | Reintentar. |
stripe_meter_missing | 422 / 500 | El meter esperado no existe en Stripe. | Crear el meter o desactivar metered. |
stripe_price_archive_failed | 502 | Stripe rechazó archivar el precio. | Reintentar. |
stripe_price_id_format_invalid | 422 | El stripe_price_id no matchea price_*. | Corregir. |
stripe_price_id_required | 422 | Falta stripe_price_id. | Agregar. |
stripe_price_not_found | 404 | El stripe_price_id no existe en Stripe. | Verificar el ID. |
stripe_product_create_failed | 502 | Falló creación de Product en Stripe. | Reintentar. |
stripe_subscription_malformed | 500 | El subscription de Stripe llegó incompleto. | (logged y resync). |
stripe_unreachable | 502 | Stripe API timeout/connection error. | Reintentar. |
subscription_not_found | 409 | La suscripción no existe. | Verificar el user_id. |
subscription_race_retry | 409 | Race condition mutando la subscripción — el cliente debe reintentar. | Reintentar tras 1-2s. |
unit_amount_required | 422 | Falta unit_amount. | Agregar. |
Rate limit
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
rate_limit_exceeded | 429 | Variante para grupos internos (e.g. login). | Esperar y reintentar. |
Recursos genéricos
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
cep_not_available | 404 / 409 | El CEP de la validación todavía no está disponible. | Reintentar más tarde. |
changelog_empty | — | No hay changelog publicado. | Esperar publicación. |
changelog_not_found | — | La versión solicitada no existe. | Listar con GET /v1/public/changelog |
dispatch_failed | 424 / 500 / 503 | La importación no pudo despacharse al trabajador. | Reintentar. |
image_not_available | 404 | La imagen original no está accesible. | Re-uploadear (si aplica). |
internal_error | 500 | Falla inesperada. | Reintentar con backoff. |
key_not_available | 404 / 409 | La API key del user no está disponible para mostrar. | Regenerar. |
method_not_allowed | 405 | Método HTTP no soportado para ese path. | Usar uno de los permitidos. |
not_found | 404 | El recurso pedido no existe o no es visible. | Verificar el id. |
spei_calendar_year_not_covered | 404 | El año no tiene calendario de días inhábiles SPEI. | Usar uno de los años de meta.covered_years. |
user_not_found | 401 / 404 | El user referenciado no existe. | Verificar el id. |
Registro y cuenta
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
current_password_incorrect | 422 | El current_password no matchea. | Reingresar correctamente. |
current_password_required | 422 | Falta current_password en un cambio de contraseña. | Agregar el campo. |
email_already_registered | 422 | El email ya tiene cuenta verificada. | Mostrar mensaje genérico anti-enum. |
email_already_taken | 422 | Variante: el email no está libre. | Pedir otro email. |
email_already_verified | 422 | El email ya está verificado. | Continuar al flujo normal. |
email_delivery_failed | — | El proveedor de email rechazó el envío. | Reintentar; si persiste, soporte. |
email_same_as_current | 422 | El email nuevo coincide con el actual. | Ingresar uno distinto. |
invalid_email_change_context | 400 | El contexto del cambio de email no es válido (purpose mismatch). | Reiniciar el flujo. |
language_unsupported | — | Variante de unsupported_locale. | Usar es o en. |
new_password_too_short | 422 | Variante: en cambio de contraseña, la nueva es muy corta. | Usar más caracteres. |
password_mismatch | 422 | password y password_confirmation no coinciden. | Reingresar coincidentes. |
password_too_short | — | La contraseña no cumple el largo mínimo. | Usar contraseña más larga. |
password_too_weak | 422 | La contraseña no cumple las reglas de complejidad. | Reforzar la contraseña. |
phone_required_for_email_change | 422 | Necesitás teléfono verificado antes de cambiar email. | Verificar phone primero. |
phone_taken | — | El teléfono ya está en otra cuenta verificada. | Pedir otro teléfono. |
sms_delivery_failed | — | El proveedor SMS rechazó el envío del OTP. | Reintentar; si persiste, soporte. |
turnstile_failed | 422 | Con el captcha activo, falta turnstile_token o Cloudflare Turnstile no lo confirmó. | Resolver de nuevo el captcha y reenviar con el token nuevo. |
unsupported_locale | 422 | El idioma enviado no está en la lista de admitidos. | Usar es o en. |
Validación de transferencias SPEI
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
bank_code_required_for_phone | 422 | Para account_type=phone se requiere bank_code explícito. | Agregar bank_code. |
clabe_prefix_not_recognized | — | Los primeros 3 dígitos de la CLABE no coinciden con ningún banco participante de SPEI. | Verificar la CLABE — puede no ser SPEI. |
clave_or_ref_required | 422 | Se requiere clave_rastreo o referencia_numerica. | Incluir uno. |
image_not_readable | 422 | Para validaciones desde imagen (OCR): OCR no pudo leer la imagen. | Adjuntar imagen más clara. |
image_not_readable_receipt | 422 | Para validaciones desde imagen (OCR): OCR leyó pero no parece un comprobante SPEI. | Adjuntar el comprobante correcto. |
image_not_retained | 410 | GET /v1/validations/{id}/image sobre una validación creada con retain_image=false: el archivo del comprobante se borra al terminar la validación y nunca se sirve. | No reintentar: el archivo no existe por decisión del cliente. Guardar el comprobante en el sistema propio antes de enviarlo, o enviar retain_image=true (el valor por defecto) si se necesita recuperarlo. |
image_not_spei_receipt | 422 | Para validaciones desde imagen (OCR): El recibo no es SPEI (otro tipo de transferencia). | Adjuntar comprobante SPEI. |
image_or_image_url_required | 422 | Para validaciones desde imagen (OCR): No se proporcionó ni image ni image_url. | Enviar uno. |
invalid_retain_image | 422 | POST /v1/validate-ocr con un retain_image que no es booleano. Se rechaza antes de consumir cuota. | Enviar true o false (también se aceptan 0, 1 y las cadenas "true" y "false"). Un valor ambiguo nunca se lee como verdadero. |
pdf_multiple_receipts | 422 | El PDF contiene más de un comprobante. Se cobra: el archivo ya se leyó. | Enviar cada comprobante por separado. |
purge_token_mismatch | 422 | POST /v1/validations/{id}/purge/execute con un token que no es de esta validación o que se emitió para otra cuenta. | Volver a preparar el borrado con POST /v1/validations/{id}/purge/prepare para esta validación y usar el token que devuelve. El token equivocado no se gasta. |
purge_validation_in_progress | 409 | Se pidió purgar una validación que sigue en curso (queued o processing); meta.status trae el estado. | Esperar a que la validación llegue a un estado terminal (GET /v1/validations/{id}) y volver a preparar el borrado. Un ciclo de reintentos abierto no lo impide: el borrado lo cancela. |
recheck_not_eligible | 422 | POST /v1/validations/{id}/recheck sobre una validación cuyo estado no es valid ni returned; meta.status trae el estado. Una returned no da este error: responde su estado actual con 200. | No hay nada que volver a consultar: sólo un valid se revisa. Leer el estado actual con GET /v1/validations/{id}. No consume cuota. |
recheck_rate_limited | 429 | La misma validación se consultó con POST /v1/validations/{id}/recheck hace menos de 10 minutos; Retry-After y meta.retry_after traen los segundos que faltan. | Esperar Retry-After segundos. El resultado de la consulta anterior ya está en GET /v1/validations/{id}. No consume cuota. |
recheck_unavailable | 503 | Banxico no entregó un estado de pago legible (captcha, tope de consultas, red o respuesta irreconocible), o la consulta de estado está apagada. No dice nada sobre la transferencia. | Reintentar tras Retry-After segundos; el intervalo de la validación no se gastó. No consume cuota. |
recheck_window_expired | 422 | POST /v1/validations/{id}/recheck sobre una validación valid con más horas que la ventana; meta.window_hours trae la ventana vigente (72 por defecto). | Ya no se puede volver a consultar su estado de pago; si hace falta confirmar un pago antiguo, crear una validación nueva, que sí consume cuota. El rechazo no consume cuota. |
validation_purged | 410 | Se pidió la imagen, el CEP, los reintentos, la revisión posterior o el borrado de una validación que ya se purgó. GET /v1/validations/{id} sí responde: devuelve la lápida con purged_at. | No reintentar: lo que se purgó no existe. Para el veredicto, las fechas y el monto, leer la lápida con GET /v1/validations/{id}. |
Validación general de campos
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
cuenta_y_candidatas_excluyentes | 422 | La petición trae cuenta_beneficiaria y cuentas_candidatas a la vez. | Enviar una sola de las dos: la cuenta, o la lista de candidatas. No consume cuota. |
cuentas_candidatas_invalidas | 422 | cuentas_candidatas no es un arreglo de texto de 2 al máximo vigente de cuentas, o alguna no es una CLABE, tarjeta o celular válidos, o hay cuentas repetidas. | Enviar de 2 al máximo indicado en meta.max cuentas válidas y distintas, como texto; field_errors señala la posición que falló. No consume cuota. |
image_invalid_format | 422 | El comprobante no es JPEG, PNG, WebP ni PDF, o el PDF está desactivado. | Convertir a JPEG/PNG o enviar el PDF original. |
image_too_large | 422 | Imagen supera el tope de peso. | Reducir tamaño. |
invalid_account_format | 400 | El número de cuenta no es CLABE 18 / tarjeta 16 / celular E.164. | Corregir según account_type. |
invalid_account_length | 422 | Largo incorrecto para el tipo (18 CLABE / 16 tarjeta / 10 celular). | Ajustar largo. |
invalid_amount | — | Monto no es válido como decimal positivo. | Corregir. |
invalid_bank_code | 422 | El código de banco no existe en el catálogo. | Usar GET /v1/public/banks. |
invalid_card_luhn | — | El check Luhn de la tarjeta falla. | Verificar el PAN. |
invalid_clabe_checksum | — | El dígito verificador de la CLABE falla. | Verificar la CLABE. |
invalid_client_ref | 422 | client_ref no es un texto de 1 a 64 caracteres, o trae saltos de línea, caracteres de control o emoji. | Enviar un texto de 1 a 64 caracteres sin saltos de línea ni emoji, o quitar el campo. No consume cuota. |
invalid_email | 422 | El email no es válido. | Corregir. |
invalid_field_type | 422 | Un campo que debe ser texto llegó como arreglo u objeto (p. ej. emisor, receptor, referencia_numerica, o un campo de la corrección de una fila de importación). | Enviar el campo como cadena de texto. |
invalid_format | 422 | El campo no coincide con el formato esperado. | Corregir el formato. |
invalid_image | — | La imagen no es decodificable. | Reenviar. |
invalid_image_format | — | Formato fuera de JPEG/PNG/WEBP/PDF. | Convertir a JPEG/PNG o enviar el PDF original. |
invalid_receptor_participante | 422 | receptor_participante no es 0 ni 1. | Enviar 0 (cuentahabiente) o 1 (pago a banco), u omitirlo para el valor por defecto. |
invalid_request_body | 422 | El JSON no es válido. | Enviar JSON válido. |
invalid_url | — | La URL es malformada. | Corregir. |
invalid_url_scheme | 422 | Solo https aceptado. | Usar https://. |
invalid_uuid | — | No es un UUID v4. | Pasar UUID válido. |
invalid_value | 422 | El valor está fuera del set permitido. | Usar un valor del enum. |
max_length_exceeded | — | Supera el max length del campo. | Acortar. |
message_build_failed | 422 | El server no pudo armar el mensaje a responder. | Reintentar. |
missing_field | 422 | Variante de required para campos concretos. | Incluir el campo. |
pdf_active_content | 422 | El PDF trae contenido activo: JavaScript, acciones automáticas, archivos adjuntos, formularios XFA o anotaciones que no son enlaces. | Enviar el comprobante original del banco, sin editar. |
pdf_encrypted | 422 | El PDF está cifrado o protegido con contraseña. | Enviar una copia sin contraseña. |
pdf_hidden_content | 422 | El PDF trae contenido oculto: capas opcionales, formularios o texto fuera del área visible de la página. | Enviar el comprobante original del banco, sin editar. |
pdf_invalid_structure | 422 | El PDF no se puede leer: está dañado, trae datos después del final del documento o excede los topes de objetos o de anidamiento. | Volver a descargar el comprobante y reenviarlo. |
pdf_modified_after_issue | 422 | El PDF tiene más de una revisión: se modificó después de emitirse. | Enviar el comprobante tal como lo emitió el banco. |
pdf_text_layer_too_large | 422 | La capa de texto del PDF excede el tope de caracteres por página o por documento. | Enviar sólo la página del comprobante. |
pdf_too_many_pages | 422 | El PDF no tiene páginas o tiene más de 3. | Enviar sólo las páginas del comprobante. |
pdf_unsupported_image | 422 | El PDF trae una imagen JBIG2 o una imagen de más de 60 megapíxeles. | Enviar el comprobante como imagen JPEG o PNG. |
spei_calendar_year_invalid | 422 | El año de la ruta no tiene cuatro dígitos. | Enviar el año con cuatro dígitos, por ejemplo 2026. |
url_dns_failed | 400 | DNS no resolvió el host. | Verificar el host. |
url_ssrf_blocked | 400 | La URL apunta a una IP privada / DNS rebind. | Usar host público. |
validation_error | 422 | Error de validación genérico. | Revisar source.pointer y meta. |
validation_failed | 422 | Variante para fallas combinadas. | Revisar el detalle. |
Webhooks y notificaciones
code | Status | Cuándo se dispara | Qué debe hacer el cliente |
|---|---|---|---|
invalid_notification_id | 422 | El id no es UUID. | Corregir. |
notification_not_found | 404 | Notificación referenciada no existe. | Verificar el id. |
notifications_preferences_empty | 422 | El cuerpo no trae preferencias. | Agregar al menos una. |
push_fcm_token_invalid | 422 | El token FCM no tiene un formato válido. | Re-obtener el token del SDK de Firebase. |
push_fcm_token_required | 422 | Falta token (FCM) en el cuerpo. | Agregar. |
push_not_configured | 503 | El servidor no tiene ni VAPID ni FCM configurados. | Soporte. |
push_subscription_endpoint_not_https | 422 | Endpoint no es HTTPS. | Verificar el provider. |
push_subscription_endpoint_required | 422 | Falta endpoint. | Agregar. |
push_subscription_endpoint_too_long | 422 | Endpoint excede el max. | (problema del provider). |
push_subscription_invalid_shape | 422 | El objeto PushSubscription es inválido. | Re-suscribir desde el SW. |
push_subscription_none_active | 422 | No tienes suscripciones push activas. | Suscribirse primero. |
quiet_hours_invalid_timezone | 422 | El timezone no existe. | Usar IANA TZ. |
quiet_hours_minutes_out_of_range | 422 | Minutos fuera de [0, 1440]. | Corregir. |
telegram_bot_not_configured | 503 | El bot de Telegram no está configurado server-side. | Soporte. |
webhook_description_invalid_type | — | description llega con un tipo distinto de cadena de texto. | Enviar description como string. |
webhook_description_too_long | — | description excede 255 caracteres. Antes se recortaba en silencio. | Acortar la descripción. |
webhook_event_invalid | 422 | Evento fuera del registry. | Ver eventos en docs. |
webhook_events_required | — | Falta el array events. | Agregar al menos uno. |
webhook_events_too_many | — | Más eventos que el max. | Reducir. |
webhook_limit_reached | 422 | Tope de webhooks del plan alcanzado. | Upgradear plan o borrar uno. |
webhook_status_invalid | — | status no es active/disabled. | Corregir. |
webhook_url_empty | — | url enviado pero vacío. | Agregar URL real. |
webhook_url_invalid_format | — | url no parsea. | Corregir. |
webhook_url_invalid_type | — | url llega con un tipo distinto de cadena de texto. | Enviar url como string. |
webhook_url_not_https | — | El scheme no es https. | Usar HTTPS. |
webhook_url_required | 422 | Falta url. | Agregar. |
webhook_url_too_long | — | url supera 2048 chars. | Acortar. |
Códigos sin glosar
La API puede emitir estos 445 códigos, y todavía no tienen descripción. Se listan con su estado HTTP para que una integración pueda al menos clasificarlos.
code | Status |
|---|---|
admin_self_delete_not_allowed | 403 |
admin_self_restore_not_allowed | 403 |
already_blocked | 409 |
already_canceling | 409 |
analytics_not_configured | 409 |
analytics_tabla_not_found | 404 |
analytics_upstream_error | 502 |
audience_required | 422 |
audience_too_many | 422 |
audience_value_too_long | 422 |
bank_conflicts_with_confirmed | 422 |
banxico_check_cooldown | 429 |
banxico_sync_failed | 502 |
beneficiary_already_exists | 409 |
billing_already_on_plan | 409 |
billing_already_subscribed | 409 |
billing_change_not_applicable | 422 |
billing_interval_invalid | 422 |
billing_invalid_currency | 422 |
billing_no_customer | 422 |
billing_orphan_customer | 500 |
billing_overage_price_missing | 500 |
billing_plan_change_failed | 502 |
billing_plan_unresolvable | 500 |
billing_price_not_found | 422 |
billing_schedule_malformed | 502 |
billing_use_cancel_for_free | 422 |
bin_invalid | 422 |
bin_not_found | 404 |
body_empty | 400 |
body_too_large | 413 |
bot_custom_command_too_many | 422 |
bot_custom_command_trigger_reserved | 409 |
bot_custom_command_trigger_taken | 409 |
bot_system_command_trigger_reserved | 409 |
broadcast_already_active | 409 |
broadcast_audience_empty | 422 |
broadcast_audience_too_large | 422 |
broadcast_invalid_user_ids | 422 |
broadcast_message_empty | 422 |
broadcast_message_too_long | 422 |
broadcast_not_cancelable | 409 |
broadcast_not_dispatchable | 409 |
broadcast_rate_limited | 429 |
bulk_too_many | 400 |
campaign_not_found | 404 |
campaign_test_owner_only | 403 |
cannot_cancel | 409 |
cannot_modify_role_permissions | 422 |
cannot_remove_critical_permission | 422 |
cannot_restore_self | 422 |
category_too_many | 422 |
category_value_too_long | 422 |
changelog_registry_error | 500 |
channels_required | 422 |
checkout_recovery_unavailable | 404 |
ci_key_invalid | 401 |
ci_webhook_not_stored | 503 |
ci_webhook_signature_invalid | 401 |
ci_webhook_unavailable | 503 |
cloudflare_not_configured | 409 |
comp_cap_not_configured | 500 |
comp_currency_invalid | 422 |
comp_daily_cap_exceeded | 429 |
comp_lock_contention | 503 |
comp_reason_invalid | 422 |
comp_user_no_customer | 422 |
compare_runs_must_differ | 422 |
confirm_required | 422 |
control_unavailable | 409 |
create_rate_limited | 429 |
date_range_too_large | 422 |
delivery_content_not_stored | 404 |
deploy_key_already_revoked | 409 |
deploy_key_input_invalid | 422 |
deploy_key_invalid | 401 |
deploy_key_issue_failed | 500 |
deploy_key_not_found | 404 |
deploy_key_not_revealable | 409 |
deploy_key_reveal_forbidden | 403 |
deploy_scope_denied | 403 |
device_credential_id_required | 422 |
device_credential_not_found | 404 |
device_credential_reauth_required | 422 |
docs_site_missing | 503 |
email_change_confirm_mismatch | 422 |
email_change_confirm_taken | 422 |
email_change_confirm_token_invalid | 422 |
email_change_confirm_token_required | 422 |
email_change_confirm_token_used | 422 |
email_change_no_pending | 422 |
email_taken | 422 |
email_verify_email_mismatch | 422 |
email_verify_token_invalid | 422 |
email_verify_token_required | 422 |
email_verify_token_used | 422 |
email_verify_unavailable_for_placeholder | 422 |
entry_ids_required | 422 |
event_not_broadcast_safe | 422 |
event_type_required | 422 |
event_type_too_long | 422 |
filter_invalid | 422 |
github_app_not_configured | 503 |
golden_case_not_found | 422 |
golden_not_available | 422 |
health_check_not_found | 404 |
hop_not_found | 404 |
identity_not_found | 404 |
image_decompression_bomb | 422 |
image_dimensions_too_large | 422 |
image_invalid | 422 |
image_mime_mismatch | 422 |
image_polyglot_detected | 422 |
image_strip_failed | 422 |
image_too_small | 422 |
import_failed | 500 |
invalid_account | 422 |
invalid_account_type | 422 |
invalid_audience | 400 / 422 |
invalid_audience_filter | 422 |
invalid_audience_kind | 422 |
invalid_audience_override | 422 |
invalid_audience_value | 422 |
invalid_block_reason | 422 |
invalid_bot_user_id | 422 |
invalid_broadcast_id | 422 |
invalid_broadcast_language | 422 |
invalid_broadcast_segment | 422 |
invalid_campaign_step | 422 |
invalid_campaign_toggle | 422 |
invalid_category | 400 |
invalid_category_value | 422 |
invalid_channel | 422 |
invalid_channel_value | 422 |
invalid_channels | 422 |
invalid_channels_override | 422 |
invalid_custom_command_id | 422 |
invalid_custom_command_response | 422 |
invalid_custom_command_trigger | 422 |
invalid_date_filter | 422 |
invalid_date_format | 422 |
invalid_date_range | 422 |
invalid_datetime | 422 |
invalid_device_credential | 401 |
invalid_enabled | 422 |
invalid_event_type | 422 |
invalid_except_value | 422 |
invalid_expected_banxico_status | 422 |
invalid_filter | 422 |
invalid_identity | 422 |
invalid_identity_value | 422 |
invalid_impact_level | 422 |
invalid_include | 400 |
invalid_json | 400 |
invalid_lang | 400 |
invalid_limit | 400 |
invalid_page_by | 400 |
invalid_path | 422 |
invalid_payload_value | 422 |
invalid_permission_action | 422 |
invalid_plan | 422 |
invalid_proxy_request | 422 |
invalid_remember | 422 |
invalid_reorder | 422 |
invalid_role | 422 |
invalid_session_id | 422 |
invalid_setting_value | 422 |
invalid_settings | 422 |
invalid_severity | 422 |
invalid_status | 400 / 422 |
invalid_system_command_description | 422 |
invalid_system_command_id | 422 |
invalid_system_command_trigger | 422 |
invalid_telegram_token | 422 |
invalid_timestamp | 400 |
invalid_user_id_filter | 422 |
invalid_webhook_url | 422 |
last_auth_method | 409 |
legal_consent_required | 422 |
lockout_unavailable | 503 |
malformed_payload | 400 |
migration_bootstrap_missing | 500 |
migration_drift_conflict | 409 |
migration_file_missing | 404 |
migration_filename_format | 422 |
migration_filename_required | 422 |
migration_filenames_must_be_array | 422 |
migration_lock_held | 409 |
migration_mark_bulk_limit | 422 |
migration_not_found | 404 |
migration_target_invalid_type | 422 |
migration_target_version_format | 422 |
missing_jti | 401 |
missing_param | 400 |
missing_required_payload_var | 422 |
missing_required_var | 422 |
no_active_grant | 409 |
no_api_key | 404 |
no_failed_files | 404 |
no_matching_entries | 422 |
not_blocked | 409 |
not_canceling | 409 |
not_linked | 409 |
not_stripe_subscription | 422 |
notifications_preferences_invalid | 422 |
oauth_missing_handoff | 400 |
oauth_no_pending_flow | 404 |
oauth_provider_unavailable | 404 |
ocr_not_configured | 502 / 503 |
ocr_settings_acknowledge_required | 422 |
ocr_settings_revision_not_found | 404 |
only_owner_can_assign_owner | 422 |
only_owner_can_create_owner | 422 |
only_owner_can_delete_owner | 422 |
only_owner_can_modify_owner | 422 |
only_owner_can_restore_owner | 422 |
only_owner_can_suspend_admin | 422 |
openapi_spec_parse_failed | 500 |
owner_only_action | 403 |
password_already_set | 409 |
password_not_set | 422 |
path_not_allowed | 403 |
permission_actions_must_be_array | 422 |
phone_required | 422 |
phone_unavailable | 409 |
plan_api_rate_per_min_invalid | 422 |
plan_beneficiaries_max_invalid | 422 |
plan_billing_model_change_blocked | 422 |
plan_billing_model_invalid | 422 |
plan_bulk_validations_max_negative | 422 |
plan_cap_exceeded | 422 |
plan_comparison_invalid_shape | 422 |
plan_create_post_commit_inconsistent | 500 |
plan_create_stripe_price_failed | 502 |
plan_create_stripe_product_failed | 502 |
plan_currency_invalid | 422 |
plan_delete_has_active_subs | 409 |
plan_duplicate_same_slug | 422 |
plan_feature_icon_invalid | 422 |
plan_feature_text_required | 422 |
plan_feature_text_too_long | 422 |
plan_features_invalid_shape | 422 |
plan_features_too_many | 422 |
plan_free_cannot_have_initial_prices | 422 |
plan_free_cannot_have_stripe_product | 422 |
plan_included_exceeds_limit | 422 |
plan_included_validations_negative | 422 |
plan_limit_negative | 422 |
plan_name_required | 422 |
plan_name_too_long | 422 |
plan_price_edit_noop | 422 |
plan_price_migrate_invalid_proration | 422 |
plan_price_migrate_source_format_invalid | 422 |
plan_price_migrate_source_not_archived | 422 |
plan_price_migrate_source_not_found | 404 |
plan_price_migrate_source_product_mismatch | 422 |
plan_price_migrate_source_retrieve_failed | 502 |
plan_price_migrate_source_same_as_target | 422 |
plan_price_not_active | 422 |
plan_price_not_found | 404 |
plan_price_out_of_range | 422 |
plan_price_slug_mismatch | 422 |
plan_retry_max_dispatched_out_of_range | 422 |
plan_retry_max_pending_out_of_range | 422 |
plan_retry_max_retries_out_of_range | 422 |
plan_slug_already_exists | 422 |
plan_slug_format_invalid | 422 |
plan_slug_invalid | 422 |
plan_slug_required | 422 |
plan_sms_2fa_monthly_cap_negative | 422 |
plan_sort_order_negative | 422 |
plan_stale_prepare | 422 |
plan_stripe_product_missing | 422 |
plan_tax_behavior_invalid | 422 |
plan_trial_days_out_of_range | 422 |
plan_update_post_commit_inconsistent | 500 |
plan_update_stripe_price_failed | 502 |
plan_update_stripe_product_failed | 502 |
plan_webhook_per_host_per_min_invalid | 422 |
platform_disabled | 404 |
png_missing | 404 |
preview_unavailable | 404 |
price_archive_has_active_subs | 409 |
price_create_race_unrecoverable | 500 |
processing_failed | 500 |
proxy_upstream_error | 502 |
push_subscription_endpoint_conflict | 409 |
queue_unavailable | 503 |
queues_batch_failed | 500 |
queues_batches_failed | 500 |
queues_cancel_failed | 500 |
queues_cancel_prepare_failed | 500 |
queues_config_failed | 500 |
queues_config_reset_failed | 500 |
queues_config_update_failed | 500 |
queues_discard_failed | 500 |
queues_discard_prepare_failed | 500 |
queues_dlq_entry_failed | 500 |
queues_dlq_failed | 500 |
queues_job_failed | 500 |
queues_jobs_failed | 500 |
queues_overview_failed | 500 |
queues_pause_failed | 500 |
queues_restart_failed | 500 |
queues_restart_prepare_failed | 500 |
queues_resume_failed | 500 |
queues_retry_failed | 500 |
queues_retry_prepare_failed | 500 |
queues_start_failed | 500 |
queues_states_failed | 500 |
queues_stats_failed | 500 |
queues_stop_failed | 500 |
queues_worker_failed | 500 |
queues_workers_failed | 500 |
rate_limited_billing_portal | 429 |
rate_limited_email_flow | 429 |
rate_limited_login | 429 |
rate_limited_oauth | 429 |
rate_limited_otp | 429 |
rate_limited_password_reset | 429 |
rate_limited_register | 429 |
rate_limited_twofa | 429 |
reactivation_cap_exceeded | 422 |
rebuild_request_failed | 503 |
refund_amount_exceeds_refundable | 422 |
refund_cap_not_configured | 500 |
refund_currency_mismatch | 422 |
refund_daily_cap_exceeded | 429 |
refund_invoice_not_paid | 422 |
refund_lock_contention | 503 |
refund_no_charge | 422 |
release_not_found | 404 |
restore_token_expired | 422 |
restore_token_invalid | 422 |
restore_token_required | 422 |
restore_token_used | 422 |
retry_age_exceeded | 422 |
retry_already_resolved | 422 |
retry_not_active | 422 |
retry_not_applicable | 422 |
retry_not_supported_for_bulk | 422 |
retry_pending_cap_exceeded | 422 |
role_has_no_permissions | 403 |
rollback_no_down | 400 |
rotate_rate_limited | 429 |
scheduled_for_required | 422 |
scheduled_task_create_failed | 500 |
scheduled_task_delete_failed | 500 |
scheduled_task_delete_prepare_failed | 500 |
scheduled_task_detail_failed | 500 |
scheduled_task_execution_detail_failed | 500 |
scheduled_task_executions_failed | 500 |
scheduled_task_run_now_failed | 500 |
scheduled_task_update_failed | 500 |
scheduled_too_far | 422 |
scheduled_too_soon | 422 |
search_too_long | 422 |
seeder_bulk_limit | 422 |
seeder_filename_format | 422 |
seeder_filename_required | 422 |
seeder_invalid | 500 |
seeder_not_found | 404 |
service_unavailable | 503 |
session_expired | 401 |
session_not_found_or_already_revoked | 404 |
session_revoked | 401 |
session_unknown | 401 |
simulation_failed | 500 |
stale_draft | 409 |
stripe_account_check_misconfigured | 500 |
stripe_comp_failed | 502 |
stripe_customer_create_failed | 502 |
stripe_customer_persist_failed | 500 |
stripe_customer_update_failed | 502 |
stripe_event_malformed | 400 |
stripe_foreign_account | 400 |
stripe_invalid_mode | 500 |
stripe_portal_failed | 502 |
stripe_price_archive_divergent | 502 |
stripe_price_create_failed | 502 |
stripe_price_orphaned_post_create | 500 |
stripe_price_orphaned_post_edit | 500 |
stripe_price_product_mismatch | 422 |
stripe_price_shape_incompatible | 422 |
stripe_refresh_failed | 502 |
stripe_refund_failed | 502 |
stripe_resume_failed | 502 |
stripe_secret_missing | 500 |
stripe_secret_placeholder | 500 |
stripe_secret_too_short | 500 |
stripe_signature_invalid | 401 |
stripe_signature_malformed | 401 |
stripe_signature_missing | 401 |
stripe_signature_no_secrets | 500 |
stripe_signature_timestamp_skew | 401 |
stripe_subs_list_failed | 502 |
stripe_subscription_fetch_failed | 502 |
stripe_unavailable | 503 |
stripe_upcoming_failed | 502 |
stripe_webhook_endpoint_ambiguous | 409 |
stripe_webhook_endpoint_not_found | 404 |
subject_override_invalid | 422 |
subject_override_too_long | 422 |
subscriber_limit_reached | 422 |
subscription_not_cancelable | 422 |
subscription_not_resumable | 422 |
subscription_sync_failed | 500 |
sync_too_many_prices | 422 |
telegram_bot_token_missing | 422 |
telegram_identity_update_failed | 502 |
telegram_not_linked | 409 |
telegram_test_send_failed | 502 |
telegram_token_persist_failed | 500 |
telegram_token_verification_failed | 422 |
telegram_user_not_linked | 422 |
telegram_webhook_secret_missing | 422 |
telegram_webhook_set_failed | 502 |
telegram_webhook_url_not_https | 422 |
telegram_webhook_url_unresolvable | 422 |
test_file_not_found | 404 |
test_filename_format | 422 |
test_files_limit | 422 |
test_files_must_be_array | 422 |
test_name_invalid | 422 |
test_source_case_required | 422 |
test_source_image_required | 422 |
test_source_validation_id_required | 422 |
test_source_validation_image_unreadable | 422 |
test_source_validation_no_image | 422 |
test_suite_empty | 404 |
test_suite_invalid | 422 |
tests_lock_held | 409 |
twofa_method_not_verified | 422 |
twofa_setup_required | 401 |
unknown_event_type | 422 |
unknown_permission_resource | 422 |
unknown_platform | 404 |
unknown_setting_key | 422 |
unknown_slug | 404 / 422 |
unknown_test_source | 422 |
unsupported_channel | 422 |
user_not_restorable | 404 |
var_too_long | 422 |
vars_must_be_object | 422 |
version_not_found | 400 |
Sin traducción
Estos 314 códigos se emiten sin entrada en el catálogo de traducción, de modo que su detail llega en el idioma en que se escribió, sin traducir.
Registrados sin emisión detectada
Estos 69 códigos están dados de alta en el catálogo de traducción, pero el análisis del código fuente no encuentra dónde se emiten. Puede tratarse de códigos retirados o de códigos que se arman en tiempo de ejecución. Se listan para que el inventario sea completo; una integración no debería contar con recibirlos.