ZEVRACentro de Ayuda
IntegracionesAPI de captación

Errores

Cada código de error de la API, qué significa y qué hacer.

La forma de un error

Todas las respuestas de error, sin excepción, tienen este cuerpo:

{
  "error": {
    "code": "validation_error",
    "message": "telefono must contain at least 10 digits",
    "field": "telefono",
    "docs_url": "https://docs.zevra.co/integraciones/api-captacion/errores#validation_error"
  },
  "request_id": "req_4f1c9a2b7d3e8c5a6b0f1e2d"
}
  • code es estable: programa contra él. El message está en inglés, pensado para quien programa, y puede cambiar de redacción.
  • field aparece solo cuando el error apunta a un campo o cabecera concretos, en notación con puntos (propiedad.codigo, extras.presupuesto, Idempotency-Key).
  • docs_url apunta a la sección de esta página que explica el código.
  • request_id identifica el intento. Aparece también en la cabecera X-Request-Id y en Solicitudes recibidas dentro del dashboard.

Resumen

HTTPcodeReintentar
400validation_errorDespués de corregir el cuerpo.
401invalid_keyNo, hasta tener una llave válida.
403plan_feature_unavailableNo, hasta que la organización cambie a un plan de pago.
404not_foundNo.
405method_not_allowedNo.
409idempotency_conflictCon otra Idempotency-Key.
409idempotency_in_progressSí, después de Retry-After (1 segundo).
413payload_too_largeDespués de reducir el cuerpo.
415unsupported_media_typeDespués de corregir Content-Type.
422property_not_foundDespués de corregir la propiedad.
422unit_type_not_foundDespués de corregir el Modelo señalado en field.
429rate_limitedSí, después de Retry-After.
500internal_errorSí, con la misma Idempotency-Key.
503temporarily_unavailableSí, después de Retry-After (5 segundos).

Errores de validación

400 validation_error. El cuerpo, uno de sus campos o una cabecera no pasó la validación. field indica cuál. Casos comunes:

  • body: el cuerpo no es JSON válido o no es un objeto.
  • nombre: falta o pasa de 200 caracteres.
  • telefono: tiene menos de 10 dígitos.
  • email: no tiene forma de correo.
  • mensaje: pasa de 2 000 caracteres.
  • propiedad: trae dos identificadores, ninguno, o una llave que no es codigo, external_code ni id.
  • extras: más de 20 entradas, una llave de más de 60 caracteres, un valor de más de 200 caracteres, o un valor que no es texto, número ni booleano.
  • calificacion.operacion: un valor distinto de comprar o rentar.
  • calificacion.presupuesto: min o max no son números (cero o mayores).
  • calificacion.modelos: no es una lista, está vacía, trae más de 10 entradas, alguna entrada trae id y nombre a la vez o ninguno de los dos, viene sin propiedad en el cuerpo (los Modelos se buscan dentro de esa propiedad), o el cuerpo trae modelo y modelos al mismo tiempo (field es calificacion.modelos).
  • calificacion.modelo: la forma corta de un solo Modelo, con las mismas reglas por entrada.
  • atribucion: no es un objeto.
  • atribucion.campana (o fuente, medio, contenido, pagina): el valor no es texto. atribucion.pagina también cuando no es una URL ni una ruta que empiece por /.
  • Idempotency-Key: vacía, de más de 200 caracteres o con caracteres que no son ASCII imprimible.

Corrige el campo y vuelve a mandar. Si usaste Idempotency-Key, puedes reutilizarla: un intento fallido no la reserva.

Llave inválida

401 invalid_key. La cabecera Authorization falta, no usa el esquema Bearer, la llave no existe o fue revocada. Revisa que estés mandando la llave completa (zvr_live_...) y que no haya sido revocada en Captación. El intento queda registrado en Solicitudes recibidas aunque la llave sea inválida, con el prefijo que mandaste.

Plan sin API de leads

