Saltar al contenido principal
Usa el campo custom_data en la API Create Message para enviar datos dinámicos desde tu backend y renderizarlos dentro de plantillas usando sintaxis Liquid. custom_data:
  • Es específico del mensaje
  • No se almacena
  • Existe solo durante la solicitud de la API
  • Debe usarse con un template_id
Haz referencia a valores en plantillas con:
Liquid
{{ message.custom_data.key_name }}
custom_data es efímero. Los datos no se guardan en los perfiles de usuario y no se pueden reutilizar en mensajes futuros. Si necesitas datos persistentes, consulta Personalización de mensajes.

Cuándo usar custom_data

Usa custom_data cuando necesites:
  • Datos que cambian por mensaje (totales de pedidos, artículos del carrito, saldos)
  • Necesites arrays (listas de productos, líneas de artículos, recomendaciones)
  • Los datos no deben persistir (códigos de un solo uso, URLs temporales)
  • Envías mensajes activados desde el backend
  • Quieres personalización masiva en una sola solicitud de API

Cómo funciona la personalización con custom_data

Agregar custom_data a los mensajes requiere algunos pasos:
1

Crear una plantilla

Crea una plantilla de Push, Email o SMS en Templates desde el panel o a través de la API Create Template.
2

Agregar marcadores de posición Liquid

Inserta referencias usando el prefijo requerido:
Liquid
Hi {{ message.custom_data.first_name }},
Order {{ message.custom_data.order_id }} is confirmed.
3

Enviar custom_data en tu solicitud de API

Llama a la API Create Message con:
  • template_id - El ID de la plantilla
  • custom_data - El objeto de datos
  • Segmentación de audiencia (include_player_ids, include_aliases o segmentos)
OneSignal renderiza la plantilla en el momento del envío usando tus datos.Si la sintaxis Liquid es inválida o las claves no existen, esos campos se renderizan como cadenas vacías, pero el mensaje se envía de todas formas.

Patrones de datos

Ejemplos comunes de patrones de datos que puedes usar con custom_data.

Ejemplo de JSON plano

Usa pares clave-valor simples para personalización básica como nombres, IDs, URLs o cualquier dato de valor único. Caso de uso: Mensajes transaccionales (facturas, recibos, confirmaciones) donde cada campo contiene un solo valor. Plantilla:
Liquid
Invoice {{ message.custom_data.invoice_id }} for {{ message.custom_data.product_name }} is ready.
Solicitud de API:
JSON
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "invoice_id": "463246732",
    "product_name": "Widget"
  }
}
Lo que ve el cliente:
Text
Invoice 463246732 for Widget is ready.

Ejemplo de datos con arrays

Pasa arrays de objetos para trabajar con múltiples elementos como productos del carrito, líneas de artículos de un pedido o recomendaciones. Los arrays permiten tanto el acceso directo (indexación) como la iteración (bucles). Caso de uso: Mostrar listas de productos, tablas de clasificación, resúmenes de pedidos o cualquier dato con múltiples elementos. Plantilla con indexación (accediendo al primer elemento):
Liquid
Your {{message.custom_data.cart_items[0].item_name}} is waiting for you!
Image: {{message.custom_data.cart_items[0].img_url}}
La indexación de arrays comienza en 0, no en 1. El primer elemento es [0], el segundo es [1], etc. Acceder a un índice que no existe devuelve vacío (no se genera un error).
Plantilla con bucle (accediendo a todos los elementos):
Liquid
{% for item in message.custom_data.cart_items %}
- {{ item.item_name }}{{ item.img_url }}
{% endfor %}
Solicitud de API:
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "cart_items": [
      {
        "item_name": "sweater",
        "img_url": "https://.../sweater.png"
      },
      {
        "item_name": "socks",
        "img_url": "https://.../socks.png"
      }
    ]
  }
}
Lo que ve el cliente:
Text
Your sweater is waiting for you!
Image: https://.../sweater.png

