Skip to main content

Overview

You can update a formula’s name, targeting settings, schedule, and more using the update endpoint. To replace the message structure or add new alternates, use the message-content endpoints.

Updating Formula Metadata

POST /formulas/{formula_id}/update
All fields are optional — only include the fields you want to change.
FieldTypeDescription
namestringThe display name of the formula
deeplinkstringDeep link URL for the message CTA
send_startdatetimeISO 8601 datetime when delivery becomes eligible
send_stopdatetimeISO 8601 datetime when delivery stops
send_start_datedateDate-only version of send start
send_stop_datedateDate-only version of send stop
is_controlled_messagebooleanWhether this is a controlled A/B test message
timezonestringIANA timezone string (e.g. "America/New_York")
audience_iduuidTarget audience segment
topic_iduuidTopic association
tagsarray of uuidsReplace all tag associations
labelsarrayReplace formula-level label associations
compound_trigger_iduuidCompound trigger rule for delivery
dataset_idintegerDataset used for user-level personalization
override_provider_frequency_limitsbooleanBypass provider-level send frequency caps
additional_metadataobjectFree-form metadata

Example: Rename a formula and set a schedule

import requests

BASE_URL  = "https://composer.api.aampe.com/api"
headers   = {"X-API-KEY": "YOUR_API_KEY", "Content-Type": "application/json"}
FORMULA_ID = 215

response = requests.post(
    f"{BASE_URL}/formulas/{FORMULA_ID}/update",
    headers=headers,
    json={
        "name":      "Welcome Back Campaign — Spring",
        "send_start": "2026-04-10T09:00:00Z",
        "send_stop":  "2026-04-30T23:59:59Z",
        "timezone":   "America/New_York",
    },
)
response.raise_for_status()
print(f"Updated: {response.json()['name']}")

Replacing the Message Structure

To replace what a formula’s message looks like — its slots and seed variants — update the message-content directly:
PUT /message-contents/{message_content_id}
This is a full replacement. Include every section and slot you want to keep — anything omitted will be removed.

Step 1 — Get the message-content ID

mc_resp = requests.get(
    f"{BASE_URL}/formulas/{FORMULA_ID}/message-contents",
    headers=headers,
)
mc_resp.raise_for_status()
message_content_id = mc_resp.json()[0]["id"]

Step 2 — Replace the structure

Pre-generate a component instance ID for each slot. The text in children[0].text becomes the seed variant (first alternate) for that slot.
import uuid

CT_OFFERING = "8e3f0698-7564-4522-9c07-49686667c0b4"
CT_CTA      = "8c0b9b73-b305-4f93-b41f-bde62cebac98"

header_component_id = str(uuid.uuid4())
body_component_id   = str(uuid.uuid4())

response = requests.put(
    f"{BASE_URL}/message-contents/{message_content_id}",
    headers=headers,
    json={
        "id": message_content_id,
        "structure": [
            {
                "kind": "section",
                "sectionType": "header",
                "children": [
                    {
                        "id":          header_component_id,
                        "kind":        "variant",
                        "variantType": "Offering",
                        "componentId": CT_OFFERING,
                        "children":    [{"text": "Spring is here, {{first_name}}!"}],
                    }
                ],
            },
            {
                "kind": "section",
                "sectionType": "body",
                "children": [
                    {
                        "id":          body_component_id,
                        "kind":        "variant",
                        "variantType": "CallToAction",
                        "componentId": CT_CTA,
                        "children":    [{"text": "Check out what's new."}],
                    }
                ],
            },
        ],
        "deeplink": None,
        "deeplink_dataset_field_id": None,
    },
)
response.raise_for_status()
After replacing the structure, add more alternates via POST /variants/create/bulk using the component instance IDs.

Adding Alternates to an Existing Formula

To add alternates to a formula without touching the structure, first fetch the existing component instance IDs from the message-content, then bulk-create:
# Get the existing structure to find component instance IDs
mc_detail = requests.get(
    f"{BASE_URL}/message-contents/{message_content_id}",
    headers={"X-API-KEY": "YOUR_API_KEY"},
)
mc_detail.raise_for_status()
structure = mc_detail.json()["structure"]

# Build a map: variantType → component instance ID
slot_ids = {}
for section in structure:
    for child in section.get("children", []):
        if child.get("kind") == "variant":
            slot_ids[child["variantType"]] = child["id"]

# Add new alternates
requests.post(
    f"{BASE_URL}/variants/create/bulk",
    headers={"X-API-KEY": "YOUR_API_KEY", "Content-Type": "application/json"},
    json=[
        {"component_id": slot_ids["Offering"], "content": "New spring deals await.", "label_id": 104},
        {"component_id": slot_ids["Offering"], "content": "Your seasonal picks are here.", "label_id": 105},
    ],
).raise_for_status()

Finding a Formula ID

Formulas are listed by lifecycle category and message type:
import requests

BASE_URL = "https://composer.api.aampe.com/api"
headers  = {"X-API-KEY": "YOUR_API_KEY"}

for category in ("Draft", "Live"):
    resp = requests.get(
        f"{BASE_URL}/formulas/category/{category}",
        headers=headers,
        params={"message_type": "push"},
    )
    resp.raise_for_status()
    for f in resp.json():
        print(f"[{category}] ID: {f['id']}  Name: {f['name']}")