Plantillas OTP (AUTHENTICATION)
Meta tiene una categoría dedicada para plantillas de verificación con código de un solo uso:AUTHENTICATION. A diferencia de Marketing o Utility, el cuerpo del mensaje lo arma Meta automáticamente — vos solo configurás el botón, los minutos de expiración y si querés agregar el disclaimer de seguridad estándar.
Por qué usar AUTHENTICATION (no UTILITY)
- Aprobación rápida: minutos, no horas. Las plantillas Authentication tienen review acelerado de Meta.
- Más baratas: ~$0.0085 USD por conversación en Colombia vs. ~$0.05 USD para Marketing.
- Botones especializados: COPY_CODE (todos los devices), ONE_TAP (autofill en Android), ZERO_TAP (sin toque, premium).
- Texto auto-generado: Meta arma el body con "_código_ es tu código de verificación. Expira en N minutos. Por tu seguridad, no compartas este código." Vos no escribís ese texto.
Anatomía del payload
Para crear una plantilla OTP, hacé POST /organizations/{orgId}/templates con este shape:
{
"wabaId": "12ba3006-...",
"name": "verificacion_codigo",
"language": "es",
"category": "AUTHENTICATION",
"components": [
{
"type": "BODY",
"add_security_recommendation": "true"
},
{
"type": "FOOTER",
"code_expiration_minutes": "10"
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "OTP",
"otp_type": "COPY_CODE",
"text": "Copiar código"
}
]
}
]
}- BODY: NO lleva
text— Meta lo genera. Soloadd_security_recommendation(string "true"/"false"). - FOOTER:
code_expiration_minutesentre 1 y 90. Meta agrega "Expira en N minutos". - BUTTONS: exactamente uno con
type: "OTP"+otp_typeuno de COPY_CODE / ONE_TAP / ZERO_TAP.
Tipo 1 — COPY_CODE (recomendado para empezar)
El más universal: el usuario toca el botón y el código se copia al portapapeles. Funciona en iOS y Android sin configuración extra.
{
"type": "OTP",
"otp_type": "COPY_CODE",
"text": "Copiar código"
}Tipo 2 — ONE_TAP (autofill en Android)
En dispositivos Android, abre tu app y autollena el campo del código. Requiere que indiques el package_name de tu app y el signature_hash SHA-256 (base64). Si el usuario está en iOS o no tiene la app, cae a COPY_CODE.
{
"type": "OTP",
"otp_type": "ONE_TAP",
"text": "Copiar código",
"autofill_text": "Autocompletar",
"package_name": "com.tuempresa.app",
"signature_hash": "abc123def...="
}Para sacar el signature hash usá la herramienta de hashing de Meta o el comando apksigner.
Tipo 3 — ZERO_TAP (sin toque, premium)
Tu app recibe el código automáticamente, el usuario no necesita ni siquiera tocar el botón. Requiere acuerdo previo con Meta (Zero-Tap Authentication terms) y el flag zero_tap_terms_accepted: true en el payload.
{
"type": "OTP",
"otp_type": "ZERO_TAP",
"text": "Copiar código",
"autofill_text": "Autocompletar",
"package_name": "com.tuempresa.app",
"signature_hash": "abc123def...=",
"zero_tap_terms_accepted": true
}Enviar la plantilla aprobada
Una vez Meta aprueba (status APPROVED), enviás un OTP con POST /organizations/{orgId}/messages. Lo más simple es pasar templateId + variables — Mosend resuelve los components y arma el payload de Meta por vos.
{
"phoneNumberId": "...",
"to": "573104183585",
"type": "template",
"templateId": "<uuid-de-la-plantilla-aprobada>",
"variables": {
"body": ["428193"],
"buttons": [{ "index": 0, "value": "428193" }]
}
}El valor del body[0] y el del buttons[0].value deben ser el mismo código — Meta los matchea para que el botón copie/autofille el mismo número que aparece en el texto. Si te falta el buttons, Meta rechaza con #131008 ("falta info requerida"), porque COPY_CODE/ONE_TAP/ZERO_TAP siempre piden su valor.
Modo experto: payload Meta-passthrough
Si ya tenés código que arma el shape de Meta directo, podés mandar payload en lugar de templateId + variables. Para COPY_CODE el sub_type es copy_code y el parámetro es coupon_code (no text):
{
"phoneNumberId": "...",
"to": "573104183585",
"type": "template",
"payload": {
"name": "verificacion_codigo",
"language": { "code": "es" },
"components": [
{ "type": "body", "parameters": [{ "type": "text", "text": "428193" }] },
{
"type": "button",
"sub_type": "copy_code",
"index": "0",
"parameters": [{ "type": "coupon_code", "coupon_code": "428193" }]
}
]
}
}Wizard en el dashboard
Para clientes que no integran vía API, el dashboard de Mosend ofrece plantillas OTP pre-armadas que se crean con un click:
- Andá a Dashboard → Plantillas
- Sobre el listado aparece el card "Plantillas recomendadas para verificación (OTP)" con sugerencias en español e inglés.
- Click → preview en vivo + form editable (nombre, expiración, tipo de botón).
- Click "Enviar a Meta" → en minutos queda APPROVED.
El card desaparece cuando ya tenés al menos una plantilla AUTHENTICATION en estado PENDING o APPROVED.
Errores típicos
#131008 Required parameter is missing: te falta el parámetro del botón COPY_CODE/ONE_TAP/ZERO_TAP. En modo simple agregávariables.buttons: [{ index: 0, value: "428193" }]. En modo experto agregá el component{ type: "button", sub_type: "copy_code", index: "0", parameters: [{ type: "coupon_code", coupon_code: "..." }] }.#132012 Parameter format mismatch: el parámetro del body es número y la plantilla espera string, o viceversa. Forzá string siempre ({ "type": "text", "text": "428193" }no{ "type": "number", "value": 428193 }).#132068 Template language mismatch: el códigolanguage.codeal enviar no coincide con el approved. Usá exactamente"es","en", etc. — no"es_CO"a menos que la plantilla esté aprobada bajo ese código exacto.#131042 Business eligibility payment issue: la WABA no tiene tarjeta vinculada en business.facebook.com. Aún plantillas Authentication necesitan billing OK para enviarse.- El botón no autollena en Android: el
signature_hashno coincide con el del APK instalado en el device. Regenerá conapksignersobre el APK firmado de producción (no debug).
Pricing y mejores prácticas
- Las plantillas AUTHENTICATION cuestan ~$0.0085 USD/conv en CO, ~$0.0125 en MX, etc. Variable por país.
- Meta cobra por conversación de 24h, no por mensaje — si reenviás el mismo OTP dentro de las 24h al mismo número, no se duplica el cobro.
- El cobro lo hace Meta directamente a la tarjeta de tu WABA (Mosend no factura el envío de plantillas).
- Cooldown interno recomendado: rate-limitá tu app a 1 OTP cada 30s y máximo 3 por hora por número de destino, para no terminar marcado como spam.
- TTL del código: que el código generado por vos expire al mismo tiempo que el footer dice (ej: si el template dice "10 minutos", tu Redis TTL = 600s).