Skip to content

Create a WhatsApp template

Request

Crea una plantilla y la envía a Meta para su aprobación. La respuesta indica que fue enviada, no aprobada: consulta el resultado con GET /retailers/api/v1/whatsapp_templates/{id}.

Soporta texto, imagen, video, documento, botones, carrusel, oferta limitada y autenticación (OTP).

Crea y consulta las plantillas de WhatsApp (HSM) desde la API. Esta sección explica cómo se arma el contenido de una plantilla (variables, ejemplos, imágenes, formato) y qué errores devuelve la API cuando una regla no se cumple.

Versión actual: texto, imagen, video y documento; botones de respuesta rápida y de llamado a la acción; carrusel; oferta limitada; plantillas de autenticación (código OTP); y soporte para cuentas con varios números de WhatsApp. La ubicación (location) aún no está disponible por API.

Autenticación de las peticiones

Todas las peticiones llevan el header Api-Key del retailer.

CasoRespuesta
Sin header Api-Key401
Api-Key desconocida404 Resource not found

El límite global es de 10 peticiones por segundo por IP.

Endpoints

MétodoRutaDescripción
POST/retailers/api/v1/whatsapp_templatesCrea la plantilla y la envía a Meta para su aprobación
GET/retailers/api/v1/whatsapp_templates/:idConsulta una plantilla en cualquier estado. :id es el id numérico o el internal_id
GET/retailers/api/v1/whatsapp_templatesLista solo las plantillas accepted y disabled (las utilizables para enviar)
GET/retailers/api/v1/whatsapp_templates/integrationsLista los números de WhatsApp con los que se pueden crear plantillas (cuentas con varios números)

La creación es asíncrona de cara a Meta: la respuesta indica que la plantilla fue enviada, no aprobada. Consulta el resultado con GET /whatsapp_templates/:id.

Campos del POST

CampoObligatorioDescripción
nameSíNombre de la plantilla. Se normaliza: minúsculas, espacios → _ y solo a-z, 0-9, _. Único por retailer (sin distinguir mayúsculas). Máx. 512
languageSíspanish o english (también se aceptan es_ES y en_US)
categorySíMARKETING, UTILITY o AUTHENTICATION (ver Autenticación)
template_typeSí (salvo autenticación)text, image, video, document o carousel
textSí (salvo autenticación)Cuerpo del mensaje (en un carrusel, el texto principal sobre las tarjetas). Máx. 1024 caracteres sin contar las variables
body_examplesSí, si text tiene variablesUn valor de ejemplo por variable, en orden
header_textNoEncabezado de texto. Solo con template_type: text. Máx. 60 caracteres, sin HTML
media_urlSí en image, video y documentURL https pública del archivo (ver Imágenes, video y documentos). No se permite en text
buttonsNoLista de botones (ver Botones). No va en carruseles ni con una oferta
offerNoOferta limitada (ver Oferta limitada)
cards y cards_media_typeSolo en carouselTarjetas y tipo de media común (ver Carrusel)
add_security_recommendation, code_expiry_minutes, code_exampleSolo en AUTHENTICATIONOpciones del código (ver Autenticación)
team_idNoEquipo del retailer al que se asigna la plantilla
integration_idSolo si hay más de un número activoNúmero de WhatsApp con el que se crea (ver Varios números)
integration_platformNoSolo para confirmar la plataforma de integration_id; se deduce sola

Variables en el texto

Las variables son los huecos que se rellenan al enviar el mensaje (nombre del cliente, número de pedido…).

  • Sintaxis: {{1}}, {{2}}, {{3}}… — número entero mayor que 0 entre dobles llaves.
  • Deben ser correlativas desde {{1}} y no repetirse. {{1}} … {{3}} (salta el 2) o {{1}} … {{1}} se rechazan.
  • El texto no puede empezar ni terminar con una variable (regla de Meta): Hola {{1}}, gracias es válido; {{1}} gracias no.
  • No se permiten nombres: {{nombre}} es inválido.

Ejemplos obligatorios

Meta revisa la plantilla con valores de muestra. Envía en body_examples un valor por variable, en el mismo orden, sin vacíos:

{
  "text": "Hola {{1}}, tu pedido {{2}} va en camino",
  "body_examples": ["Ana", "ORD-1042"]
}

Mercately construye el ejemplo que ve Meta reemplazando cada variable: Hola [Ana], tu pedido [ORD-1042] va en camino. Estos valores solo sirven para la revisión; los valores reales se indican al enviar el mensaje (template_params).

