BunnyDoc
APIAPI de firma electrónica

Errores

Todos los errores que puede devolver la API de firma electrónica, con un código legible por máquina y estable sobre el que ramificar.

Todas las respuestas de error tienen la misma forma. Lee error.code: es un valor estable y legible por máquina. El message es para personas y puede cambiar en cualquier momento, así que nunca ramifiques según el texto del mensaje.

Forma del error
{
  "error": {
    "code": "unknown_signer_role",
    "message": "One or more recipient roles do not match this template.",
    "details": { },
    "reference": "0190f3a2-7b6c-7e21-9a3f-2c9b1d4e5f60"
  }
}
CampoSiempre presentePara qué sirve
codeSíEl valor estable sobre el que ramificar. Abajo están todos los posibles.
messageSíExplicación legible para personas. Puede cambiar sin aviso.
detailsNoContexto estructurado, cuando hay alguno; ver más abajo.
referenceNoUn id de soporte para los fallos que registramos en el servidor (5xx y 422).

details

Solo aparece cuando hay algo útil que decir. Dos casos merecen tratamiento explícito:

403 insufficient_scope
{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key is missing the required scope \"envelopes:send\".",
    "details": { "required_scope": "envelopes:send", "granted_scopes": ["templates:read"] }
  }
}
429 rate_limited
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and retry after the indicated interval.",
    "details": { "retry_after": "15 minutes" }
  }
}

Usa la cabecera Retry-After, no details.retry_after

details.retry_after es una cadena legible para personas ("15 minutes", "42 seconds") pensada para logs y mensajes de error: no la parsees. Todas las respuestas 429 incluyen además la cabecera estándar Retry-After, que es un número entero de segundos. Usa la cabecera para tu espera progresiva.

reference

Un UUID que identifica la entrada de log del servidor para ese fallo. Aparece en los errores que persistimos (5xx y 422) y no está en los errores de autenticación o validación que no generan log en el servidor.

Guárdalo en tus logs. Cuando nos reportes un problema, citar el reference nos permite encontrar el fallo exacto con una sola consulta en lugar de pedirte que lo reproduzcas.

Códigos de error

HTTPerror.codeSignificado
401missing_api_keyFalta la cabecera X-API-Key en la petición de token.
401invalid_api_keyLa clave es desconocida, revocada, caducada o no es de modo real.
401missing_tokenNo se envió el token Authorization: Bearer.
401invalid_tokenEl token está mal formado o caducado. Solicita uno nuevo.
401key_revokedLa clave tras este token fue revocada: sus tokens ya no funcionan.
403insufficient_scopeLa clave no incluye el scope que requiere este endpoint.
403forbiddenEl propietario de la clave carece del permiso subyacente, o la función (acceso a la API, webhooks) no está en tu plan.
403signing_links_disabledEl sobre no comparte enlaces de firma con el remitente.
402quota_exceededNo quedan solicitudes de firma por API (al enviar).
403quota_exceededSe alcanzó un límite de recursos: el de contactos o el de endpoints de webhook.
404template_not_foundNo existe ninguna plantilla con ese id en tu empresa.
404envelope_not_foundNo existe ningún sobre con ese id en tu empresa.
404webhook_not_foundNo existe ninguna suscripción de webhook con ese id en tu empresa.
422unknown_signer_roleUn rol de destinatario no coincide con la plantilla, o se proporcionó un rol bloqueado.
422sender_not_foundsender_email no es un usuario activo con asiento de firma electrónica en tu empresa.
422sender_fields_incompleteEl propio remitente de la plantilla ("Me") tiene campos obligatorios sin valor, así que el sobre no puede salir.
400 422validation_failedEl cuerpo está mal formado, falta un campo obligatorio, se supera un límite de longitud, o contiene un placeholder desconocido o un enlace engañoso.
429rate_limitedDemasiadas peticiones: espera y reintenta.
5xxsend_failedEl sobre se creó pero no pudo enviarse, así que se descartó. No se entregó nada.
500internal_errorAlgo falló de nuestro lado. Se puede reintentar.

Por qué algunos errores son deliberadamente imprecisos

En el endpoint de token, "clave inexistente", "revocada", "caducada" y "no de modo real" devuelven todos el mismo cuerpo 401. Del mismo modo, una plantilla de otra empresa y una que no existe devuelven ambas 404 template_not_found. Es intencionado: un error más específico permitiría a alguien sondear qué ids o claves existen.

Cómo resolver sender_fields_incomplete

Este sorprende, porque la petición es perfectamente válida. Significa que la plantilla tiene campos asignados a su propio rol de remitente ("Me") que son obligatorios y están vacíos, así que no hay un documento completo que enviar.

La API rellena los campos del remitente automáticamente con lo que esté guardado en la plantilla; no puede inventar valores. Arréglalo en la plantilla, no en tu petición:

  • da un valor a esos campos del remitente en la plantilla,
  • márcalos como opcionales, o
  • elimínalos.

Después repite la misma llamada.

Cómo gestionar bien los errores

  • Ramifica según error.code, nunca según message.
  • Reintenta 5xx, 429 y errores de red con espera progresiva, respetando la cabecera Retry-After en un 429. No reintentes los demás 4xx: la petición nos llegó y fue rechazada; corrige la petición.
  • Renueva ante 401 invalid_token intercambiando tu clave por un token nuevo y reintenta una vez. Si recibes key_revoked, la clave se revocó: carga la clave de reemplazo en lugar de reintentar.
  • Trata quota_exceeded como una señal del plan, no como un error transitorio: se resuelve cuando el periodo se reinicia o se mejora tu plan. Reintentar no sirve y, al enviar, significa que no se entregó nada.
  • send_failed significa que no salió nada. El sobre se elimina, así que un reintento crea uno nuevo en lugar de duplicar una entrega.
  • Registra reference siempre que esté presente.

En esta página