smartchat

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.

CodeBedeutung
plan_expiredDie plan_id ist älter als 10 Minuten. Mache Schritt 3a noch einmal.
plan_already_usedDie plan_id wurde schon genutzt. Mache Schritt 3a noch einmal.
plan_changedDer Entwurf hat sich nach der Vorschau geändert. Mache Schritt 3a noch einmal.
landing_not_publishableDie Prüfung hat Probleme gefunden. Lies issues, behebe den Entwurf und versuche es noch einmal.