Si el texto no tiene variables, body_examples debe omitirse o ir vacío.

Qué se guarda y qué ves en GET

Al ser aprobada, Mercately guarda internamente el text con cada {{n}} convertido en * y escapa los * literales como \*. Por eso, en una plantilla accepted, text se ve así: Hola *, tu pedido * va en camino.

Para no tener que interpretar eso, las respuestas incluyen body: el mismo texto con las variables restauradas como {{1}}, {{2}}… y los asteriscos de formato (*negrita*) como los escribiste. Usa body para leer el contenido de una plantilla; text se conserva solo por compatibilidad con el listado existente. En plantillas aún no aprobadas, body y text coinciden.

Formato del texto

WhatsApp admite formato con marcas dentro de text:

MarcaResultado
*texto*negrita
_texto_cursiva
~texto~tachado
`texto`monoespaciado

El texto se envía tal cual a Meta, que valida el formato. Evita HTML.

Encabezado (header)

Una plantilla tiene un solo encabezado:

template_typeEncabezado
textOpcional: header_text (máx. 60, no admite variables, sin HTML)
imageLa imagen indicada en media_url
videoEl video indicado en media_url
documentEl PDF indicado en media_url

header_text no se permite junto a image, video o document.

Imágenes, video y documentos

Para incrustar un archivo en la plantilla indica su URL en media_url. Mercately lo descarga, lo sube al proveedor de WhatsApp y usa esa referencia como ejemplo de cabecera en la revisión de Meta.

TipoFormatoTamaño máximo
imageJPG, PNG5 MB
videoMP416 MB
documentPDF40 MB

Requisitos de la URL:

  • Debe ser https (puerto 443), sin usuario ni contraseña, y accesible públicamente sin autenticación.
  • El tipo se valida por el contenido real del archivo, no por la extensión ni por el Content-Type.
  • Se siguen hasta 3 redirecciones, cada una debe ser https y pública.
  • Por seguridad se rechazan direcciones privadas, locales o de infraestructura interna.
  • La descarga tiene tiempos de espera cortos: el servidor debe responder en pocos segundos.

El archivo no se almacena en Mercately: se usa solo durante la creación.

Botones

Una plantilla puede llevar botones de respuesta rápida o botones de llamado a la acción, pero no ambos a la vez. No envíes interactive_action: se deduce de los botones (quick_reply o call_to_action) y, si lo envías, se rechaza.

Cada botón es un objeto con type en mayúsculas y un text de máx. 20 caracteres. Los textos no pueden repetirse (sin distinguir mayúsculas). Un botón solo admite los campos de su tipo; cualquier otro se rechaza con unknown_field.

typeCamposLímite
QUICK_REPLYtextHasta 3 botones
URLtext, url, example (solo si la URL es dinámica)Hasta 1 por plantilla
PHONE_NUMBERtext, phone_numberHasta 1 por plantilla

Los botones URL y PHONE_NUMBER pueden combinarse entre sí (máx. 2 en total). No se pueden mezclar con QUICK_REPLY.

Teléfono

phone_number va en formato internacional con + y sin espacios: +573001234567.

URL estática y dinámica

  • Estática: una URL completa http(s)://…, sin variables y sin example.
  • Dinámica: la URL termina en {{1}} (la única variable permitida, y solo al final). Se completa al enviar el mensaje. Exige example con una URL completa de muestra que empiece igual que la parte fija:
{
  "type": "URL",
  "text": "Rastrear pedido",
  "url": "https://tienda.com/track/{{1}}",
  "example": ["https://tienda.com/track/ORD-1042"]
}

example también puede enviarse como texto simple. La URL admite hasta 2000 caracteres.

Carrusel

Un carrusel es un mensaje principal (text) con 2 a 10 tarjetas deslizables. Se crea con template_type: "carousel".

CampoObligatorioDescripción
text / body_examplesSíMensaje principal sobre las tarjetas, con las mismas reglas de variables que cualquier cuerpo
cards_media_typeSíimage o video: es el mismo tipo en todas las tarjetas
cardsSíLista de 2 a 10 tarjetas

Cada tarjeta es un objeto con estos campos (cualquier otro se rechaza con unknown_field):