- sweater — https://.../sweater.png
- socks — https://.../socks.png
Propiedades útiles de arrays:
  • {{message.custom_data.cart_items.size}} — Número de elementos en el array (devuelve 2 en este ejemplo)
  • {{message.custom_data.cart_items.first.item_name}} — Nombre del primer elemento (equivalente a [0])
  • {{message.custom_data.cart_items.last.item_name}} — Nombre del último elemento

Ejemplo de personalización masiva

Envía una sola solicitud de API a múltiples usuarios donde cada destinatario ve contenido personalizado basado en su external_id. Cómo funciona:
  1. Estructura custom_data como un objeto donde las claves son external_ids y los valores son datos específicos del usuario
  2. En la plantilla, usa subscription.external_id para buscar los datos del destinatario actual
  3. OneSignal renderiza la plantilla una vez por destinatario con sus datos específicos
Plantilla:
{% assign user = message.custom_data.users[subscription.external_id] %}
Hi {{ user.first_name }}, you have {{ user.points }} points. Your level is {{ user.level }}.
Qué está ocurriendo:
  • subscription.external_id contiene el external_id del destinatario actual (por ejemplo, “user123”)
  • message.custom_data.users[subscription.external_id] busca los datos de ese usuario en el objeto custom_data
  • user se convierte en una variable abreviada para los datos de ese usuario
  • Cada destinatario solo ve su propio contenido personalizado
Solicitud de API:
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["user123", "user456"]
  },
  "custom_data": {
    "users": {
      "user123": { "first_name": "John", "points": "150", "level": "Gold" },
      "user456": { "first_name": "Sarah", "points": "200", "level": "Platinum" }
    }
  }
}
Lo que ve cada usuario:
  • John (user123): “Hi John, you have 150 points. Your level is Gold.”
  • Sarah (user456): “Hi Sarah, you have 200 points. Your level is Platinum.”
Requisitos para la personalización masiva:
  • Todos los destinatarios deben tener un external_id configurado en OneSignal
  • Cada external_id en include_aliases debe tener una clave correspondiente en custom_data.users
  • Si el external_id de un destinatario no está presente en custom_data, su mensaje tendrá campos vacíos

Ejemplo: Carrito abandonado con custom_data

Cómo crear mensajes de carrito abandonado tanto para email como para push usando custom_data. Cuándo usar este enfoque:
  • Tu servidor detecta el abandono del carrito (por ejemplo, 1 hora después de la última actividad)
  • Los datos del carrito en tiempo real están en tu base de datos
  • Quieres mostrar múltiples productos con imágenes, nombres y precios
  • Cada usuario puede tener diferentes artículos y cantidades
  • Quieres orquestar el mensaje desde tu backend

Ejemplo de payload custom_data

Esta es la solicitud de la API Create Message para este ejemplo.
JSON
{
  "custom_data": {
    "cart_url": "https://yourdomain.com/cart",
    "cart": [
      {
        "product_name": "24 Pack of Acorns",
        "product_image": "https://i.imgur.com/ssPCfbC.png",
        "product_price": "$12.99",
        "product_quantity": "1"
      },
      {
        "product_name": "Fancy Sweater",
        "product_image": "https://i.imgur.com/8QWTfV4.png",
        "product_price": "$9.99",
        "product_quantity": "1"
      }
    ]
  },
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["YOUR_EXTERNAL_ID"]
  }
}
Explicación de los campos:
CampoTipoPropósito
cart_urlstringEnlace único del carrito del cliente (para botones/URLs de lanzamiento)
cartarrayLista de productos: admite conteo, bucles y visualización de detalles
product_imagestringImagen del producto (por elemento en el array)
product_namestringNombre del producto (por elemento)
product_quantitystringCantidad (por elemento)
product_pricestringPrecio con formato (por elemento)
Puedes nombrar los campos como quieras, solo asegúrate de que la sintaxis Liquid de tu plantilla coincida.
Mantente por debajo de 2KB: Si tienes carritos grandes, considera limitar a los primeros 3-5 artículos o enviar solo los campos esenciales para evitar exceder el límite de tamaño.

