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

# Concepts and System Objects

> What formulas are and how they map to the messages you see in Composer.

## 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                                                          |

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:

| 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'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:

| 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        |

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.
