Skip to content

Errores ​

La API devuelve errores con un JSON estandarizado:

json
{
  "error":   "validation_failed",
  "message": "email no puede estar en blanco",
  "errors":  { "email": ["no puede estar en blanco"] }
}
  • error es un código estable que debes usar para tomar decisiones en código.
  • message es texto en español apto para mostrar al usuario final.
  • errors (opcional, solo en 422 validation_failed) trae los errores por campo.

Códigos por status HTTP ​

400 Bad Request ​

errorCuándo
invalid_idEl parámetro :id no es un ObjectId válido.

401 Unauthorized ​

errorCuándo
invalid_keyEl header Authorization falta, está mal formado, la key no existe, no matchea el digest, o fue revocada. Devolvemos el mismo error en todos esos casos para no filtrar información.

403 Forbidden ​

errorCuándo
origin_not_allowedEl Origin/Referer no matchea con la lista de dominios permitidos del account.
insufficient_scopeLa key autenticada no tiene el scope que requiere ese endpoint. El campo required te dice cuál falta.
module_not_enabledEl módulo opt-in que cubre ese endpoint no está activado para la empresa (p. ej. Facturación en /sales/:id/invoice). Se activa desde la aplicación, no por API.

404 Not Found ​

errorCuándo
not_foundEl recurso con ese :id no existe, o existe pero pertenece a otra empresa (deliberadamente devolvemos el mismo error para no filtrar IDs entre tenants).

422 Unprocessable Entity ​

errorCuándo
validation_failedEl payload no pasa las validaciones del modelo. Mira errors para el detalle por campo.
parameter_missingEl JSON no incluye la llave data o un campo obligatorio en data.<field>.
idempotency_key_reusedEl header Idempotency-Key ya se usó con un body diferente. Reusar la misma key requiere el MISMO body.
not_supported_yetEl endpoint existe pero esta acción no está soportada en Fase 1 (ej. POST /automations).
invalid_metadataEl metadata se salió de su forma: más de 50 claves, una clave de más de 40 bytes, un valor de más de 500 bytes, o un objeto/lista anidados. Ver metadata.
period_lockedoccurred_at cae en un mes que la contabilidad ya cerró. La llave no puede saltarse un cierre — la respuesta trae year y month.
already_invoicedLa venta ya tiene CFDI timbrado. Para corregirlo, sustituye en vez de volver a emitir.
sale_without_taxLa venta tiene conceptos sin IVA, que un CFDI no admite salvo exentos o tasa 0%.
no_emitterLa empresa no tiene completos sus datos fiscales o sus sellos digitales (CSD).
customer_no_rfcEl cliente de la venta no tiene RFC. Sin cliente, la venta se timbra a público en general.

409 Conflict ​

errorCuándo
duplicate_referenceUn update intentó poner un metadata.external_ref que otro registro de la empresa ya tiene. En un create, esto no es un error: se devuelve 200 con el recurso que ya existía (ver idempotencia).

413 Payload Too Large ​

errorCuándo
idempotency_body_too_largeBodies > 100 KB no se pueden idempotency-key. Quita el header o mándalo en partes.

426 Upgrade Required ​

errorCuándo
https_requiredEn producción solo aceptamos HTTPS. Cambia a https://.

429 Too Many Requests ​

errorCuándo
rate_limitedExcediste el cap de 600 req/min para tu API key. Espera lo que indica el header Retry-After.

Ver: Rate limiting.

Mejores prácticas ​

  • Lee error, no message: message puede cambiar de redacción; error es contrato estable.
  • No diferencies 401: nunca te diremos si una key existe pero está mal o si jamás existió. Trata cualquier 401 invalid_key igual: re-emite la key.
  • Reintenta con backoff exponencial solo en 429 o 5xx. Para 4xx el reintento sin cambios no va a ayudar.
  • Usa Idempotency-Key en POST para evitar duplicados en reintentos. Ver Idempotencia.

Hecho con cuidado por Finova.