403 plan_feature_unavailable. La llave es válida, pero el plan de tu organización no incluye la API de leads (el plan Gratis no la trae). Pídele a un Administrador de tu organización que cambie a un plan de pago; en cuanto el cambio se aplique, la misma llave vuelve a funcionar sin generar otra. El intento queda registrado en Solicitudes recibidas. Nada se escribió y la Idempotency-Key no queda reservada.

Ruta no encontrada

404 not_found. La ruta no existe. Las rutas válidas son GET /v1, GET /v1/openapi.json y POST /v1/leads. Revisa que no falte el prefijo /v1 y que no sobre una barra o un parámetro.

Método no permitido

405 method_not_allowed. La ruta existe pero no con ese método (por ejemplo, un GET /v1/leads). La cabecera Allow lista los métodos válidos. OPTIONS también responde 405: no hay preflight porque no hay CORS.

Conflicto de idempotencia

409 idempotency_conflict. Ya usaste esa Idempotency-Key en las últimas 24 horas con un cuerpo distinto. Una llave corresponde a un envío; si el contenido cambió, es otro envío y necesita otra llave. Detalle en Idempotencia.

Solicitud en curso

409 idempotency_in_progress. Otra solicitud con la misma Idempotency-Key y el mismo cuerpo sigue procesándose (típico cuando dos procesos reintentan a la vez). Trae Retry-After: 1: espera un segundo y reintenta; recibirás la respuesta original con "replay": true.

Cuerpo demasiado grande

413 payload_too_large. El cuerpo pasa de 64 000 bytes. Lo normal es un mensaje o unos extras enormes; recorta lo que no sea del lead. La conexión se cierra al responder.

Tipo de contenido no soportado

415 unsupported_media_type. La cabecera Content-Type no es application/json. Un application/x-www-form-urlencoded (el envío por defecto de un <form> HTML) o un text/plain caen aquí. Serializa a JSON y manda la cabecera correcta.

Propiedad no encontrada

422 property_not_found. El identificador de propiedad no corresponde a ninguna propiedad de tu organización. Revisa el código en el dashboard (la ficha de la propiedad muestra su código ZVR-#### y tu código propio) y que la propiedad no esté archivada. field es propiedad. Un intento fallido no reserva la Idempotency-Key.

Modelo no encontrado

422 unit_type_not_found. Alguno de los Modelos indicados no existe en esa propiedad. Cada entrada de calificacion.modelos se busca solo entre los Modelos de la propiedad que mandaste, por id o por nombre exacto (sin distinguir mayúsculas, pero sin coincidencias aproximadas); la API se detiene en el primero que no encuentra y no guarda nada. field señala esa entrada por su posición, por ejemplo calificacion.modelos[1] para la segunda (o calificacion.modelo si usaste la forma corta de un solo Modelo). Revisa el nombre o el id en el dashboard: la ficha de la propiedad muestra sus Modelos en la tarjeta Modelos. Si la propiedad no tiene Modelos todavía, omite modelos. Un intento fallido no reserva la Idempotency-Key.

Límite de solicitudes

429 rate_limited. Pasaste de 60 solicitudes por minuto con esta llave. Retry-After dice cuántos segundos esperar y las cabeceras X-RateLimit-* te dan el estado de la ventana. Un reintento en bucle sin espera (un Zapier que reintenta sin pausa) es la causa habitual. Detalle en Límites.

Error interno

500 internal_error. Algo falló de nuestro lado al guardar el lead. Reintenta con la misma Idempotency-Key: si el lead alcanzó a crearse, recibirás su respuesta; si no, se creará ahora. Si persiste, escríbenos con el request_id.

Servicio temporalmente no disponible

503 temporarily_unavailable. La base de datos no respondió al consultar la llave o la idempotencia. Trae Retry-After: 5. Nada se escribió; reintenta después de esos segundos con la misma Idempotency-Key.

En esta página