# Die Landingpage bearbeiten

> Lies den Katalog und die Seite, ändere den Entwurf mit Operationen und schalte sie in zwei Aufrufen mit dem zusätzlichen Recht live.

Stand: 2026-10-30. Quelle: https://docs.smartchat.marketing/de/guides/build-a-landing-page/

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

```bash
curl "https://api.smartchat.marketing/v1/landing-catalog" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
```

**Python**

```python
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())
```

**TypeScript**

```typescript
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):


```json
{
  "object": "landing_catalog",
  "version": "2d26379cee484580",
  "operations": [
    {
      "type": "replace_text"
    }
  ]
}
```

**curl**

```bash
curl "https://api.smartchat.marketing/v1/landing-page?include=text" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
```

**Python**

```python
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())
```

**TypeScript**

```typescript
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):


```json
{
  "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`](https://docs.smartchat.marketing/de/errors/#landing_ops_rejected)). Die Live-Seite ändert sich noch nicht; die Antwort sagt `has_draft: true`.

**curl**

```bash
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"
    }
  ]
}'
```

**Python**

```python
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())
```

**TypeScript**

```typescript
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):


```json
{
  "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`](https://docs.smartchat.marketing/de/errors/#landing_not_publishable). Die `plan_id` gilt 10 Minuten und lässt sich einmal nutzen.

**curl**

```bash
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 '{}'
```

**Python**

```python
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())
```

**TypeScript**

```typescript
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):


```json
{
  "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**

```bash
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"
}'
```

**Python**

```python
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())
```

**TypeScript**

```typescript
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):


```json
{
  "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`](https://docs.smartchat.marketing/en/api/reference/landing/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`](https://docs.smartchat.marketing/de/errors/#plan_expired) | Die `plan_id` ist älter als 10 Minuten. Mache Schritt 3a noch einmal. |
| [`plan_already_used`](https://docs.smartchat.marketing/de/errors/#plan_already_used) | Die `plan_id` wurde schon genutzt. Mache Schritt 3a noch einmal. |
| [`plan_changed`](https://docs.smartchat.marketing/de/errors/#plan_changed) | Der Entwurf hat sich nach der Vorschau geändert. Mache Schritt 3a noch einmal. |
| [`landing_not_publishable`](https://docs.smartchat.marketing/de/errors/#landing_not_publishable) | Die Prüfung hat Probleme gefunden. Lies `issues`, behebe den Entwurf und versuche es noch einmal. |