Campo de la tarjetaObligatorioDescripción
bodySíTexto de la tarjeta, máx. 160 caracteres, con las mismas reglas de variables ({{1}}, {{2}}…, correlativas y sin empezar ni terminar en variable)
body_examplesSi el body tiene variablesUn ejemplo por variable de esa tarjeta
media_urlSíURL https del archivo de la tarjeta (mismas reglas, formatos y tamaños que los archivos)
buttonsSí1 o 2 botones (QUICK_REPLY, URL o PHONE_NUMBER), texto de hasta 25 caracteres

Reglas del conjunto:

  • Todas las tarjetas deben tener los mismos tipos de botón en el mismo orden (si la primera lleva URL, todas llevan URL); los textos y las URL pueden diferir. Si no, cards[n].buttons / mismatch.
  • En un carrusel los botones pueden mezclarse (por ejemplo QUICK_REPLY + URL), a diferencia de una plantilla normal.
  • El carrusel no admite header_text, media_url ni buttons en el nivel principal.
  • Los errores indican la tarjeta: cards[1].body, cards[0].media_url, cards[2].buttons[0].text…
{
  "name": "coleccion_octubre", "language": "spanish", "category": "MARKETING", "template_type": "carousel",
  "text": "Hola {{1}}, mira nuestra colección", "body_examples": ["Ana"],
  "cards_media_type": "image",
  "cards": [
    { "body": "Camisa azul", "media_url": "https://cdn.mitienda.com/azul.png",
      "buttons": [{ "type": "URL", "text": "Comprar", "url": "https://tienda.com/azul" }] },
    { "body": "Pantalón {{1}} nuevo", "body_examples": ["rojo"], "media_url": "https://cdn.mitienda.com/rojo.png",
      "buttons": [{ "type": "URL", "text": "Comprar", "url": "https://tienda.com/rojo" }] }
  ]
}

Oferta limitada

Una oferta limitada es una plantilla de marketing con un encabezado de oferta (por ejemplo «Solo hoy»), un botón para ir a la tienda y, opcionalmente, una cuenta regresiva con un código de cupón.

Requisitos: category: "MARKETING", template_type image o video (con su media_url) y el objeto offer. No se envía buttons: la oferta define los suyos.

Campo de offerObligatorioDescripción
titleSíTítulo de la oferta, máx. 16 caracteres
urlSíBotón { "text", "url", "example" }, con las mismas reglas que un botón URL (estática o dinámica con {{1}} al final y example)
expires_in_minutesNoDuración de la oferta en minutos desde el envío, entero ≥ 1. Activa la cuenta regresiva
codeSi hay expires_in_minutesCódigo de cupón de ejemplo que se copia con el botón. No se permite sin expiración
code_button_textNoTexto del botón de copiar (máx. 25). Por defecto «Copiar código de oferta» / «Copy offer code»
{
  "name": "oferta_viernes", "language": "spanish", "category": "MARKETING", "template_type": "image",
  "media_url": "https://cdn.mitienda.com/oferta.png",
  "text": "Hola {{1}}, solo por hoy tenemos un descuento para ti", "body_examples": ["Ana"],
  "offer": {
    "title": "Solo hoy",
    "url": { "text": "Comprar", "url": "https://tienda.com/oferta" },
    "expires_in_minutes": 120,
    "code": "VIP10"
  }
}

expires_in_minutes se cuenta desde el momento en que Mercately envía la plantilla al proveedor.

Plantillas de autenticación (código OTP)

Con category: "AUTHENTICATION" la plantilla sirve para enviar códigos de verificación. Mercately genera el texto y el botón, igual que la pantalla de creación: no envíes text, body_examples, header_text, media_url, buttons, offer ni cards (se rechazan con not_allowed).

CampoObligatorioDescripción
name, language, categorySílanguage: spanish o english
template_typeNoSi se envía, debe ser text
code_exampleNoCódigo de muestra que aparece en el texto (por defecto 123456), máx. 30
add_security_recommendationNotrue agrega «Por tu seguridad, no lo compartas.» (en inglés: «For your security, do not share this code.»)
code_expiry_minutesNoEntero de 1 a 90. Agrega «Este código caduca en N minutos.» (en inglés: «This code expires in N minutes.»)

El texto resultante en español, con ambas opciones, es:

Tu código de verificación es: 123456
Por tu seguridad, no lo compartas.
Este código caduca en 10 minutos.

y el botón es Copiar código (Copy code en inglés), de tipo OTP / COPY_CODE. Puedes leer ambos en la respuesta (body y buttons).

{ "name": "codigo_login", "language": "spanish", "category": "AUTHENTICATION",
  "add_security_recommendation": true, "code_expiry_minutes": 10 }

