Reintentos de SMS transaccionales: cuándo repetir, detener o revisar un envío
Una política de reintentos de SMS transaccionales debe decidir con evidencia técnica, ventana de utilidad y riesgo de duplicado. Este marco separa el reintento de transporte del reenvío de negocio y define cuándo detenerse.

El problema: un fallo técnico no siempre justifica otro SMS
Una política de reintentos SMS transaccionales establece qué hacer cuando el resultado de un envío no es concluyente o indica un problema. Su objetivo no es maximizar el número de intentos, sino maximizar la probabilidad de que un mensaje todavía útil llegue sin crear duplicados, confusión para el destinatario ni tráfico innecesario.
El punto de partida es distinguir los estados técnicos disponibles. La aceptación de una solicitud por una plataforma, la aceptación posterior por un carrier y una entrega reportada son eventos diferentes. Por ejemplo, un estado equivalente a «sent» puede significar que un carrier upstream ha aceptado el mensaje, no que este haya llegado al terminal.
Por ello, un timeout de una integración, una respuesta tardía o una actualización de estado incompleta no deben transformarse automáticamente en un nuevo SMS. Antes de repetir, el sistema debe determinar si el primer mensaje pudo haberse aceptado o seguir en proceso.
- No use la ausencia inmediata de un DLR como prueba de fallo definitivo.
- No equipare la aceptación por proveedor o carrier con recepción confirmada en el teléfono.
- No trate todo estado de error como una causa transitoria.
- No priorice el volumen de reintentos sobre la utilidad del mensaje y la experiencia del destinatario.

Separe tres decisiones: transporte, negocio y cierre
Un diseño robusto separa el mensaje lógico del intento técnico. El mensaje lógico es la intención de negocio, como confirmar una operación, avisar de un cambio o entregar un código de un solo uso. Un intento técnico es una ejecución concreta para transportar esa intención mediante una conexión, proveedor o ruta disponible.
El reintento de transporte consiste en volver a intentar la ejecución técnica del mismo mensaje lógico bajo reglas acotadas. Puede ser apropiado cuando existe una causa documentada y potencialmente transitoria, el mensaje sigue siendo útil y el riesgo de que ya exista un envío activo es controlado.
El reenvío de negocio es distinto: genera una nueva comunicación para el destinatario. Debe estar gobernado por reglas de producto y experiencia, no por un error de red aislado. Por ejemplo, solicitar un nuevo OTP puede invalidar el anterior, modificar la expiración y requerir supresión de solicitudes repetidas.
El cierre definitivo marca que no se enviarán más intentos para esa unidad lógica. Puede producirse por caducidad, evidencia de rechazo definitivo, agotamiento del límite de intentos, alto riesgo de duplicado o necesidad de revisión operativa.
- Mensaje lógico: la notificación que el negocio desea comunicar.
- Intento técnico: una ejecución individual para entregar ese mensaje lógico.
- Reintento de transporte: nueva ejecución técnica bajo la misma intención.
- Reenvío de negocio: nueva notificación, potencialmente con nuevo contenido o nueva validez.
- Cierre: decisión explícita de no seguir enviando.

