Solicitudes
Solución de problemas de solicitudes
Dónde mirar cuando una solicitud fue rechazada, una invitación nunca llegó, o un flujo de trabajo sigue esperando un callback que ya ocurrió.
Leer un error
Todo rechazo lleva dos cosas: un code para el tipo de fallo, y un details.reason para la causa concreta. Decide
según el código; lee el motivo para saber qué arreglar. Cuando ayuda, details también nombra el field ofensor,
las claves que se habrían aceptado, o las claves de opción que admite una pregunta de elección.
Los métodos de solicitud usan cuatro códigos: VALIDATION_ERROR (la llamada estaba mal), CONFLICT (la solicitud
está en el estado equivocado, o se reutilizó una clave de idempotencia), NOT_FOUND, y UPGRADE_REQUIRED (un
límite de plan o la asignación mensual). Llamar demasiado rápido devuelve RATE_LIMITED en su lugar, con
retryAfterMs — consulta el límite de frecuencia.
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "No field with key \"company\".",
"details": { "reason": "UNKNOWN_FIELD_KEY", "field": "prefill.company", "validKeys": ["company_name", "company_size"] }
}
}Motivos que puedes ver
Hacer bien la llamada
| Motivo | Qué hacer |
|---|---|
| FORM_NOT_PUBLISHED | Publica el formulario. Una solicitud fija una versión publicada, así que tiene que existir una. |
| UNKNOWN_FIELD_KEY | No hay ningún campo con esa clave, o pertenece al otro grupo. Toda clave de contexto debe ser un campo oculto en el formulario publicado; envía las claves de formato libre en metadata. Comprueba fields.list; validKeys lista las aceptadas. |
| CONTEXT_KEY_NOT_HIDDEN_FIELD | Enviaste una pregunta visible — o un campo calculado — en context. Las preguntas visibles van en prefill; los campos calculados no se pueden establecer en absoluto. |
| INVALID_PREFILL_VALUE | Forma incorrecta para ese tipo de pregunta. expectedType indica lo que se esperaba; para preguntas de elección, envía la clave de la opción, no la etiqueta; una matriz toma { "row_key": "column_key" }. expectedType "not_prefillable" significa que el campo no acepta un valor de quien llama — un archivo, firma, pago, cita o campo calculado. |
| READONLY_REQUIRES_PREFILL | Una clave bloqueada no tiene valor. Toda clave en readonly también debe estar en prefill. |
| READONLY_REQUIRED_EMPTY | Un campo obligatorio está bloqueado con un valor vacío — el destinatario nunca podría enviarlo. Suministra un valor o deja de bloquearlo. |
| LANGUAGE_NOT_PUBLISHED | Ese idioma no está publicado en la versión actual. validKeys lista los que sí lo están. |
| INVALID_REMINDER_SCHEDULE | No se pudo leer un tiempo, el mismo tiempo aparece dos veces, o hay más de cinco pasos. Usa días, horas o minutos enteros positivos: 2d, 12h, 30m. |
| EXPIRY_OUT_OF_RANGE | expiresAt está en el pasado o a más de 365 días. |
| CALLBACK_URL_NOT_ALLOWED | La URL no es HTTPS, lleva credenciales, o resuelve a una dirección privada. Localhost no funcionará — usa un túnel. |
| DOMAIN_NOT_ALLOWED | Ese dominio personalizado no está activo, o pertenece a otro espacio de trabajo. |
| INVALID_DOCUMENT_TARGET | El formulario no tiene ningún bloque de Documentos, o tiene más de uno y no indicaste cuál con field. validKeys lista las claves de los bloques. |
| DOCUMENT_NOT_UPLOADED | La subida se reservó pero los bytes nunca llegaron. Haz primero un PUT del archivo a su uploadUrl. |
| DOCUMENT_INVALID | Los bytes subidos no coinciden con el tamaño, tipo o sha256 declarados en documents.create, o el tipo no es un PDF ni una imagen. |
| DOCUMENTS_TOO_MANY | El bloque mostraría más de 20 documentos, contando los de autor. |
| DOCUMENTS_TOO_LARGE | Una solicitud puede llevar 100 MB de documentos en total, y 25 MB por documento. |
| SCOPE_REQUIRED | Listar solicitudes necesita un espacio de trabajo o un formulario para acotar la lista. |
| RECIPIENT_EMAIL_REQUIRED | La entrega por correo o los recordatorios necesitan recipient.email. |
| UPGRADE_REQUIRED | El plan no incluye la función — los recordatorios son Pro o Business, y una cuenta de invitado no puede enviar invitaciones por correo. |
| FREE_INVITATIONS_USED | Esta cuenta Free ha gastado sus 10 invitaciones gratis, para siempre. Crea la solicitud con "delivery": "none" y envía el enlace tú mismo, o actualiza a Pro. |
| MONTHLY_ALLOWANCE_REACHED | El espacio de trabajo ha gastado la asignación de este mes para envíos y solicitudes. Cada solicitud cuesta una unidad al crearse, se responda o no. Las solicitudes que ya creaste todavía se pueden responder; las nuevas esperan al día 1 o a una mejora de plan. |
Actuar sobre una solicitud existente
| Motivo | Qué hacer |
|---|---|
| REQUEST_NOT_FOUND | No hay ninguna solicitud con ese id en un espacio de trabajo al que este token pueda acceder. |
| REQUEST_NOT_PENDING | Ya está completada, expirada o cancelada. No puedes recordar ni cancelar una solicitud finalizada. |
| REMINDER_TOO_SOON | Se envió un recordatorio manual hace menos de diez minutos. details.retryAfterMs indica cuánto esperar. |
| REMINDER_CAP_REACHED | Esta solicitud ya ha tenido los ocho recordatorios que le corresponden, manuales y programados juntos. |
| TEST_REQUEST | Le pediste a formbase que enviara por correo una solicitud de prueba. Nunca se envía nada por correo para una — abre su enlace tú mismo en su lugar. |
| REQUEST_NOT_TERMINAL | Pediste reproducir un callback de una solicitud que sigue pendiente. Todavía no hay nada que reproducir. |
| NO_CALLBACK_TO_REPLAY | La solicitud se creó sin callbackUrl. |
| IDEMPOTENCY_CONFLICT | Esa clave se usó para un cuerpo distinto. Usa una clave nueva, o envía de nuevo el cuerpo original sin cambios. |
La invitación nunca llegó
Abre la solicitud en la página de Solicitudes y lee la cronología. La primera línea de invitación te dice en qué caso estás.
| La cronología dice | Qué significa | Qué hacer |
|---|---|---|
| Invitación en cola | Aceptada, aún no enviada. | Dale un minuto. Si sigue en cola, comprueba que la solicitud tiene un correo de destinatario. |
| Invitación entregada | Entregada al proveedor de correo. | Pídeles que revisen el correo no deseado. Enviar desde tu propio dominio ayuda — consulta dominios de correo personalizados. |
| Invitación fallida | formbase no pudo enviarla — o el proveedor la rebotó, o el destinatario la marcó como spam. | Lee deliveryStatus en requests.get: "failed" suele ser un problema de plan o de dirección, así que arréglalo y envía un recordatorio, que lleva el mismo enlace (en Free, copia el enlace y envíalo tú mismo). "bounced" significa que la dirección es incorrecta o está muerta — crea una nueva solicitud para la dirección correcta; recordar no ayudará. |
No hay ninguna entrada en la cronología
Entonces nunca se pidió ningún correo. La solicitud se creó con delivery: “none” — entrega el enlace tú mismo, o crea una
nueva solicitud con delivery: “email”.
Las invitaciones y los recordatorios comparten un cupo de diez correos al día por formulario y dirección de destinatario, y una solicitud nunca escribe a su destinatario más de nueve veces en toda su vida — una invitación y hasta ocho recordatorios.
El callback nunca aterrizó
La sección Callback del panel de la solicitud muestra la URL y el resultado. Callback fallido tras N intentos significa que formbase lo intentó y se rindió — ocho intentos a lo largo de unas cuatro horas.
Comprueba la URL. Se muestra en el panel. La URL de reanudación de una herramienta de flujos de trabajo pertenece a una ejecución, y una ejecución que se borró o se recreó ya no responde en ella.
Comprueba qué devolvió tu endpoint. Cualquier cosa fuera de 2xx es un fallo. Un 4xx que no sea 408 ni 429 detiene los reintentos de inmediato — formbase lo interpreta como “tu endpoint rechazó esto”, y reenviar los mismos bytes no puede cambiarlo.
Arregla el receptor y luego pulsa Reproducir. El mismo payload sale de nuevo con el mismo id de evento, así que un receptor que desduplica está a salvo.
¿Falla la comprobación de la firma?
Casi siempre es el cuerpo bruto. Si analizas el JSON y lo reserializas antes de hashearlo, los bytes difieren y la firma nunca coincidirá. Aplica el hash al cuerpo exactamente como llegó. La otra causa habitual es un secreto de firma regenerado que el receptor aún no ha recogido — no hay periodo de gracia.
Otras cosas con las que te puedes topar
El destinatario dice que el enlace muestra un aviso, no el formulario. La solicitud está en un estado final — completada, expirada o cancelada. Esa es la página de resultado. Crea una nueva solicitud si necesitan otro intento.
Una automatización dejó de coincidir después de una edición — una respuesta desapareció del callback, o
requests.createempezó a rechazar una clave conUNKNOWN_FIELD_KEY. Una clave de campo publicada desapareció: alguien la reescribió, o eliminó la pregunta y añadió una nueva en su lugar. Cambiar el título es seguro; ninguna de esas dos cosas lo es. Escribe la clave antigua en el campo (icono de claves de la barra de herramientas → Claves) y vuelve a publicar. Publicar avisa antes de que esto ocurra — consulta Cuando una clave publicada está a punto de desaparecer.El precompletado de una subida de archivo o una firma se rechaza. Eso no puede suministrarlo quien llama —
fields.listlos marcaprefillable: false.Aparecieron dos solicitudes para una misma ejecución de flujo. La ejecución se reintentó sin un
idempotencyKey. Pasa el id de ejecución como clave.