Die Landingpage bearbeiten
Du brauchst landing:read und landing:write. Das Live-Schalten braucht landing:publish, das in der App ein eigenes Kästchen hat. Die Antworten auf dieser Seite gehören zu einer Geschichte: Der Text einer Bäckerei-Seite wird geändert und live geschaltet.
#1. Katalog und Seite lesen
Der Katalog listet die Bausteine und die Felder jedes Bausteins. Du wählst Bausteine und füllst Felder; du schreibst kein HTML.
curl "https://api.smartchat.marketing/v1/landing-catalog" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY"import os
import requests
response = requests.get(
"https://api.smartchat.marketing/v1/landing-catalog",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/landing-catalog", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
},
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "landing_catalog",
"version": "2d26379cee484580",
"operations": [
{
"type": "replace_text"
}
]
}curl "https://api.smartchat.marketing/v1/landing-page?include=text" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY"import os
import requests
response = requests.get(
"https://api.smartchat.marketing/v1/landing-page",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
params={
"include": "text",
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/landing-page?include=text", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
},
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "landing_page",
"status": "live",
"url": "https://example-shop.smartchat.marketing",
"structure": "free",
"language": "en",
"title": "Example Shop",
"description": "Fresh bread every morning.",
"has_draft": false,
"draft_changed_at": null,
"previous_version_available": true,
"previous_version_saved_at": "2026-10-29T18:00:00Z",
"never_offline": true,
"protected_parts": [
"signup",
"footer",
"cookie_banner"
],
"updated_at": "2026-10-29T18:00:00Z",
"text_blocks": [
{
"index": 0,
"text": "Fresh bread every morning"
}
]
}#2. Den Entwurf ändern
Du sendest eine Liste von Operationen. Wird eine Operation abgelehnt, wird nichts geändert und die Antwort listet die abgelehnten (landing_ops_rejected). Die Live-Seite ändert sich noch nicht; die Antwort sagt has_draft: true.
curl -X POST "https://api.smartchat.marketing/v1/landing-page/operations" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{
"type": "replace_text",
"find": "Fresh bread every morning",
"replace": "Fresh bread from 6 o'\''clock"
}
]
}'import os
import uuid
import requests
response = requests.post(
"https://api.smartchat.marketing/v1/landing-page/operations",
headers={
"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"operations": [
{
"type": "replace_text",
"find": "Fresh bread every morning",
"replace": "Fresh bread from 6 o'clock",
},
],
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/landing-page/operations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"operations": [
{
"type": "replace_text",
"find": "Fresh bread every morning",
"replace": "Fresh bread from 6 o'clock"
}
]
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "landing_page_operations",
"applied": 1,
"dry_run": false,
"diff": [
{
"operation": 0,
"field": "text",
"before": "Fresh bread every morning",
"after": "Fresh bread from 6 o'clock"
}
],
"has_draft": true
}#3. Live schalten
Das Live-Schalten braucht zwei Aufrufe. Beide sind PUT an dieselbe Adresse und beide brauchen einen Idempotency-Key, jedes Mal einen anderen.
3a. Vorschau. Rufe ohne plan_id auf. Nichts geht live. Die Antwort zeigt, wie viele Felder sich ändern, und listet Probleme (issues). Findet die Prüfung ein Problem, lautet die Antwort landing_not_publishable. Die plan_id gilt 10 Minuten und lässt sich einmal nutzen.
curl -X PUT "https://api.smartchat.marketing/v1/landing-page/publication" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'import os
import uuid
import requests
response = requests.put(
"https://api.smartchat.marketing/v1/landing-page/publication",
headers={
"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
"Idempotency-Key": str(uuid.uuid4()),
},
json={},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/landing-page/publication", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "landing_publish_plan",
"plan_id": "pln_9f8e7d6c5b4a43210fedcba987654321",
"expires_at": "2026-10-30T09:51:07Z",
"changed_fields": 1,
"issues": []
}3b. Live schalten. Rufe noch einmal mit der plan_id auf. Jetzt wird der Entwurf zur Live-Seite.
curl -X PUT "https://api.smartchat.marketing/v1/landing-page/publication" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"plan_id": "pln_9f8e7d6c5b4a43210fedcba987654321"
}'import os
import uuid
import requests
response = requests.put(
"https://api.smartchat.marketing/v1/landing-page/publication",
headers={
"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"plan_id": "pln_9f8e7d6c5b4a43210fedcba987654321",
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/landing-page/publication", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"plan_id": "pln_9f8e7d6c5b4a43210fedcba987654321"
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "landing_page",
"status": "live",
"url": "https://example-shop.smartchat.marketing",
"structure": "free",
"language": "en",
"title": "Example Shop",
"description": "Fresh bread every morning.",
"has_draft": false,
"draft_changed_at": null,
"previous_version_available": true,
"previous_version_saved_at": "2026-10-30T09:42:00Z",
"never_offline": true,
"protected_parts": [
"signup",
"footer",
"cookie_banner"
],
"updated_at": "2026-10-30T09:42:00Z"
}Die Live-Seite wird nie offline genommen und die vorherige Version bleibt gespeichert; du kannst sie mit restore_landing_page zurückholen. Das Zurückholen ersetzt einen nicht veröffentlichten Entwurf endgültig, deshalb wird es abgelehnt, außer du sendest discard_draft: true.
| Code | Bedeutung |
|---|---|
plan_expired | Die plan_id ist älter als 10 Minuten. Mache Schritt 3a noch einmal. |
plan_already_used | Die plan_id wurde schon genutzt. Mache Schritt 3a noch einmal. |
plan_changed | Der Entwurf hat sich nach der Vorschau geändert. Mache Schritt 3a noch einmal. |
landing_not_publishable | Die Prüfung hat Probleme gefunden. Lies issues, behebe den Entwurf und versuche es noch einmal. |