Defina primero la ventana de utilidad
La primera condición de cualquier política debe ser la ventana de utilidad: el intervalo durante el cual recibir el SMS sigue teniendo valor para el destinatario y para el proceso. Un aviso de evento, una confirmación de operación y un OTP pueden tener ventanas muy diferentes. No existe una duración universal que sirva para todos los casos.
La caducidad técnica configurada en una plataforma de mensajería puede limitar cuánto tiempo permanece un mensaje en cola antes de dejar de enviarse. Sin embargo, esa configuración no sustituye la decisión de negocio. El sistema emisor debe imponer una fecha u hora de caducidad coherente con el propósito del mensaje.
Cuando la ventana ha terminado, la acción prudente es detener los reintentos. Entregar tarde una alerta puede resultar inútil; entregar tarde un OTP puede causar confusión o inducir al usuario a introducir un código que ya no es válido.
- Defina una caducidad por tipo de mensaje antes de configurar esperas y número de intentos.
- Evalúe la utilidad desde la perspectiva del destinatario, no solo desde la disponibilidad de la ruta.
- Impida que un intento se inicie si ya no queda tiempo suficiente para que el mensaje cumpla su propósito.
- Registre la caducidad como motivo de cierre, no como un fallo técnico genérico.
Clasifique el resultado antes de decidir
Una política operativa necesita una clasificación propia, estable y auditable. No debe depender únicamente de las etiquetas de estado de una integración concreta. El objetivo es traducir el resultado disponible a una decisión: detener, esperar, reintentar de forma controlada o revisar.
Los rechazos definitivos son resultados para los que la evidencia disponible indica que repetir de inmediato no resolverá el problema. Un fallo potencialmente transitorio es aquel en el que la causa documentada permite considerar un nuevo intento dentro de la ventana de utilidad. La aceptación sin resultado final requiere espera y conciliación antes de enviar otra copia. El estado incierto exige máxima prudencia porque el primer mensaje puede haber avanzado aunque la aplicación no haya recibido confirmación concluyente.
Un estado equivalente a «undelivered» aporta evidencia de que el mensaje no fue entregado, pero no determina una causa única. Puede haber múltiples motivos, incluidos filtrado de contenido por carrier o disponibilidad del terminal. Por tanto, tampoco convierte automáticamente el reintento en la acción correcta.
- Rechazo definitivo: detener y clasificar para revisión o corrección.
- Fallo potencialmente transitorio: evaluar un reintento limitado.
- Aceptación sin resultado final: esperar una ventana de conciliación.
- Estado incierto: no duplicar sin comprobar referencias, eventos tardíos y caducidad.
- Entrega reportada: cerrar el flujo técnico, sin asumir más evidencia de la disponible.
No confunda DLR, aceptación y recepción en el terminal
Los recibos de entrega y los callbacks de estado son elementos valiosos para operar, pero deben interpretarse según lo que realmente acreditan. Una plataforma puede informar que aceptó la solicitud; un estado de envío puede indicar aceptación por un carrier upstream; y un DLR puede comunicar un resultado posterior. Son señales operativas distintas.
La recepción independiente en el terminal no debe inferirse solo porque un proveedor haya aceptado una solicitud o porque exista un estado de envío hacia la red. Incluso cuando hay un estado de entrega reportada, la política debe describirlo con precisión como evidencia reportada por la cadena de mensajería disponible, no como una prueba absoluta de lectura o actuación por el usuario.
Esta distinción es esencial para evitar dos errores opuestos: repetir un mensaje que probablemente ya avanzó, o declarar éxito de negocio cuando únicamente se conoce un estado de transporte.
- Conserve el significado original de cada estado recibido.
- Modele por separado éxito de transporte, entrega reportada y éxito de negocio.
- Evite usar un DLR como prueba de consentimiento, identidad, titularidad del número o lectura del mensaje.
- Defina qué evidencias son suficientes para cerrar cada tipo de flujo.
Criterios operativos para autorizar un reintento
Un reintento debe requerir condiciones acumulativas, no una única señal de error. Como mínimo, evalúe la causa documentada, el tiempo ya transcurrido, la criticidad del mensaje, el riesgo de duplicación y las restricciones aplicables al destino o al remitente.
La causa debe ser interpretable. Si no hay una causa clara o existe una referencia de proveedor pendiente, trate el caso como incierto y priorice la conciliación. El tiempo transcurrido debe compararse con la ventana de utilidad y con un período de espera diseñado para permitir actualizaciones tardías. La criticidad puede justificar una revisión más rápida, pero no elimina el riesgo de duplicar una notificación.
También conviene considerar si el contenido, el identificador de remitente o el destino pueden estar relacionados con el resultado. Un error de entrega no demuestra por sí mismo cuál de esos elementos causó el problema. Si hay un patrón persistente, corresponde revisar la configuración, el contenido, los eventos y la conectividad, en lugar de repetir indefinidamente.
- ¿La causa disponible está documentada y es compatible con un comportamiento transitorio?
- ¿El mensaje sigue dentro de su ventana de utilidad?
- ¿Existe un identificador de proveedor o una actualización pendiente que pueda confirmar el estado?
- ¿El destinatario podría recibir dos copias si se reintenta ahora?
- ¿El mensaje es suficientemente crítico para justificar el riesgo residual?
- ¿Existe una restricción recurrente por destino, remitente o contenido que requiera revisión?
Diseñe una escalera de reintentos con condiciones explícitas de parada
Una escalera de reintentos debe estar definida por tipo de mensaje, no como una regla global. Debe especificar el máximo de intentos técnicos, la espera entre ellos, la caducidad absoluta, las causas admisibles y las condiciones de parada. Si una de estas piezas no está definida, el comportamiento quedará expuesto a decisiones improvisadas.
Las esperas deben permitir que se reciban eventos y callbacks tardíos antes de generar otra copia. Los callbacks HTTP pueden llegar desordenados y con variaciones de latencia; algunas transiciones pueden ocurrir muy próximas entre sí. Por eso, una automatización no debería decidir solo a partir del primer evento observado ni del primer timeout local.
El límite de intentos debe ser bajo y razonado para el caso de uso. Si la degradación persiste, más repeticiones pueden aumentar duplicados, costes operativos y frustración sin corregir la causa. El último resultado debe llevar a cierre o revisión, no a un ciclo indefinido.
- Establezca un máximo de intentos técnicos por mensaje lógico.
- Defina una espera mínima de conciliación antes de cada nuevo intento.
- Aplique una caducidad absoluta que prevalezca sobre cualquier reintento pendiente.
- Permita reintentos solo para causas previamente aprobadas.
- Detenga el flujo ante entrega reportada, rechazo definitivo, caducidad, riesgo alto de duplicado o agotamiento del límite.
- Envie los casos repetidos o no concluyentes a revisión operativa.
OTP: coordine entrega, expiración y seguridad
Los OTP y otros secretos de autenticación requieren una política más estricta. Un secreto fuera de banda es de vida corta y se entrega por un canal independiente. Si el código ya ha caducado, un reintento de transporte no aporta valor y puede empeorar la experiencia.
La validez del código, el límite de intentos de autenticación y la supresión de solicitudes repetidas deben funcionar como un conjunto. Cuando se genera un código nuevo, el sistema debe decidir explícitamente qué ocurre con el anterior, qué intento técnico sigue asociado a cada código y qué mensajes quedan suprimidos. No deje que la capa de transporte continúe reenviando un código que el backend de autenticación ya considera inválido.
Los flujos por PSTN/SMS también requieren alternativas de autenticación y controles de riesgo adecuados al contexto. La cobertura limitada, cambios de dispositivo o SIM, portabilidad del número y comportamientos anómalos son ejemplos de señales que pueden justificar controles adicionales. Reenviar SMS no debe convertirse en la respuesta automática ante una degradación persistente.
Las respuestas de cara al usuario deben ser prudentes, especialmente en autenticación y recuperación de cuenta. Evite mensajes que revelen innecesariamente si una cuenta existe o cuál es su estado.
- Vincule cada OTP a una caducidad de negocio inequívoca.
- No reintente enviar un OTP después de su expiración.
- Controle solicitudes repetidas para reducir fatiga y tráfico innecesario.
- Aplique limitación de tasa a los intentos de autenticación cuando corresponda.
- Defina alternativas de autenticación para los casos en que SMS no sea adecuado o no esté disponible.
- Mantenga respuestas externas genéricas cuando sea necesario para evitar enumeración de cuentas.
Preguntas frecuentes
¿Un estado de envío confirma que el SMS llegó al móvil?
No necesariamente. Un estado de envío puede indicar que un carrier upstream aceptó el mensaje. Debe distinguirse de un estado de entrega reportada y, a su vez, de la recepción o lectura por el destinatario.
¿Cuándo debe detenerse un reintento de SMS transaccional?
Debe detenerse cuando el mensaje ya no es útil, hay evidencia de rechazo definitivo, existe un riesgo elevado de duplicado, se alcanzó el límite definido de intentos o la causa requiere revisión en lugar de otra repetición.
¿Debe reenviarse automáticamente un SMS tras un timeout?
No. Un timeout puede dejar un resultado incierto: el primer intento pudo haber sido aceptado o puede seguir generando actualizaciones. Antes de reenviar, concilie el identificador disponible, espere eventos tardíos y compruebe la ventana de utilidad.
¿Qué datos mínimos deben registrarse por intento?
Registre un ID interno del mensaje lógico, clave de idempotencia, número de intento, hora de creación y de decisión, proveedor o conexión utilizada, identificador del proveedor, estado, código de error cuando exista, causa clasificada, caducidad y decisión posterior.
¿Un OTP debe reenviarse mientras siga siendo válido?
Solo si la política lo permite y el riesgo de duplicado está controlado. La decisión debe coordinarse con la expiración del código, la supresión de solicitudes repetidas y los límites de autenticación. No conviene enviar un código que ya ha caducado o que ha sido invalidado por un código más reciente.
Fuentes consultadas
- NIST SP 800-63B-4: autenticadores fuera de banda y uso de PSTNNational Institute of Standards and Technology (NIST)
- Twilio Message Resource: estados, aceptación por carrier, intentos y período de validezTwilio
- Twilio: seguimiento de estados y callbacks de mensajes salientesTwilio
- OWASP Authentication Cheat SheetOWASP Foundation