Skip to main content

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:
PropertyDescription
nameThe display name shown in the Composer UI
message_typeThe channel — push, SMS, email, in-app, etc.
statusThe current lifecycle state — Draft, Review, Approved, Live, etc.
labelsTags that describe the formula’s overall intent and which component types they apply to
topic_idThe topic this message belongs to
audience_idAn optional segment filter controlling who can receive it
send_startOptional delivery window start
The message structure and all actual copy live in the message-content record, which is a separate object automatically created alongside the formula.

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.
Formula  →  created via POST /formulas
               └── message-content  →  auto-created, fetched via GET /formulas/{id}/message-contents
                     ├── structure  →  set via PUT /message-contents/{id}
                     └── variants   →  created via POST /variants or POST /variants/create/bulk
You’ll need the message-content ID for most content operations:
EndpointWhat it does
GET /formulas/{id}/message-contentsReturns 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}/variantsLists 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’s structure 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 a component_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 same component_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.
Formula
└── message-content
      ├── structure
      │     ├── slot: header  (component instance id = X)  ← seed text auto-creates first alternate
      │     └── slot: body    (component instance id = Y)
      └── variants
            ├── component_id = X, label = Calm       ← alternate 1 for header (seed)
            ├── component_id = X, label = Breathe    ← alternate 2 for header
            ├── component_id = X, label = Stillness  ← alternate 3 for header
            ├── component_id = Y, label = Science    ← alternate 1 for body (seed)
            └── component_id = Y, label = Sleep      ← alternate 2 for body
This formula produces 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:
NameTypeSourceUsed in
Component type IDUUIDGET /component-typesidcomponentId in structure nodes; identifies what kind of content a slot holds
Component instance IDUUIDYou generate with uuid.uuid4()Variant node id in the structure; component_id when creating variants
The component type ID says what kind of slot this is (e.g. Offering, CallToAction). The component instance ID says which specific slot in this message a variant belongs to.

Formula Lifecycle

Draft → Review → Approved → Live / Scheduled / Expired

                 Archived
Only formulas in Approved or Live status are eligible for delivery. Formulas stay in Draft until explicitly submitted for review.