Cuentas con varios números de WhatsApp

Si la cuenta tiene varios números, cada plantilla se crea para uno de ellos.

  1. Consulta los disponibles: GET /retailers/api/v1/whatsapp_templates/integrations. Devuelve solo los activos y compatibles con plantillas, con id, platform, name, phone_number y status.
  2. Envía el id elegido como integration_id al crear la plantilla. La plataforma se deduce sola.
{ "integrations": [ { "id": "int-1", "platform": "whatsapp_gupshup_messages", "name": "Ventas", "phone_number": "+573001234567", "status": "active" } ] }
  • Si solo hay un número activo, integration_id es opcional y se usa ese.
  • Si hay varios y no lo envías, la API responde 422 integration_id / required y lista los ids disponibles.
  • En cuentas con un solo número, integration_id no aplica y se rechaza con not_applicable.
  • Una plantilla pertenece al número con el que se creó: no se comparte entre números.

Ciclo de vida de una plantilla

POST → submitted → accepted        (Meta la aprobó: ya se puede usar para enviar)
                 → rejected        (Meta la rechazó: ver `reason`)
accepted ↔ disabled
statusSignificado
pendingCreada, aún sin enviar a Meta
submittedEnviada a Meta, a la espera de aprobación
acceptedAprobada. Aparece en el listado y se puede usar en send_notification_by_id con su internal_id
rejectedRechazada. El motivo está en reason
disabledDesactivada
deletedEliminada

Para saber cuándo se aprueba, consulta periódicamente GET /whatsapp_templates/:id (por ejemplo cada minuto; Meta suele resolver en minutos u horas).

Respuestas

Éxito (201)

{
  "template": {
    "id": 1234,
    "internal_id": "7f3f0c1e-1f6b-4a43-9a25-0d1a5f0f0a11",
    "name": "order_update",
    "status": "submitted",
    "category": "UTILITY",
    "language": "spanish",
    "template_type": "text",
    "text": "Hola {{1}}, tu pedido {{2}} va en camino",
    "body": "Hola {{1}}, tu pedido {{2}} va en camino",
    "header_text": "Tu pedido",
    "reason": null,
    "created_at": "2026-10-07T12:40:37.636Z"
  }
}

id es estable desde el primer momento. internal_id es el identificador de Meta/proveedor y puede ser null mientras la plantilla está pending.

Error

{
  "message": "Template could not be created",
  "errors": [
    { "field": "text", "code": "variables_not_sequential", "detail": "variables must be sequential starting at {{1}}" }
  ]
}

Cuando Meta rechaza la plantilla se responde 422 con code: provider_rejected, el motivo en detail y la plantilla guardada en template (con status: rejected).

Recetas

Solo texto con variables y encabezado

curl -X POST https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H "Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "order_update", "language": "spanish", "category": "UTILITY", "template_type": "text",
    "header_text": "Tu pedido",
    "text": "Hola {{1}}, tu pedido {{2}} va en camino",
    "body_examples": ["Ana", "ORD-1042"]
  }'

Plantilla con imagen

curl -X POST https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H "Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "promo_octubre", "language": "spanish", "category": "MARKETING", "template_type": "image",
    "media_url": "https://cdn.mitienda.com/promos/octubre.png",
    "text": "Hola {{1}}, tenemos una promo para ti: *20% de descuento* hasta el viernes",
    "body_examples": ["Ana"]
  }'

Plantilla con documento PDF

curl -X POST https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H "Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "catalogo_2026", "language": "spanish", "category": "MARKETING", "template_type": "document",
    "media_url": "https://cdn.mitienda.com/catalogo.pdf",
    "text": "Hola, aquí tienes nuestro catálogo actualizado"
  }'

Quick replies

curl -X POST https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H "Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "confirmar_cita", "language": "spanish", "category": "UTILITY", "template_type": "text",
    "text": "Hola {{1}}, ¿confirmas tu cita del {{2}}?",
    "body_examples": ["Ana", "viernes 10 de octubre"],
    "buttons": [
      { "type": "QUICK_REPLY", "text": "Sí, confirmo" },
      { "type": "QUICK_REPLY", "text": "Reprogramar" }
    ]
  }'

Imagen con URL dinámica y botón de llamada

