Comprobación de teléfono, OTP y verificación de identidad: ¿qué pregunta responde cada una?
Un flujo de registro tiene un campo de teléfono y alguien del equipo pide que se «verifique». Esa palabra abarca tres preguntas distintas. Una comprobación de teléfono describe el número: si tiene un formato correcto, si es válido y qué tipo de línea podría ser. Un OTP comprueba si la persona que escribe puede recibir un código por un canal en ese momento. Una verificación de identidad evalúa una afirmación sobre una persona. Ninguna responde a la pregunta de otra. Una línea móvil no demuestra quién es su titular, un código entregado no establece la identidad y un resultado Approved no concede permisos por sí solo. Este artículo te ayuda a decidir qué prueba necesita tu registro y muestra cómo el ejemplo sintético descargable de GridZen mantiene separadas las tres.
curl https://gridzen.ai/console/api/quickstart/trial \
-H 'Content-Type: application/json' \
-d '{"task": "signup_phone", "scenario": "success"}'La decisión: nombra la pregunta antes de elegir la prueba
Empieza por escribir qué debe establecer el paso de registro. Si solo quieres detectar errores de escritura y entradas mal formadas antes de crear la cuenta, necesitas propiedades del número. Si necesitas saber que la persona puede recibir mensajes en ese número, necesitas acceso al canal, es decir, un OTP enviado mediante un proveedor que tú operas. Si una acción posterior, como permitir que un vendedor publique productos, depende de quién es la persona, necesitas una afirmación de identidad verificada mediante un onboarding alojado y, después, tus propias reglas de negocio. El error habitual es interpretar una señal débil como una más fuerte: tratar un número móvil válido como prueba de titularidad o tratar Approved como un permiso. Cada prueba tiene sus propios modos de fallo, reintentos y responsables, así que mantenlas en campos y rutas de código separados.
Lo que implementa realmente el ejemplo descargable
El ejemplo verification_delivery de la guía es un script de Python 3.10+ sin dependencias. No necesita credenciales ni hace llamadas de red. Su comando phone tiene cuatro ramas: normal, unknown, provider_failure y otp. Su comando identity usa un archivo SQLite local para guardar sesiones y eventos de fixture. Toda salida incluye mode: synthetic_fixture. Las ramas de teléfono siempre devuelven otp_sent: false y live_line_type_available: false. La ruta de identidad solo acepta eventos sintéticos cuyo origen sea fixture_callback. No tiene un verificador de firmas de producción. Cualquier permiso que registre es una marca local del fixture, y cada lectura de identidad indica live_permission_changed: false. Esta descarga de cuatro ramas es distinta de la prueba HTTP anónima de tres escenarios; no interpretes los resultados de una como si fueran de la otra. Todo lo demás de este artículo que vaya más allá de estas salidas es un diseño de aplicación propuesto para tu propio código.
Ejemplo hipotético: registro de un vendedor
Imagina un marketplace B2B hipotético. Un nuevo vendedor introduce un número de teléfono. La rama normal devuelve state: simulated, valid: true, line_type: mobile y next: continue_customer_policy. Para tu diseño, eso solo indica que el número parece utilizable. No dice nada sobre titularidad ni alcanzabilidad. Si el equipo quiere una prueba de acceso al canal, la rama otp responde con claridad: state: unsupported, valid: null, line_type: null, next: customer_otp_provider. El código debe venir de tu propio proveedor de OTP. Más adelante, antes de que el vendedor pueda publicar productos, la ruta de identidad crea una sesión. El paso de creación devuelve state: simulated, session: fixture-session, un hosted_link en example.invalid, link_executable: false y next: send_real_provider_link_only_after_authorization. Un evento Approved sintético con policy en true devuelve status: approved, deadline: 60, permission_granted: true y grant_count: 1. En este flujo, el resultado del teléfono, el resultado del OTP y el estado de identidad permanecen cada uno en su propio campo.
Gestión de fallos a cargo del llamador
Un resultado de teléfono desconocido no es un rechazo. La rama unknown devuelve state: unknown con next: review_or_existing_otp. La rama provider_failure devuelve el mismo estado unknown con next: bounded_retry_then_review. Tu diseño debe limitar el número de reintentos y después enviar el registro a revisión, no bloquearlo en silencio. En la parte de identidad, un evento duplicado no cambia nada: la salida sigue en approved con grant_count: 1. Un evento Declined posterior se trata como una corrección. Establece status en declined y permission_granted en false, mientras grant_count se mantiene en 1. Si no llega ninguna decisión antes del plazo, recover marca como expired una sesión que esté en pending, review o unknown. Devuelve permission_granted: false, grant_count: 0, next: review_or_authorized_provider_refresh y provider_polled: false. La expiración ocurre localmente; recover nunca contacta con un proveedor. Un evento cuya sesión o vínculo tenant/subject no coincida se rechaza con BINDING_MISMATCH. Leer una sesión que no existe devuelve SESSION_NOT_FOUND.
Límites de las rutas reales
A fecha de 2026-10-17, las empresas elegibles de EE. UU. y Reino Unido pueden inscribirse por su cuenta en una ruta básica gratuita de teléfono. Solo comprueba formato y validez, con hasta 10 solicitudes por dominio empresarial verificado. No solicita tipo de línea, titularidad, alcanzabilidad ni envío de OTP. También hay disponible una prueba de identidad alojada. Requiere aceptar por separado el anexo de Didit y está limitada a 2 solicitudes por dominio empresarial verificado y 10 solicitudes compartidas de por vida. Un usuario recién aprobado y la acción de negocio resultante del cliente siguen sin verificarse de extremo a extremo. El permiso sintético del fixture no es un permiso de negocio real, y las pruebas anónimas no son una aprobación de producción.
Lista de aceptación
Ejecuta las cuatro ramas de teléfono y confirma que cada una imprime exactamente los valores de state, valid, line_type y next descritos arriba, con otp_sent: false en todos los casos. Confirma que tu registro guarda las propiedades del número, el resultado del OTP y el estado de identidad en campos separados. Confirma que unknown y provider_failure llevan a un reintento limitado o a revisión, nunca a un rechazo automático. Ejecuta python3 -m unittest -v test_delivery y confirma que pasan los casos de duplicado, corrección, expiración y error de vínculo. Confirma que ninguna ruta de código concede un permiso real a partir de un valor del fixture o solo de Approved. Elige por separado una ruta real y autorizada de OTP o de identidad antes de tratar con cualquier usuario real. Si estas comprobaciones encajan con tu tarea, puedes guardar una solicitud de sandbox como siguiente paso.
Ejecutar el ejemplo sintético comprobado
Descargue y extraiga https://gridzen.ai/downloads/verification-delivery.zip, entre en verification_delivery y ejecute con Python 3.10+. El ejemplo local no hace llamadas de red. Use una base nueva para otra prueba de identidad.
python3 delivery.py phone --branch unknown
python3 delivery.py phone --branch provider_failureFuentes y alcance
https://gridzen.ai/guides/phone-otp-identity/ https://gridzen.ai/guides/current-capabilities/ Basado en las fuentes comprobadas y el ejemplo local; las reglas propuestas son recomendaciones de diseño, no comportamiento de producción demostrado. Redacción asistida por IA con revisión independiente.
Probar por separado tres resultados del sandbox Crear una cuenta para continuar la integración
Una descarga no demuestra una ejecución correcta. Los ejemplos locales y el sandbox en línea se prueban por separado.