# Attributes

## Overview

Attributes are the variables you drop into a message body — an order ID, a coupon code, a tracking URL, an appointment time — so one template personalises itself for every recipient. They are your reusable merge fields, and they exist because WhatsApp Business templates only accept positional placeholders, not named ones.

Open it from the More menu under Attributes. The page lists every attribute in the workspace with its name, key, default value, description, and status, plus a side rail to filter by status, a search box, and a list / grid toggle.

What | Detail
--- | ---
Where to find it | More menu → Attributes
Page size | 12 per page.
Scope | Per workspace — everyone on the team shares the same set of variables.
In the picker | Only active attributes appear when you insert a variable.

> Shared by workspace: attributes belong to the workspace, not to one person, so different workspaces never see each other's definitions.

## Built-in vs. custom variables

There are two kinds of variable you'll use while composing:

Kind | Where the value lives | Examples
--- | --- | ---
Built-in contact fields | Already stored on every contact record. | first name, full name, mobile, email, language
Custom attributes | Defined here on the Attributes page; filled in when you send from the contact's saved data (or the attribute's default). | order ID, tracking URL, discount code, appointment time

- You don't create built-in fields — they come from the contact. You only manage custom attributes on this page.
- The slash picker lists your active custom attributes for insertion. Standard contact fields are inserted by the message editor itself.

> When to add one: if the value you want to personalise isn't a standard contact field, create a custom attribute for it. Otherwise just use the built-in field.

## Creating an attribute

1. Click New attribute to open the create modal.
2. Enter a display name and a key (both required).
3. Optionally set a default value and a description.
4. Leave Active on (the default) so the attribute appears in the slash picker, or turn it off to keep it defined but hidden.
5. Save. It appears at the top of the table.

### Field reference

Field | Required | Limit / rule | Notes
--- | --- | --- | ---
Display name | Yes | Max 120 chars | The friendly label shown in the slash picker (for example "Order ID").
Key | Yes | Max 64, letters / digits / `_` / `-`, unique in the workspace | The short name used behind the scenes. Use lowercase with underscores, e.g. `order_id`.
Default value | No | Max 255 chars | Used when a contact is missing this value at send time.
Description | No | Max 500 chars | A short note on what the attribute means.
Active | No | On / off (default on) | When on, the attribute appears in the slash picker. Off hides it from the picker but keeps the definition.

> The key can't change. Once created, the key is read-only — the edit modal disables that field on purpose, because the key is already referenced in your templates and messages. You can rename the display name, edit the default and description, and flip Active, but not the key. To change a key, create a new attribute and update your templates.

## Inserting attributes with the slash picker

To use an attribute, type `/` in any compose-aware message body — templates, broadcasts, WhatsApp campaigns, and the flow builder. A picker opens listing your active attributes.

Key | Action
--- | ---
`/` | Open the attribute picker.
`Enter` | Insert the highlighted attribute.
`Esc` | Close the picker without inserting.

Picking an attribute inserts the next positional placeholder — `{{1}}`, `{{2}}`, and so on — into the body, not the attribute's key. At send time WaDesk substitutes the recipient's value for that slot (or the attribute's default when the value is missing).

## Why positional placeholders (Meta rules)

WhatsApp Business templates accept only positional placeholders — `{{1}}`, `{{2}}`, `{{3}}` — never named ones like `{{name}}`. That's why the slash picker inserts a number instead of the key: it keeps your message compliant with what Meta will approve.

- Don't type attribute keys directly into a template body. Always use the slash picker so it inserts `{{N}}`.
- Placeholders must be 1-based and contiguous: use `{{1}}`, `{{2}}`, `{{3}}` with no gaps and no jump to a higher number.

### How the check works

When you save a message that contains placeholders (in templates, broadcasts, or campaigns), WaDesk checks that the numbers you used run `1, 2, 3, …` in order with no gaps. If they don't, the save is blocked with the message:

> "Variable placeholders must be 1-based and contiguous (use {{1}}, {{2}}, {{3}}... no gaps)."

> Gaps are rejected. A body that jumps from `{{1}}` to `{{3}}` (skipping `{{2}}`), or that starts at `{{2}}`, will not save. Renumber so the placeholders run in order from 1. A body with no placeholders is always valid.

## Managing the list

The table is fully interactive without page reloads:

- Filter by status from the left rail: All, Active, Inactive. Each shows a live count.
- Search by name, key, or description; results update as you type (debounced).
- Edit a row to change its display name, default, description, or Active toggle (the key stays locked).
- Delete a row after a confirmation prompt.
- Three stat tiles summarise the workspace: Total, Active (show in picker), and Inactive (hidden from picker).

Status | Effect
--- | ---
Active | Appears in the slash picker while composing.
Inactive | Hidden from the picker; the definition (and any placeholders already in saved messages) is untouched.

## Best practices

- Always set a default value. If a contact is missing the value at send time, the default is used instead of the message failing or showing a blank slot.
- Use snake_case keys. Keep them short and consistent: `order_id`, `tracking_url`, `discount_code`, `appointment_at`.
- Deactivate instead of delete when retiring an attribute but keeping older templates working — toggle it off so it leaves the picker but the definition stays.

### Where attributes are used

The same active attributes are available everywhere you write a message — the slash picker works in:

- Templates (when creating a template)
- Broadcasts
- WhatsApp campaigns
- The Flow builder

## Troubleshooting

Symptom | Cause & fix
--- | ---
Attribute doesn't appear in the slash picker | It's inactive. Edit it and turn Active on — the picker only loads active attributes.
"Key already taken" on create | That key exists in this workspace (uniqueness is per workspace). Pick a different key.
Key field is greyed out | Expected — keys are immutable after creation. Create a new attribute to change the key.
Template won't save | Your placeholders aren't 1-based and contiguous. Renumber to `{{1}}`, `{{2}}`, ... with no gaps.
Recipient saw a blank where a variable should be | The contact had no value for that attribute and you set no default. Add a default value.
Key rejected as invalid | Keys allow only lowercase letters, digits, dash, and underscore, up to 64 characters.