> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notifique.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Variables, campos personalizados y CRUD

> {{…}} marcadores de posición, combinación de contactos, valores predeterminados, cargas útiles por canal y administración de plantillas a través de API.

## En resumen

* Escribe `{{key}}` en la copia. En el momento del envío Notifique **completa** los valores predeterminados, el contacto y solicite `variables`.
* Teclas de contacto: utilice **`name`**, **`email`**, **`phone`**. Prefiero el inglés para las claves integradas.
* **Administración** y **envío** utilizan ámbitos diferentes. Consulte [Ámbitos de clave API](/es/template-api/como-funciona/escopos-da-api-key).

***

## Canales en una plantilla

Cada plantilla elige **qué canales están activos** (1 a 7): `sms`, `whatsapp`, `telegram`, `email`, `rcs`, `push`, `voice`.

En la API, use un bloque raíz por canal:

On **send**, `channels` must be a **subset** of `enabledChannels`. A requested but disabled channel returns **400** (`TEMPLATE_CHANNEL_NOT_ENABLED`).

***

## Per-channel payloads (create / update)

| Channel    | Main `payload` fields                                                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sms`      | `content` (final text 9 to 160 after variables)                                                                                                                         |
| `whatsapp` | `content`, optional `mediaUrl`, `buttons` (`label` + HTTPS `url`)                                                                                                       |
| `telegram` | `content`, optional `mediaUrl`, `buttons`                                                                                                                               |
| `email`    | `subject`, `html` and/or `text`, optional `buttons`                                                                                                                     |
| `rcs`      | `messageType` (`BASIC` \| `CARD` \| `CAROUSEL` \| `FILE`), `message`, plus type fields: `cardImage`, `cardTitle`, `cardMessage`, `buttons`, `cards`, `file`, `fileName` |
| `push`     | `title`, `body`, optional `url`, `icon`, `image`, `data` (string map)                                                                                                   |
| `voice`    | `speakText`, optional `speakVoice`, optional `gather` (`prompt`, `maxDigits`, `timeoutSecs`, `voice`)                                                                   |

`{{…}}` variables also apply inside nested RCS strings, push title/body, and voice `speakText`.

***

## Variables in copy (`{{…}}`)

Two sources merge on send:

1. **From the template**: placeholders you typed. They need a value in `variables` or **`variableDefaults`**.
2. **From the contact**: filled automatically when the recipient exists in the workspace (except **Telegram-only** recipients).

**Priority order:** template defaults → contact data → custom fields → request **`variables`** (wins).

### Built-in contact keys

| Key in template    | Meaning                                    |
| ------------------ | ------------------------------------------ |
| `name`             | Contact name                               |
| `email`            | Email                                      |
| `phone`            | Phone (E.164)                              |
| `telefone`         | Same as `phone`                            |
| `url`              | Contact URL when set                       |
| `preferences_link` | Preferences / unsubscribe link (marketing) |

<Note>
  Prefer **`{{name}}`**. In some internal flows `nome` may be filled alongside `name`, but the stable API and editor contract is `name`. Send `variables.nome` only if your copy intentionally uses that key.
</Note>

<Info>
  **Telegram-only** recipients (`chat_id` or `@username`): automatic name/email merge **does not** run. Fill via `variables` or defaults.
</Info>

### Accepted formats

* **Named:** `{{order}}` → `variables: { "order": "123" }`
* **Positional:** `{{1}}`, `{{2}}` → keys `"1"`, `"2"`
* **Custom fields:** same CRM technical key, e.g. `{{current_plan}}`

***

## Custom fields

Each field has a **technical key** (`snake_case`, e.g. `current_plan`). In the template: `{{current_plan}}` with the same key.

Define them in the dashboard (**Contacts → Custom fields**) or via the Contacts API. After merge, values also apply to RCS, Push, and Voice.

***

## Defaults (`variableDefaults`)

If the send **does not** provide a key, the template default is used before failing on a missing variable. Contact data and request `variables` can still override it.

***

## Marketing and preferences

For templates with category **`MARKETING`**:

* `marketingTopicId`: ties the send to a communication topic
* `appendPreferencesLink` (default `true`): the platform fills `{{preferences_link}}` per recipient

Outside marketing, `preferences_link` may be empty: do not rely on it as the only CTA.

***

## Translations (`localeTranslations`)

Puede almacenar traducciones por locale para campos de canales habilitados. Al enviar, la API elige la copia según la preferencia de idioma del contacto cuando esté disponible. Los marcadores `{{…}}` en traducciones deben coincidir con la plantilla principal.

***

## Management via API

| Operation       | Scope              |
| --------------- | ------------------ |
| List templates  | `templates:read`   |
| Get template    | `templates:read`   |
| Create template | `templates:create` |
| Update template | `templates:update` |
| Delete template | `templates:delete` |

**List query:** `page`, `limit`, `search` (name).

Minimal SMS-only example:

<Warning>
  **`templates:*`** scopes are for **management**. On **send**, each channel needs its send scope (including `voice:call` for voice).
</Warning>

## Metaplantillas oficiales (`WHATSAPP_OFFICIAL`)

`POST /v1/templates` y `PATCH /v1/templates/:id` utilizan las **mismas validaciones** que el panel:

* medios requeridos en el encabezado/carrusel (`META_TEMPLATE_MEDIA_REQUIRED`)
* tarjetas de carrusel con la misma estructura (`META_TEMPLATE_CAROUSEL_INCONSISTENT`)
* estructura rica solo en plantillas oficiales (`TEMPLATE_META_STRUCTURE_REQUIRES_OFFICIAL`)

Al **enviar** (`POST /v1/templates/send` o `type: "template"` en cada ruta de canal) con `sk_live_`, la API también valida el Meta token, **`metaName`**, los medios y el carrusel **antes** de hacer cola cuando el canal es WhatsApp oficial. Con `sk_test_`, esas Meta puertas **no** se ejecutan (consulte [Sandbox](/es/guides/sandbox/index)).

Cada ruta de canal (`POST /v1/sms/messages`, `/v1/email/messages`, `/v1/whatsapp/messages`, etc.) acepta `type: "template"` + `payload.templateId` y activa **sólo** ese canal, lo que resulta útil cuando ya utiliza el contrato de canal nativo.

El **`name`** interno puede diferir de **`metaName`** (nombre del gráfico). Sin un `metaName` → `META_TEMPLATE_NOT_FOUND` resoluble.

Códigos completos: [Respuestas de error](/es/guides/conceitos/resposta-de-erros) (**Meta Cloud / plantillas oficiales** acordeón) y [Metaplantillas oficiales](/es/template-api/como-funciona/templates-oficiais-meta).

Esquemas completos: **Referencia de API** en la pestaña Plantillas.

***

## Ver también

* [Introducción](/es/template-api/como-funciona/introducao)
* [Inicio rápido](/es/template-api/como-funciona/quick-start)
* [Respuestas de error](/es/guides/conceitos/resposta-de-erros)
* [Metaplantillas oficiales](/es/template-api/como-funciona/templates-oficiais-meta)
