What Is a Formula?
A formula is the API’s internal representation of a message in Composer. Every message you see listed in the Composer UI corresponds to exactly one formula under the hood. When you open a message in Composer, browse its alternates, or trigger a send — you are interacting with a formula and the variants attached to it.What a Formula Contains
A formula captures everything needed to describe a message:| Property | Description |
|---|---|
name | The display name shown in the Composer UI |
message_type | The channel — push, SMS, email, in-app, etc. |
status | The current lifecycle state — Draft, Review, Approved, Live, etc. |
labels | Tags that describe the formula’s overall intent and which component types they apply to |
topic_id | The topic this message belongs to |
audience_id | An optional segment filter controlling who can receive it |
send_start | Optional delivery window start |
Message-Content
Every formula has exactly one message-content record. This is where the structure (the slot layout) and all variants (the actual copy) live — not on the formula itself. The formula is the container: name, channel, status, targeting. The message-content is the payload: what the message looks like and what it says. When you create a formula, the API automatically creates a message-content record alongside it. You then set the structure and variants on that record directly.| Endpoint | What it does |
|---|---|
GET /formulas/{id}/message-contents | Returns the message-content ID |
PUT /message-contents/{id} | Sets or replaces the structure and seed variants |
GET /message-contents/{id} | Reads the current structure |
GET /message-contents/{id}/variants | Lists all variants |
Structure, Variants, Components, and Alternates
These four concepts work together to describe a message and all the ways it can be personalized.Structure and Slots
The message-content’sstructure defines the skeleton of the message — what slots exist (header, body, etc.) and what type of content each slot holds. It does not contain the message text itself.
Each slot is one variant node in the structure. The node’s id is the component instance ID — a UUID you generate that identifies the slot and ties all its alternates together.
Variants
A variant is a single piece of message copy for a slot. It has a label, a text value, and acomponent_id pointing to the slot it belongs to. Every slot has at least one variant — the seed variant, which is set inline in the structure when you first define it.
Components
A component is a slot, identified by its component instance ID. In the Composer UI, a component appears as a single content block within a message that shows how many alternates it has. All variants sharing the samecomponent_id belong to the same component.
Alternates
Alternates are the multiple variants grouped under a single component. If a header slot has three variants (Calm, Breathe, Stillness), those three are the alternates for that component. Aampe picks one alternate per component per send.3 × 2 = 6 unique message combinations.
The Two Component IDs
There are two distinct IDs named “component ID” in the system. Confusing them is the most common source of errors:| Name | Type | Source | Used in |
|---|---|---|---|
| Component type ID | UUID | GET /component-types → id | componentId in structure nodes; identifies what kind of content a slot holds |
| Component instance ID | UUID | You generate with uuid.uuid4() | Variant node id in the structure; component_id when creating variants |