Plantilla de email

Este ejemplo muestra cómo construir una plantilla de email que muestra:
  • El conteo de artículos del carrito
  • Cada producto con imagen, nombre, cantidad y precio usando un bucle for
  • Un botón que enlaza a la URL única del carrito del cliente
1

Crear la plantilla de email

Navega a Messages > Templates > New Email Template y abre el Editor de Arrastrar y Soltar.
2

Agregar la estructura del diseño

Crea cinco filas:
  • Filas 1, 2 y 4: una columna con un bloque de Párrafo
  • Fila 3: cuatro columnas con HTML | Párrafo | Párrafo | Párrafo
  • Fila 5: una columna con un bloque de Botón
3

Mostrar el conteo de artículos

En la fila 1, agrega:
Liquid
We're holding onto {{message.custom_data.cart.size}} items in your cart, but don't wait too long, other squirrels are getting ahead!
Para mejor gramática, podrías usar un condicional para decir “1 item” vs “2 items”, pero para emails de carrito abandonado, el plural generalmente es aceptable.
Liquid
{% assign cart = message.custom_data.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
We're holding onto {{item_count}} item in your cart, but don't wait too long, other squirrels are getting ahead!
{% endif %}
{% if item_count > 1 %}
We're holding onto {{item_count}} items in your cart, but don't wait too long, other squirrels are getting ahead!
{% endif %}
4

Iniciar el bucle

Usa un bucle for para repetir la fila de visualización del producto por cada artículo en el carrito.En la fila 2 (inicio del bucle), agrega esto al bloque de texto:
Text
{% for product in message.custom_data.cart %}
Qué hace esto:
  • Comienza un bucle que itera sobre cada objeto en el array cart
  • Crea una variable temporal llamada product que representa el elemento actual
  • Todo lo que está entre {% for %} y {% endfor %} se repite una vez por cada artículo del carrito
  • Puedes nombrar product como quieras (por ejemplo, item, cartItem), solo mantén la consistencia
Ubicación del bucle for: Asegúrate de que la sintaxis {% for %} esté en su propia fila de bloque de texto. No la coloques dentro de una fila de múltiples columnas con otro contenido, ya que esto puede romper el renderizado del email en algunos clientes.
5

Mostrar los detalles del producto

Esta fila de 4 columnas muestra la imagen, nombre, cantidad y precio. Como está dentro del bucle, se repite para cada artículo del carrito.En la fila 3 (detalles del producto), configura:Columna 1 - Bloque HTML (imagen del producto):
HTML
<img src="{{product.product_image}}" alt="Product image" style="max-width:100%;" />
Columnas 2–4 - Bloques de texto (nombre del producto, cantidad, precio):
  • Columna 2: {{product.product_name}}
  • Columna 3: {{product.product_quantity}}
  • Columna 4: {{product.product_price}}
Cómo funciona el bucle:
  • En la primera iteración, product = primer objeto en el array del carrito
  • {{product.product_image}} obtiene la URL de la imagen del primer artículo
  • En la segunda iteración, product = segundo objeto
  • La fila se repite automáticamente para todos los artículos del carrito
Coincidencia de nombres de campos: Las claves como product_image deben coincidir exactamente con tu payload de evento (distingue mayúsculas y minúsculas). Los nombres que no coincidan se renderizan como cadenas vacías.
6

Finalizar el bucle

Cierra el bucle para marcar dónde se detiene la repetición.En la fila 4 (fin del bucle), agrega:
Liquid
{% endfor %}
Cada {% for %} debe tener un {% endfor %} correspondiente. Si falta, se romperá el renderizado del email.
7

Agregar un botón de enlace al carrito

En el bloque de Botón de la fila 5, establece la URL de acción a:
Text
{{message.custom_data.cart_url}}
8

Probar la plantilla

  • Configura tu solicitud de API usando el Ejemplo de payload custom_data
  • Envíate el email a ti mismo.
  • Verifica que los datos se muestren correctamente.
¡Éxito! Ahora puedes aplicar tus propios estilos a la plantilla. Consulta Diseñar emails con arrastrar y soltar.

Plantilla de push

Las notificaciones push tienen límites de caracteres y restricciones del sistema operativo, por lo que en lugar de mostrar todos los artículos, muestra el primer producto e indica el conteo total con gramática correcta. Aquí tienes un ejemplo de notificación push que construiremos:
Campo de mensaje:
Liquid
{% assign cart = message.custom_data.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
You left {{cart.first.product_name}} in your cart.
{% endif %}
{% if item_count == 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more item in your cart.
{% endif %}
{% if item_count > 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more items in your cart.
{% endif %}
Consulta Uso de sintaxis Liquid para más información.
Campo de imagen:
Liquid
{{message.custom_data.cart.first.product_image | default: "https://i.imgur.com/ssPCfbC.png"}}
Consulta Imágenes de notificaciones y rich media para más información.
Campo de URL de lanzamiento:
Liquid
{{cart_url | default: "https://yourdomain.com/cart"}}
Guarda la plantilla y usa su template_id en tu solicitud de la API Create message con la propiedad custom_data para probar.

Solución de problemas y mejores prácticas

  • Mantenlo simple: Solo incluye datos que realmente usarás en la plantilla
  • Mantente por debajo de 2KB: Monitorea el tamaño de tu payload, especialmente con arrays
  • Usa nombres consistentes: Mantén snake_case o camelCase en todo el contenido
  • Valida antes de enviar: Verifica valores nulos, arrays vacíos y campos requeridos
Diseño de plantillas:
  • Siempre usa filtros default para campos opcionales:
    Liquid
    {{message.custom_data.user_name | default: "there"}}
    
  • Verifica el tamaño del array antes de iterar:
    Liquid
    {% if message.custom_data.items.size > 0 %}
      {% for item in message.custom_data.items %}
        {{item.name}}
      {% endfor %}
    {% endif %}
    
  • Prueba con casos límite: arrays vacíos, campos faltantes, conteos máximos de elementos
Manejo de errores:
  • Registra las respuestas de la API en el servidor para detectar errores de validación
  • Monitorea las tasas de entrega de mensajes: caídas repentinas pueden indicar errores de Liquid
  • Mantén plantillas de respaldo listas para mensajes transaccionales críticos
Rendimiento:
  • Pre-formatea datos complejos en tu backend en lugar de usar lógica Liquid compleja
  • Almacena plantillas en caché y reutilízalas en múltiples llamadas de API
  • Considera separar los mensajes transaccionales de alto volumen de las campañas de marketing
Causa: Errores de sintaxis Liquid o nombres de campos que no coincidenSoluciones:
  • Verifica que los nombres de campos coincidan exactamente entre custom_data y la plantilla (distingue mayúsculas y minúsculas)
  • Busca errores tipográficos: {{message.custom_data.name}} no {{message.custm_data.name}}
  • Usa filtros default para capturar campos faltantes
  • Prueba las plantillas con la estructura real de custom_data antes de producción
Causa: custom_data excede el límite de 2KBSoluciones:
  • Elimina campos innecesarios de tu payload
  • Acorta nombres de campos y valores donde sea posible
  • Limita los arrays a los primeros 3-5 elementos
  • Mueve el contenido estático grande (como HTML completo) a tu plantilla en su lugar

Páginas relacionadas

¿Necesita ayuda?Chatee con nuestro equipo de Soporte o envíe un correo electrónico a support@onesignal.comPor favor incluya:
  • Detalles del problema que está experimentando y pasos para reproducir si están disponibles
  • Su ID de aplicación de OneSignal
  • El ID externo o ID de suscripción si corresponde
  • La URL del mensaje que probó en el panel de OneSignal si corresponde
  • Cualquier registro o mensaje de error relevante
¡Estamos felices de ayudar!