curl -X POST https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H "Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "pedido_enviado", "language": "spanish", "category": "UTILITY", "template_type": "image",
    "media_url": "https://cdn.mitienda.com/envio.png",
    "text": "Hola {{1}}, tu pedido salió hoy",
    "body_examples": ["Ana"],
    "integration_id": "int-1",
    "buttons": [
      { "type": "URL", "text": "Rastrear", "url": "https://tienda.com/track/{{1}}",
        "example": ["https://tienda.com/track/ORD-1042"] },
      { "type": "PHONE_NUMBER", "text": "Llámanos", "phone_number": "+573001234567" }
    ]
  }'

Consultar el estado

curl https://app.mercately.com/retailers/api/v1/whatsapp_templates/7f3f0c1e-1f6b-4a43-9a25-0d1a5f0f0a11 \
  -H "Api-Key: $API_KEY"

Campos aún no soportados

Estos campos se rechazan con 422 y code: field_not_supported (no se ignoran en silencio): interactive_action (se deduce de buttons) y footer. Además, template_type: location responde not_supported_yet: la creación de plantillas de ubicación aún no está disponible por API.

Catálogo de errores

HTTPfieldcodeQué hacer
422cualquierarequiredFalta un campo obligatorio
422nameinvalid, too_longEl nombre debe tener letras o números y máx. 512 caracteres
422name(mensaje del modelo)Ya existe una plantilla con ese nombre
422language / category / template_typeinvalidUsa uno de los valores permitidos
422template_typenot_supported_yetlocation aún no está disponible por API
422texttoo_longMáx. 1024 caracteres sin contar variables
422textvariables_invalidUsa {{1}}, {{2}}… (solo enteros)
422textvariables_repeatedNo repitas una variable
422textvariables_not_sequentialNumera desde {{1}} sin saltos
422textvariable_at_edgeEl texto no puede empezar ni terminar con variable
422body_examplesmismatchUn ejemplo no vacío por variable
422body_examplesunexpectedQuita los ejemplos si no hay variables
422header_texttoo_long, invalid, not_allowedMáx. 60, sin HTML, solo en text
422media_urlrequired, not_allowedObligatoria en image/video/document; no en text
422media_urlinvalid_urlUsa una URL https válida, sin credenciales
422media_urlblocked_hostLa URL debe apuntar a un servidor público
422media_urltoo_many_redirectsReduce las redirecciones
413media_urlfile_too_largeEl archivo supera el máximo de su tipo
415media_urlunsupported_media_typeFormato no permitido para ese tipo
502media_urldownload_failedNo se pudo descargar el archivo; revisa que sea público
504media_urldownload_timeoutEl servidor del archivo tardó demasiado
422team_idinvalidEl equipo no pertenece al retailer
422buttonsinvalidDebe ser una lista de objetos
422buttonsmixed_typesNo mezcles QUICK_REPLY con URL/PHONE_NUMBER
422buttonstoo_manyMáx. 3 quick replies o 2 botones de llamado a la acción
422buttonsduplicate_typeSolo un botón URL y uno PHONE_NUMBER
422buttonsduplicate_textLos textos de los botones deben ser únicos
422buttons[n]unknown_fieldEl botón trae un campo que no corresponde a su tipo
422buttons[n].typeinvalidQUICK_REPLY, URL o PHONE_NUMBER en mayúsculas
422buttons[n].textrequired, too_longObligatorio, máx. 20 caracteres
422buttons[n].urlrequired, invalid, too_longURL http(s) válida; {{1}} solo al final; máx. 2000
422buttons[n].examplemismatch, not_allowedLa URL dinámica exige un ejemplo completo; la estática no lleva example
422buttons[n].phone_numberinvalidFormato internacional, p. ej. +573001234567
422cardsrequired, invalid, too_few, too_manyUn carrusel necesita de 2 a 10 tarjetas (lista de objetos)
422cards[n]unknown_fieldLa tarjeta trae un campo no permitido (solo body, body_examples, media_url, buttons)
422cards[n].body / .body_examples(reglas de variables)Mismas reglas que el cuerpo, con máx. 160 caracteres
422cards[n].media_urlrequiredToda tarjeta lleva su archivo (también download_failed, unsupported_media_type, file_too_large… indicando la tarjeta)
422cards[n].buttonsrequired, too_many, mismatch1 o 2 botones, con los mismos tipos que la primera tarjeta
422cards_media_typerequired, invalid, not_allowedimage o video, solo en carruseles
422offerrequires_marketing, not_allowed, invalid, unknown_fieldLa oferta es solo de marketing, no va con carrusel y es un objeto con sus claves
422template_typeinvalid_for_offerUna oferta necesita image o video
422offer.titlerequired, too_longObligatorio, máx. 16 caracteres
422offer.url…(reglas de botón URL)Se reporta como offer.url.text, offer.url.url, offer.url.example
422offer.expires_in_minutesinvalidEntero de al menos 1
422offer.coderequired, too_long, not_allowedObligatorio si la oferta expira; no se permite sin expiración
422offer.code_button_texttoo_long, not_allowedMáx. 25 y solo con expiración
422text, buttons, media_url…not_allowedEn AUTHENTICATION esos campos los genera Mercately
422code_expiry_minutesinvalidEntero de 1 a 90
422code_exampleinvalid, too_longTexto no vacío, máx. 30
422add_security_recommendationinvalidtrue o false
422integration_idrequiredHay varios números activos: elige uno
422integration_idnot_found, not_activeNo existe o no está activo para plantillas
422integration_idunavailableNo hay ningún número activo
422integration_id / integration_platformnot_applicable, mismatchLa cuenta tiene un solo número, o la plataforma no coincide
502integrationsintegrations_unavailableNo se pudieron consultar los números; reintenta
422cualquierafield_not_supportedCampo aún no disponible
422templateprovider_rejectedMeta/proveedor rechazó la plantilla; ver detail
Security
api-key
Bodyapplication/jsonrequired
namestring, <= 512 charactersrequired

