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. Solo add_security_recommendation (string "true"/"false").
  • FOOTER: code_expiration_minutes entre 1 y 90. Meta agrega "Expira en N minutos".
  • BUTTONS: exactamente uno con type: "OTP" + otp_type uno 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
}

Doc oficial de Zero-Tap →

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:

  1. Andá a Dashboard → Plantillas
  2. Sobre el listado aparece el card "Plantillas recomendadas para verificación (OTP)" con sugerencias en español e inglés.
  3. Click → preview en vivo + form editable (nombre, expiración, tipo de botón).
  4. 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ódigo language.code al 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_hash no coincide con el del APK instalado en el device. Regenerá con apksigner sobre 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).