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.
How Multilanguage Works
Each formula can have one version of its content per language. These language versions are separate message-content records — each with its own structure and variants.
Formula
├── message-content (English — default)
│ ├── structure
│ └── variants: "Find your calm", "Breathe and begin", ...
└── message-content (German)
├── structure
└── variants: "Finde deine Ruhe", "Atme und beginne", ...
When Aampe sends a message, it selects the message-content that matches the user’s language. Each language version is personalized independently — Aampe learns label preferences per language.
Step 1 — List Available Languages
import requests
BASE_URL = "https://composer.api.aampe.com/api"
headers = {"X-API-KEY": "YOUR_API_KEY"}
response = requests.get(f"{BASE_URL}/languages", headers=headers)
response.raise_for_status()
for lang in response.json():
default = " (default)" if lang["is_default"] else ""
print(f"{lang['id']} {lang['name']}{default}")
Response:
[
{
"id": "4abd0bdd-9d63-44de-b9d1-affcd3f61bfc",
"name": "Default Language",
"is_default": true,
"status": "active"
}
]
Step 2 — Create a Language (if it doesn’t exist)
response = requests.post(
f"{BASE_URL}/languages",
headers={**headers, "Content-Type": "application/json"},
json={
"name": "German",
"description": "German language",
},
)
response.raise_for_status()
german_language_id = response.json()["id"]
| Field | Type | Required | Description |
|---|
name | string | Yes | Display name for the language |
description | string | No | Optional description |
Create the formula as normal. The API automatically creates a message-content for the default language. You will add the German message-content separately.
import uuid
CT_OFFERING = "8e3f0698-7564-4522-9c07-49686667c0b4"
CT_VALUE_PROPOSITION = "72150aa9-6b20-4d95-9659-0c05701ef7de"
headers_json = {**headers, "Content-Type": "application/json"}
formula_resp = requests.post(f"{BASE_URL}/formulas", headers=headers_json, json={
"name": "My Multilanguage Formula",
"message_type": "push",
"structure": [],
})
formula_resp.raise_for_status()
formula_id = formula_resp.json()["id"]
# Default language message-content is auto-created
mc_resp = requests.get(f"{BASE_URL}/formulas/{formula_id}/message-contents", headers=headers)
mc_resp.raise_for_status()
default_mc_id = mc_resp.json()[0]["id"]
Step 4 — Set the Default Language Content
Pre-generate component instance IDs. These identify the slots for the default language — each language uses its own component instance IDs.
en_header_cid = str(uuid.uuid4())
en_body_cid = str(uuid.uuid4())
requests.put(
f"{BASE_URL}/message-contents/{default_mc_id}",
headers=headers_json,
json={
"id": default_mc_id,
"structure": [
{
"kind": "section",
"sectionType": "header",
"children": [{
"id": en_header_cid,
"kind": "variant",
"variantType": "Offering",
"componentId": CT_OFFERING,
"labelId": 101,
"children": [{"text": "Find your calm"}],
}],
},
{
"kind": "section",
"sectionType": "body",
"children": [{
"id": en_body_cid,
"kind": "variant",
"variantType": "ValueProposition",
"componentId": CT_VALUE_PROPOSITION,
"labelId": 103,
"children": [{"text": "5 minutes a day reduces stress hormones 30%."}],
}],
},
],
"deeplink": None,
"deeplink_dataset_field_id": None,
},
).raise_for_status()
# Add remaining English alternates
requests.post(f"{BASE_URL}/variants/create/bulk", headers=headers_json, json=[
{"component_id": en_header_cid, "content": "Breathe and begin", "label_id": 102},
{"component_id": en_header_cid, "content": "A moment of stillness awaits", "label_id": 101},
{"component_id": en_body_cid, "content": "Fall asleep faster and wake up restored.", "label_id": 103},
]).raise_for_status()
Step 5 — Add a New Language Version
Create a new message-content for German by posting with formula_id and language_id:
de_mc_resp = requests.post(
f"{BASE_URL}/message-contents",
headers=headers_json,
json={
"formula_id": formula_id,
"language_id": german_language_id,
},
)
de_mc_resp.raise_for_status()
german_mc_id = de_mc_resp.json()["id"]
Then set its structure and variants the same way as the default language — using new component instance IDs:
de_header_cid = str(uuid.uuid4())
de_body_cid = str(uuid.uuid4())
requests.put(
f"{BASE_URL}/message-contents/{german_mc_id}",
headers=headers_json,
json={
"id": german_mc_id,
"structure": [
{
"kind": "section",
"sectionType": "header",
"children": [{
"id": de_header_cid,
"kind": "variant",
"variantType": "Offering",
"componentId": CT_OFFERING,
"labelId": 101,
"children": [{"text": "Finde deine Ruhe"}],
}],
},
{
"kind": "section",
"sectionType": "body",
"children": [{
"id": de_body_cid,
"kind": "variant",
"variantType": "ValueProposition",
"componentId": CT_VALUE_PROPOSITION,
"labelId": 103,
"children": [{"text": "5 Minuten täglich senken Stresshormone um 30%."}],
}],
},
],
"deeplink": None,
"deeplink_dataset_field_id": None,
},
).raise_for_status()
requests.post(f"{BASE_URL}/variants/create/bulk", headers=headers_json, json=[
{"component_id": de_header_cid, "content": "Atme und beginne", "label_id": 102},
{"component_id": de_header_cid, "content": "Ein Moment der Stille erwartet dich", "label_id": 101},
{"component_id": de_body_cid, "content": "Schlaf schneller ein und wache erholt auf.", "label_id": 103},
]).raise_for_status()
Reading Back All Language Versions
all_mc = requests.get(
f"{BASE_URL}/formulas/{formula_id}/message-contents",
headers=headers,
).json()
for mc in all_mc:
lang_id = mc["language_id"]
mc_id = mc["id"]
variants = requests.get(f"{BASE_URL}/message-contents/{mc_id}/variants", headers=headers).json()
print(f"Language: {lang_id} — {len(variants)} variants")
Key Points
- The default language’s message-content is auto-created with the formula — do not create it manually
- Each language version uses its own component instance IDs (the UUIDs you generate per slot)
- Labels and component types are shared across languages — you do not need to recreate them
- Each language version is personalized independently by Aampe