Se normaliza (minúsculas, espacios a _, solo a-z, 0-9, _). Único por retailer.

Example:"order_update"
languagestringrequired
Enum:"spanish""english""es_ES""en_US"
categorystringrequired
Enum:"MARKETING""UTILITY""AUTHENTICATION"
template_typestring

Obligatorio salvo en AUTHENTICATION.

Enum:"text""image""video""document""carousel"
textstring

Cuerpo del mensaje, máx. 1024 caracteres sin contar variables. Obligatorio salvo en AUTHENTICATION.

Example:"Hola {{1}}, tu pedido {{2}} va en camino"
body_examplesArray of strings

Un valor de ejemplo por variable, en orden. Obligatorio si text tiene variables.

Example:
[ "Ana", "ORD-1042" ]
header_textstring, <= 60 characters

Solo con template_type text.

media_urlstring, (uri)

URL https pública del archivo. Obligatoria en image, video y document.

buttonsArray of objects

QUICK_REPLY (hasta 3) o URL / PHONE_NUMBER (hasta 1 de cada uno). No se mezclan los dos grupos.

offerobject

Oferta limitada. Solo MARKETING con template_type image o video; no se envía buttons.

cards_media_typestring

Solo en carousel.

Enum:"image""video"
cardsArray of objects, [ 2 .. 10 ] items

Solo en carousel. Todas las tarjetas llevan los mismos tipos de botón en el mismo orden.

add_security_recommendationboolean

Solo en AUTHENTICATION.

code_expiry_minutesinteger, [ 1 .. 90 ]

Solo en AUTHENTICATION.

code_examplestring, <= 30 characters

Solo en AUTHENTICATION. Por defecto 123456.

team_idinteger

Equipo del retailer al que se asigna la plantilla.

integration_idstring

Número de WhatsApp con el que se crea. Obligatorio si hay más de uno activo (ver GET .../integrations).

integration_platformstring

Solo para confirmar la plataforma de integration_id; se deduce sola.

curl -i -X POST \
  https://app.mercately.com/retailers/api/v1/whatsapp_templates \
  -H 'Content-Type: application/json' \
  -H 'api-key: YOUR_API_KEY_HERE' \
  -d '{
    "name": "order_update",
    "language": "spanish",
    "category": "UTILITY",
    "template_type": "text",
    "header_text": "Tu pedido",
    "text": "Hola {{1}}, tu pedido {{2}} va en camino",
    "body_examples": [
      "Ana",
      "ORD-1042"
    ]
  }'

Responses

Plantilla creada y enviada a Meta

Bodyapplication/json
templateobject(template)
Response
{ "template": { "id": 1234, "internal_id": "7f3f0c1e-1f6b-4a43-9a25-0d1a5f0f0a11", "name": "order_update", "status": "submitted", "category": "UTILITY", "language": "spanish", "template_type": "text", "text": "Hola {{1}}, tu pedido {{2}} va en camino", "body": "Hola {{1}}, tu pedido {{2}} va en camino", "header_text": "Tu pedido", "interactive_action": "string", "buttons": [ … ], "cards": [ … ], "offer": { … }, "reason": "string", "created_at": "2026-10-07T12:40:37.636Z" } }