
# Campaigns API

Eine Kampagne bündelt alles, was der KI-Bot benötigt, um mit Ihren Kontakten zu kommunizieren: seine Anweisungen, die Kanäle, auf denen er läuft, seine aktiven Zeiten und sein Follow-up-Verhalten. Die Campaigns API ermöglicht es Ihnen, Kampagnen direkt aus Ihrem eigenen Code heraus aufzulisten, zu erstellen, zu aktualisieren, zu duplizieren, zu aktivieren, zu archivieren und fein abzustimmen, anstatt dies über das Dashboard zu tun.

Alle unten aufgeführten Endpunkte beziehen sich auf die Basis-URL `https://api.youraiconnector.com/v1`. Jede Anfrage muss authentifiziert sein – siehe [API-Zugriff](../integrations/api-access.md) und [Authentifizierung](authentication.md), um zu erfahren, wie Sie Ihren API-Schlüssel erhalten und übergeben. Der API-Zugriff ist eine kostenpflichtige Funktion; ohne diesen werden Anfragen mit einem `403` abgelehnt.

> **Hinweis:** Einige Beispiele zeigen die einfache `?apiKey=YOUR_API_KEY`-Abfrageform, andere verwenden den `X-API-Key`-Header. Beide funktionieren überall – verwenden Sie die Variante, die am besten zu Ihrem Setup passt.

---

## Kampagnentypen

Wenn Sie eine Kampagne erstellen, müssen Sie einen dieser Typen auswählen:

| Typ | Verwendungszweck |
|---|---|
| `Incoming from Unknown Contacts` | Der Bot antwortet Personen, die Ihnen zum ersten Mal schreiben. |
| `Outgoing` | Der Bot beginnt Konversationen mit Kontakten, die Sie der Kampagne hinzufügen. |
| `Keywords` | **Inaktiv – nicht verwenden.** Eine `Keywords`-Kampagne ist inaktiv: Sie wird aus Gründen der Abwärtskompatibilität zwar noch akzeptiert, ist jedoch für das eingehende Routing auf allen Kanälen unsichtbar und ihre Trigger-Schlüsselwörter werden von nichts gelesen. Verwenden Sie stattdessen einen Einstiegspunkt vom Typ **Schlüsselwort** bei einem KI-Agenten. |
| `Combined` | Eine Mischung aus eingehendem und ausgehendem Verhalten. |

**Die Groß-/Kleinschreibung spielt keine Rolle.** `type`, `status`, `booking_provider`, `first_response_mode`, `bot.anthropic_model` und `bot.ai_speed` akzeptieren alle jede Schreibweise – `"live"`, `"Live"` und `"LIVE"` sind dasselbe – und der Wert wird in seiner kanonischen Form gespeichert, die zurückgegeben wird, wenn Sie die Kampagne lesen. Die einzige Ausnahme ist das Pausen-Paar: `"Paused"` und `"paused"` sind zwei grundlegend verschiedene Zustände, daher wird eine mehrdeutige Schreibweise wie `"PAUSED"` mit einem `400` abgelehnt, der Sie auffordert, eine Auswahl zu treffen.

### Die zwei Pausenstatus

| Status | Wer schreibt ihn | Was er bedeutet |
|---|---|---|
| `Paused` | Die eigenen Sicherheitsprüfungen der Plattform (geringes Engagement, wiederholte Sendefehler, ein erreichtes Limit) sowie die neueren Oberflächen für Agents und Broadcasts | Die Kampagne ist angehalten. Ein geplanter Durchlauf kann eine Sicherheitspause automatisch aufheben, sobald der Grund entfällt. |
| `paused` | Die Pause-Schaltfläche des Dashboards, gepaart mit `resumed` bei Fortsetzen | Eine Person hat die Kampagne manuell pausiert. Geplante Sendungen werden beim Fortsetzen verworfen und neu erstellt. |

Beide stoppen die Kampagne: Eingehendes Routing funktioniert nur, während der Status exakt `Live` ist. **Verwenden Sie über die API `Paused` zum Pausieren und `Live` zum Fortsetzen** – das kleingeschriebene Paar existiert für die Dashboard-Schaltfläche und wird für diese beibehalten.

Nichts davon entspricht dem, was passiert, wenn die KI innerhalb einer Konversation aufhört zu antworten. Dies ist ein Schalter pro Kontakt, `is_bot_active` beim Kontakt – gesetzt, wenn ein Mensch übernimmt, wenn der Kontakt sich abmeldet oder wenn die KI den Chat beendet. Der Status der Kampagne selbst bleibt unberührt, und jede andere Konversation darin läuft weiter. Siehe [KI für einen Kontakt pausieren oder fortsetzen](messages.md#pause-or-resume-the-ai-for-one-contact).

> **Das Erstellen einer Kampagne entscheidet nicht darüber, wer auf einen Kanal antwortet.** Das Routing wird von **Einstiegspunkten** bei einem KI-Agenten gesteuert, nicht von Kampagnen. Jeder Kanal hat einen standardmäßigen Kanal-Einstiegspunkt, der den Agenten benennt, der auf neue, unbekannte Kontakte antwortet: Legen Sie ihn mit `PUT /entry-points/channel-defaults` fest, prüfen Sie mit `GET /entry-points/routing-status`, ob die Leiter für das Konto aktiv ist, und löschen Sie ihn mit `DELETE /entry-points/channel-defaults`. `POST /channels/campaign` schreibt zwar weiterhin die alte Routing-Karte für Kampagnen pro Kanal, aber diese Karte wird für das eingehende Routing auf keinem Konto mehr herangezogen; sie wird nur noch für Rollbacks beibehalten. Bauen Sie nicht darauf auf. Siehe [Einen Kanal an eine Kampagne weiterleiten](channels.md#route-a-channel-to-a-campaign) für beide Oberflächen im Vergleich.

---

## Kampagnen auflisten

`GET /campaigns`

Gibt Ihre Kampagnen zurück, beginnend mit der neuesten. Archivierte Kampagnen sind ausgeschlossen, es sei denn, Sie übergeben `archived=true`.

**Abfrageparameter**

| Parameter | Erforderlich | Beschreibung |
|---|---|---|
| `limit` | Nein | Maximale Anzahl der zurückzugebenden Kampagnen. Standard `50`, Maximum `100`. |
| `cursor` | Nein | Paginierungs-Cursor. Übergeben Sie den `next_cursor`-Wert aus der vorherigen Antwort, um die nächste Seite zu erhalten. |
| `archived` | Nein | Auf `true` setzen, um archivierte Kampagnen einzubeziehen. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/campaigns?limit=20&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/campaigns?limit=20", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.campaigns, data.next_cursor);
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/campaigns",
    params={"limit": 20},
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["campaigns"], data["next_cursor"])
```

**Antwort**

```json
{
  "success": true,
  "campaigns": [
    {
      "id": "NBCXrhqGPSFsd6MV7pRo",
      "name": "Inbound WhatsApp Leads",
      "type": "Incoming from Unknown Contacts",
      "status": "Live",
      "enabled": true,
      "archived": false,
      "created_at": 1700000000000,
      "ai_mode": true,
      "language": "en",
      "enabled_channels": ["whatsapp", "instagram"]
    }
  ],
  "next_cursor": "NBCXrhqGPSFsd6MV7pRo"
}
```

Wenn `next_cursor` gleich `null` ist, haben Sie die letzte Seite erreicht.

---

## Eine Kampagne abrufen

`GET /campaigns/{campaignId}`

Gibt das vollständige Kampagnendokument zurück, einschließlich der Live-Bot-Konfiguration (`bot`), Follow-up-Einstellungen, aktivierten Kanälen und allen Schlüsselwörtern. Zeitstempel werden in Epochen-Millisekunden zurückgegeben.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const { campaign } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
campaign = res.json()["campaign"]
```

**Antwort**

```json
{
  "success": true,
  "campaign": {
    "id": "NBCXrhqGPSFsd6MV7pRo",
    "name": "Inbound WhatsApp Leads",
    "type": "Incoming from Unknown Contacts",
    "status": "Live",
    "language": "en",
    "ai_mode": true,
    "enabled": true,
    "archived": false,
    "created_at": 1700000000000,
    "enabled_channels": ["whatsapp", "instagram"],
    "bot": {
      "instructions": "Greet warmly and ask about their goals.",
      "goal": "Book a discovery call.",
      "ai_speed": "balanced",
      "anthropic_model": "standard",
      "max_messages": 20
    }
  }
}
```

::: note
**Hinweis:** Eine Kampagne, die einem anderen Konto gehört, gibt `404 Campaign not found` (nicht `403`) zurück, sodass Sie nicht feststellen können, ob eine ID in einem anderen Konto existiert.
:::


---

## Eine Kampagne erstellen

`POST /campaigns`

Erstellt eine neue Kampagne. `name` und `type` sind erforderlich; alles andere ist optional. Sie können jedes andere Kampagnenfeld in dieselbe Anfrage aufnehmen – zum Beispiel `language`, `ai_mode` oder ein vollständiges `bot`-Konfigurationsobjekt –, und es wird mit der neuen Kampagne gespeichert. Der Eigentümer und die Erstellungszeit werden automatisch festgelegt.

**Anfragefelder**

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `name` | Ja | Der Name der Kampagne. |
| `type` | Ja | Einer der vier oben genannten Kampagnentypen. |
| `language` | Nein | Sprache, in der der Bot antwortet (z. B. `"en"`). |
| `ai_mode` | Nein | Ob der KI-Modus aktiviert ist (`true`/`false`). Bei einer Kampagne, die von einem KI-Agenten beantwortet wird, geben Lesevorgänge den **Aktiv**-Status des Agenten zurück anstelle eines gespeicherten Wertes – siehe den Hinweis unter „Aktualisieren“ weiter unten. |
| `bot` | Nein | Das Bot-Konfigurationsobjekt (siehe [Bot-Konfigurationsfelder](#bot-configuration-fields)). |
| `list_id` | Nein | ID der zu verknüpfenden Kontaktliste. |
| `event_id` | Nein | ID des Ereignistyps, den die KI buchen darf. |
| `event_ids` | Nein | Mehrere Ereignistypen gleichzeitig als Array von Ereignistyp-IDs – der erste ist der Standardwert. Senden Sie entweder `event_id` oder `event_ids`, nicht beides. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring Promo",
    "type": "Outgoing",
    "language": "en",
    "ai_mode": true,
    "bot": {
      "instructions": "Greet warmly and ask about their goals.",
      "goal": "Book a discovery call."
    }
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/campaigns", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Spring Promo",
    type: "Outgoing",
    language: "en",
    ai_mode: true,
    bot: {
      instructions: "Greet warmly and ask about their goals.",
      goal: "Book a discovery call.",
    },
  }),
});
const { campaign_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/campaigns",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "Spring Promo",
        "type": "Outgoing",
        "language": "en",
        "ai_mode": True,
        "bot": {
            "instructions": "Greet warmly and ask about their goals.",
            "goal": "Book a discovery call.",
        },
    },
)
campaign_id = res.json()["campaign_id"]
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

---

## Eine Kampagne aktualisieren

`PUT /campaigns/{campaignId}`

Aktualisiert eine Kampagne teilweise – senden Sie nur die Felder, die Sie ändern möchten. Dies ist das einzige allgemeine Update-Verb; es gibt kein `PATCH /campaigns/{campaignId}` (die beiden `PATCH`-Routen sind die spezifischen [Aktivieren](#enable-or-disable-a-campaign)- und [Archivieren](#archive-or-restore-a-campaign)-Umschalter).

**Welche Felder Sie ändern können.** Alles, was der Kampagnen-Editor schreibt, einschließlich `name`, `status`, `type`, `language`, `ai_mode`, `enabled_channels`, die Trigger- und Drip-Einstellungen, die Buchungs- und Follow-up-Flags, die Überwachungsfelder für Instagram/Facebook und die gesamte `bot`-Konfiguration. Identität und Eigentümerschaft sind für die Lebensdauer der Kampagne gesperrt: `user`, `id` und `created_at` werden abgelehnt, ebenso wie jeder Feldname, den der Endpunkt nicht erkennt. Die Ablehnung erfolgt pro Anfrage, nicht pro Feld – ein unbekannter Schlüssel führt zu einem `400` und **nichts** in dieser Anfrage wird geschrieben.

**`ai_mode` bei einer Agent-gestützten Kampagne spiegelt den Agenten wider.** Wenn eine Kampagne von einem KI-Agenten beantwortet wird, gibt das Lesen der Kampagne `ai_mode` zurück, das vom **Aktiv**-Schalter dieses Agenten abgeleitet ist – der einzige Schalter, der tatsächlich entscheidet, ob die KI antwortet. Das Schreiben von `ai_mode` bei einer solchen Kampagne wird akzeptiert, ändert jedoch nicht den Wert, den Sie beim Lesen zurückerhalten; schalten Sie stattdessen den Aktiv-Schalter des Agenten ein oder aus (im Dashboard oder über die Agents-API). Bei klassischen Kampagnen ohne Agent liest und schreibt `ai_mode` wie bisher den gespeicherten Wert.

**Bot-Felder werden zusammengeführt, nicht überschrieben.** Senden Sie Bot-Einstellungen entweder als punktierte Schlüssel (`"bot.instructions": "..."`) oder als verschachteltes Objekt (`"bot": { "instructions": "..." }`) – beide schreiben Feld für Feld, sodass die Felder, die Sie weglassen, ihre aktuellen Werte behalten. `bot.instructions`, `bot.goal`, `bot.rules` und `bot.personality` sind auf diese Weise editierbar, ebenso wie jede andere Bot-Einstellung, die unter [Bot-Konfigurationsfelder](#bot-configuration-fields) aufgeführt ist. Dasselbe gilt für `test_bot`, `frequency` und `follow_up_config`.

Um eine Bot-Konfiguration vollständig zu ersetzen – und dabei jedes Feld zu löschen, das Sie nicht senden – verwenden Sie `bot_replace` (oder `test_bot_replace`) mit dem vollständigen Objekt. Sie können ein Ersetzen und ein Zusammenführen für dasselbe Objekt nicht in einer Anfrage kombinieren; dies führt zu einem `400`.

::: note
**Hinweis:** Das Schreiben von `bot.*` über die API wird **sofort** auf die aktive Kampagne angewendet. Der Dashboard-Editor funktioniert anders: Änderungen dort werden als Entwurf gespeichert und gehen erst live, wenn der Kunde auf „Veröffentlichen“ klickt. Wenn ein Kunde also unveröffentlichte Dashboard-Änderungen hat, verbleiben diese in `test_bot` und ein API-Lesezugriff auf `bot` zeigt korrekt an, was die KI aktuell verwendet.
:::


Einige Felder werden über einen dedizierten Schlüssel festgelegt, anstatt direkt geschrieben zu werden: Verwenden Sie `list_id` für die Kontaktliste, `event_id` für den Ereignistyp (oder `event_ids`, ein geordnetes Array von Ereignistyp-IDs, damit die KI mehrere buchen kann – der erste ist der Standardwert; ein leeres Array hebt alle Verknüpfungen auf) und `contact_ids` (ein Array von Kontakt-IDs) für die Kontakte der Kampagne. Einträge in der Wissensdatenbank werden über die [FAQs-API](faqs.md) verwaltet, nicht über diesen Endpunkt.

**Tags ersetzen, sie werden nicht zusammengeführt.** Senden Sie `tags` als vollständiges Array, und es wird zum Tag-Satz der Kampagne – siehe [Kampagnen-Tags](#campaign-tags) für die Felder und die Endpunkte zum Hinzufügen oder Bearbeiten eines einzelnen Tags.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Spring Promo v2", "enabled_channels": ["whatsapp"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Spring Promo v2",
      enabled_channels: ["whatsapp"],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"name": "Spring Promo v2", "enabled_channels": ["whatsapp"]},
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

---

## Eine Kampagne löschen

`DELETE /campaigns/{campaignId}`

Löscht eine Kampagne dauerhaft. Dies kann nicht rückgängig gemacht werden – falls Sie die Kampagne möglicherweise später noch benötigen, [archivieren Sie sie](#archive-or-restore-a-campaign) stattdessen.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwort**

```json
{
  "success": true
}
```

---

## Eine Kampagne duplizieren

`POST /campaigns/{campaignId}/duplicate`

Erstellt eine Kopie der Kampagne, wobei alle Einstellungen beibehalten werden. Die Kopie ist zunächst **deaktiviert** und erhält ein `(copy)`-Suffix, sodass sie keine Nachrichten versendet, bis Sie sie explizit aktivieren.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/duplicate?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/duplicate",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const { campaign_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/duplicate",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
new_campaign_id = res.json()["campaign_id"]
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "aZ9plnewCopyId01234"
}
```

> Duplizierte Kopien **innerhalb eines Kontos**.

---


## Eine Kampagne aktivieren oder deaktivieren

`PATCH /campaigns/{campaignId}/enabled`

Schaltet eine Kampagne ein oder aus. Eine deaktivierte Kampagne hört auf, Kontakte anzusprechen, behält jedoch ihre gesamte Konfiguration bei.

**Anfragefelder**

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `enabled` | Ja | `true` zum Aktivieren, `false` zum Deaktivieren. Muss ein boolescher Wert sein. |

**cURL**

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/enabled?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/enabled",
  {
    method: "PATCH",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ enabled: true }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.patch(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/enabled",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"enabled": True},
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "enabled": true
}
```

---

## Kampagne archivieren oder wiederherstellen

`PATCH /campaigns/{campaignId}/archived`

Archiviert oder stellt eine Kampagne wieder her. Archivierte Kampagnen werden in der Standard-Kampagnenliste ausgeblendet, behalten jedoch alle ihre Daten und können jederzeit wiederhergestellt werden.

**Anfragefelder**

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `archived` | Ja | `true` zum Archivieren, `false` zum Wiederherstellen. Muss ein boolescher Wert sein. |

**cURL**

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/archived?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "archived": true }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/archived",
  {
    method: "PATCH",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ archived: true }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.patch(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/archived",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"archived": True},
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "archived": true
}
```

---

## Bot-Konfiguration aktualisieren

`PUT /campaigns/{campaignId}/bot-config`

Dies ist der sichere Weg, um einzelne Bot-Einstellungen zu ändern. Jedes Feld, das Sie senden, wird in die bestehende Bot-Konfiguration **integriert**; alle Felder, die Sie weglassen, bleiben erhalten. Verwenden Sie dies anstelle des Endpunkts für Kampagnen-Updates, wenn Sie nur einen Teil des Bots anpassen möchten.

Feld-Schlüssel dürfen nur Buchstaben, Zahlen, Unterstriche und Bindestriche enthalten.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/bot-config?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Always answer in a friendly, concise tone.",
    "ai_speed": "balanced"
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/bot-config",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      instructions: "Always answer in a friendly, concise tone.",
      ai_speed: "balanced",
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/bot-config",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "instructions": "Always answer in a friendly, concise tone.",
        "ai_speed": "balanced",
    },
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

### Felder der Bot-Konfiguration

Alle Bot-Felder sind optional. Senden Sie nur die Felder, die Sie festlegen möchten. Alle zusätzlichen Bot-Felder, die über die hier aufgeführten hinausgehen, werden akzeptiert und unverändert gespeichert.

| Feld | Typ | Beschreibung |
|---|---|---|
| `instructions` | string | Die primären Anweisungen, die steuern, wie der Bot mit Kontakten spricht. |
| `rules` | string | Strenge Regeln, die der Bot immer befolgen muss. |
| `goal` | string | Das Ergebnis, auf das der Bot in jeder Konversation hinarbeiten soll. |
| `personality` | string | Beschreibung von Tonfall und Persönlichkeit des Bots. |
| `ai_speed` | string | Wie viel Überlegung die KI vor einer Antwort anwendet. Einer der Werte `fast`, `fast_thinker`, `balanced`, `thorough`. |
| `anthropic_model` | string | Die KI-Qualitätsstufe, die für die Antworten dieser Kampagne verwendet wird. Einer der Werte `standard`, `economy` (veraltet), `max`, `mini`. `max` und `mini` sind nur für Konten wirksam, die für diese Stufen berechtigt sind. |
| `max_messages` | integer | Maximale Anzahl an Bot-Nachrichten pro Konversation. |
| `alert_human_when` | string | Bedingungen, unter denen der Bot einen menschlichen Teamkollegen alarmieren soll. |
| `availability` | object | Der Zeitplan für die aktiven Stunden des Bots. Sie können diesen hier festlegen oder den dedizierten [Endpunkt für aktive Stunden](#set-the-bot-active-hours) verwenden. |
| `follow_up_config` | object | Konfiguration des Folgeverhaltens, wie bereitgestellt gespeichert. |

---

## Aktive Stunden des Bots festlegen

`PUT /campaigns/{campaignId}/active-hours`

Legt den Verfügbarkeitszeitplan des Bots fest. Außerhalb der konfigurierten Zeitfenster antwortet der Bot nicht automatisch. Dies schreibt das Feld `availability` der Bot-Konfiguration.

**Anfragefelder**

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `availability` | Ja | Ein Objekt, das nach Wochentagen unterteilt ist. Zulässige Schlüssel sind `monday` bis `sunday`; jeder andere Schlüssel führt zu einem `400`. Tage, die Sie auslassen, bleiben unverändert. |

Jeder Wochentag enthält entweder ein einzelnes Zeitfenster oder ein Array von Fenstern. Ein Fenster hat einen `start_time` und `end_time` im 24-Stunden-`HH:MM`-Format.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/active-hours?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "availability": {
      "monday": { "start_time": "09:00", "end_time": "17:00" },
      "tuesday": [
        { "start_time": "09:00", "end_time": "12:00" },
        { "start_time": "13:00", "end_time": "17:00" }
      ]
    }
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/active-hours",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      availability: {
        monday: { start_time: "09:00", end_time: "17:00" },
        tuesday: [
          { start_time: "09:00", end_time: "12:00" },
          { start_time: "13:00", end_time: "17:00" },
        ],
      },
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/active-hours",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "availability": {
            "monday": {"start_time": "09:00", "end_time": "17:00"},
            "tuesday": [
                {"start_time": "09:00", "end_time": "12:00"},
                {"start_time": "13:00", "end_time": "17:00"},
            ],
        }
    },
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

---

## Benutzerdefinierte Funktionen einer Kampagne auflisten

`GET /campaigns/{campaignId}/custom-functions`

Gibt die mit dieser Kampagne verknüpften benutzerdefinierten Funktionen zurück, aufgelöst in vollständige Definitionen. Benutzerdefinierte Funktionen sind externe HTTP-Aktionen, die der Bot während eines Gesprächs aufrufen kann – zum Beispiel, um den Lagerbestand in Ihrem Shop zu prüfen oder einen Datensatz in Ihrem CRM zu erstellen.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/custom-functions?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/custom-functions",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const { custom_functions } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/custom-functions",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
custom_functions = res.json()["custom_functions"]
```

**Antwort**

```json
{
  "success": true,
  "custom_functions": [
    {
      "id": "fn_abc123",
      "name": "check_stock",
      "description": "Looks up whether a product is in stock.",
      "url": "https://example.com/api/stock",
      "method": "POST",
      "input": [
        { "name": "sku", "type": "string" }
      ],
      "ai_action": "Tell the customer whether the item is available.",
      "created_at": 1700000000000,
      "updated_at": 1700000500000
    }
  ]
}
```

---

## Verknüpfen einer benutzerdefinierten Funktion mit einer Kampagne

`POST /campaigns/{campaignId}/custom-functions`

Verknüpft eine bestehende [benutzerdefinierte Funktion](../ai-automation/custom-functions.md) mit dieser Kampagne, damit der Bot sie während eines Gesprächs aufrufen kann. Das Verknüpfen einer bereits verknüpften Funktion hat keine Auswirkungen.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `custom_function_id` | Ja | ID der zu verknüpfenden benutzerdefinierten Funktion. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/custom-functions?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_function_id": "fn_abc123" }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "custom_function_id": "fn_abc123"
}
```

---

## Aufheben der Verknüpfung einer benutzerdefinierten Funktion von einer Kampagne

`DELETE /campaigns/{campaignId}/custom-functions/{customFunctionId}`

Das Aufheben der Verknüpfung einer Funktion, die nicht verknüpft ist, hat keine Auswirkungen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/custom-functions/fn_abc123?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "custom_function_id": "fn_abc123"
}
```

---

## Verknüpfen einer Wissensdatenbankquelle mit einer Kampagne

`POST /campaigns/{campaignId}/kb-sources`

Verknüpft eine Wissensdatenbankquelle (erstellt über die [FAQs-API](faqs.md)) mit dieser Kampagne, damit der Bot bei der Beantwortung darauf zurückgreifen kann. Das Verknüpfen einer bereits verknüpften Quelle hat keine Auswirkungen.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `kb_source_id` | Ja | ID der zu verknüpfenden Wissensdatenbankquelle. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/kb-sources?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_id": "kb_abc123" }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "kb_source_id": "kb_abc123"
}
```

---

## Aufheben der Verknüpfung einer Wissensdatenbankquelle von einer Kampagne

`DELETE /campaigns/{campaignId}/kb-sources/{kbSourceId}`

Das Aufheben der Verknüpfung einer Quelle, die nicht verknüpft ist, hat keine Auswirkungen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/kb-sources/kb_abc123?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "kb_source_id": "kb_abc123"
}
```

---

## Verknüpfen eines MCP-Servers mit einer Kampagne

`POST /campaigns/{campaignId}/mcp-servers`

Verknüpft einen MCP-Server mit dieser Kampagne und gibt dem Bot während eines Gesprächs Zugriff auf die Tools dieses Servers. Das Verknüpfen eines bereits verknüpften Servers hat keine Auswirkungen.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `mcp_server_id` | Ja | ID des zu verknüpfenden MCP-Servers. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mcp_server_id": "mcp_abc123" }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "mcp_server_id": "mcp_abc123"
}
```

---

## Einen MCP-Server von einer Kampagne trennen

`DELETE /campaigns/{campaignId}/mcp-servers/{mcpServerId}`

Das Trennen eines Servers, der nicht verknüpft ist, hat keine Auswirkungen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/mcp-servers/mcp_abc123?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "mcp_server_id": "mcp_abc123"
}
```

---

## Medienbibliothek der Kampagne

Die Medienbibliothek enthält Bilder, Videos, Dokumente und Sprachnachrichten, die der Bot während eines Gesprächs senden kann.

### Medienbibliothek einer Kampagne auflisten

`GET /campaigns/{campaignId}/media-library`

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/media-library?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "media_items": [
    {
      "id": "media_abc123",
      "item_id": "media_abc123",
      "title": "Pricing sheet",
      "description": "Send when the contact asks about pricing.",
      "media_url": "https://example.com/pricing.pdf",
      "media_content_type": "application/pdf",
      "type": "document",
      "agent_id": "",
      "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
      "media_home": "campaign"
    }
  ]
}
```

`media_url` ist eine signierte URL, die zum Zeitpunkt des Hochladens erfasst wurde – sie könnte bereits abgelaufen sein, wenn Sie sie abrufen; das Dashboard signiert sie bei Bedarf neu.

### Ein Medienelement hochladen

`POST /campaigns/{campaignId}/media-library`

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `base64Data` | Ja | Die Datei, base64-kodiert (ohne data-URL-Präfix). |
| `mimeType` | Ja | MIME-Typ der Datei (z. B. `image/png`). |
| `title` | Ja | Kurze Bezeichnung, die in der Bibliothek und im KI-Prompt angezeigt wird. |
| `description` | Ja | Anweisung, die dem Bot mitteilt, **wann** dieses Element gesendet werden soll. |
| `fileName` | Nein | Ursprünglicher Dateiname, der zum Erstellen des Speicherobjektnamens verwendet wird. |
| `sendMessage` | Nein | Bevorzugte Formulierung, die der Bot beim Senden dieses Elements verwenden soll. |
| `maxSendsPerConversation` | Nein | Maximale Anzahl, wie oft der Bot dieses Element an einen Kontakt in einem Gespräch senden darf. Standardwert ist `1`. |
| `sendAsVoiceNote` | Nein | Bei einem Audio-Upload: Transkodierung in eine WhatsApp-Sprachnachricht. Standardwert ist `false` (als einfache Audiodatei gespeichert). |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/media-library?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base64Data": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mimeType": "image/png",
    "title": "Product photo",
    "description": "Send when the contact asks what the product looks like."
  }'
```

**Antwort**

```json
{
  "success": true,
  "itemId": "media_abc123",
  "mediaUrl": "https://example.com/product.png",
  "storagePath": "ai_media/campaigns/NBCXrhqGPSFsd6MV7pRo/media_abc123.png",
  "mediaContentType": "image/png",
  "type": "image",
  "isVoiceNote": false
}
```

### Ein Medienelement aktualisieren

`PATCH /campaigns/{campaignId}/media-library/{itemId}`

Bearbeitet nur die Metadaten des Elements – um die Datei selbst zu ersetzen, löschen Sie das Element und laden Sie ein neues hoch.

| Feld | Beschreibung |
|---|---|
| `title` | Kurze Bezeichnung. |
| `description` | Anweisung zum Sendezeitpunkt. |
| `send_message` | Bevorzugte Formulierung für den Bot. |
| `max_sends_per_conversation` | Nicht-negative Ganzzahl oder `null`, um das Limit aufzuheben. |

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/media-library/media_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Updated pricing sheet" }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "item_id": "media_abc123"
}
```

### Ein Medienelement löschen

`DELETE /campaigns/{campaignId}/media-library/{itemId}`

Das Löschen eines bereits entfernten Elements hat keine Auswirkungen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/media-library/media_abc123?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{ "success": true, "deleted": true }
```

---

## Kampagnen-Tags

Ein Kampagnen-Tag ist eine Bezeichnung, die Sie dem Bot beibringen, einem Kontakt während eines Gesprächs zuzuweisen – `hot-lead`, `not-interested`, `booked-a-call`. Jeder Tag besteht aus drei Teilen:

| Feld | Typ | Beschreibung |
|---|---|---|
| `name` | string, erforderlich | Die Bezeichnung selbst. Dies ist das, was der Bot dem Kontakt zuweist und worauf Sie später abgleichen, halten Sie es also kurz und stabil. |
| `description` | string | Die Anweisung, die dem Bot sagt, **wann** dieser Tag angewendet werden soll. Dies ist der Teil, der die Arbeit erledigt – "die Person bestätigt, dass sie der Community beigetreten ist" wird verwendet, "heißer Lead" nicht. |
| `webhook` | string | Eine URL, die einen `POST` empfängt, sobald der Tag einem Kontakt zugewiesen wird. Lassen Sie dies weg, wenn Sie keine benötigen. |
| `tag_id` | string | Optional. Verknüpft diesen Eintrag mit einem bestehenden Tag in Ihrem Konto anstelle eines neuen. Geben Sie dies an, wenn Sie diesen spezifischen Tag später mit den unten aufgeführten Einzel-Tag-Endpunkten adressieren möchten. |

Tag-Namen müssen innerhalb einer Kampagne eindeutig sein. Der Bot wendet Tags **nach Namen** an, daher haben zwei Einträge, die sich einen Namen teilen, keinen definierten Gewinner.

### Alle Tags einer Kampagne festlegen

`PUT /campaigns/{campaignId}` mit einem `tags` Array.

Dies ersetzt die Tags der Kampagne durch genau das, was Sie senden, was dasselbe ist, was die Registerkarte „Tags“ im Dashboard tut, wenn Sie sie speichern. **Senden Sie jedes Mal das vollständige Array** – ein Tag, den Sie weglassen, ist ein gelöschter Tag. Das Senden von `[]` löscht alle.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tags": [
      {
        "name": "hot-lead",
        "description": "The person confirms they want to buy, or asks how to get started right away.",
        "webhook": "https://example.com/hooks/campaign-events"
      },
      {
        "name": "not-interested",
        "description": "The person declines the offer or says they are not a fit."
      }
    ]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      tags: [
        {
          name: "hot-lead",
          description:
            "The person confirms they want to buy, or asks how to get started right away.",
          webhook: "https://example.com/hooks/campaign-events",
        },
        {
          name: "not-interested",
          description: "The person declines the offer or says they are not a fit.",
        },
      ],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "tags": [
            {
                "name": "hot-lead",
                "description": "The person confirms they want to buy, or asks how to get started right away.",
                "webhook": "https://example.com/hooks/campaign-events",
            },
            {
                "name": "not-interested",
                "description": "The person declines the offer or says they are not a fit.",
            },
        ]
    },
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

Lesen Sie die Tags mit [`GET /campaigns/{campaignId}`](#get-a-campaign) zurück.

### Einen Tag hinzufügen

`POST /campaigns/{campaignId}/tags`

Hängt einen einzelnen Tag an, ohne den Rest erneut zu senden. Verwenden Sie dies, wenn Sie eine Menge ergänzen, die Sie nicht in dieser Anfrage erstellt haben.

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tag": { "name": "booked-a-call", "description": "The person confirms a booked time." } }'
```

Das zweimalige Posten desselben Tags bewirkt beim zweiten Mal nichts. Das Posten desselben `tag_id` mit einem anderen Namen oder einer anderen Beschreibung hängt einen **zweiten** Eintrag an, anstatt den ersten zu bearbeiten – verwenden Sie den unten stehenden Endpunkt, um direkt zu bearbeiten.

### Einen Tag aktualisieren oder entfernen

`PUT /campaigns/{campaignId}/tags/{tagId}`
`DELETE /campaigns/{campaignId}/tags/{tagId}`

Diese adressieren einen Eintrag über seine `tag_id`, daher funktionieren sie nur bei Tags, die mit einer solchen erstellt wurden. Wenn ein Tag keine `tag_id` hat, ändern Sie diese mit der oben genannten `PUT /campaigns/{campaignId}` für das gesamte Array.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/tags/tag_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tag": { "name": "hot-lead", "description": "Updated instruction." } }'
```

Ein `tagId`, der sich nicht in der Kampagne befindet, gibt `404` mit `"Tag not found in campaign tags"` zurück.

---

## Kanäle einer Kampagne umschalten

`POST /campaigns/{campaignId}/channels`

Fügt Kanäle zum `enabled_channels`-Array der Kampagne hinzu oder entfernt sie, ohne das gesamte Array erneut zu senden – sicherer als [`PUT /campaigns/{campaignId}`](#update-a-campaign), wenn gleichzeitig andere Änderungen an der Kampagne vorgenommen werden könnten.

Senden Sie entweder einen einzelnen Umschaltbefehl oder einen Batch – nicht beides in derselben Anfrage:

```json
{ "channel": "whatsapp", "action": "add" }
```

```json
{ "add": ["whatsapp", "instagram"], "remove": ["sms"] }
```

| Feld | Beschreibung |
|---|---|
| `channel` | Ein einzelner Kanal zum Umschalten. Zusammen mit `action` verwenden. |
| `action` | `"add"` oder `"remove"`. Zusammen mit `channel` verwenden. |
| `add` | Array der hinzuzufügenden Kanäle. Batch-Form – anstelle von `channel`/`action` verwenden. |
| `remove` | Array der zu entfernenden Kanäle. Batch-Form. |

Gültige Kanäle: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `facebook`, `chat_widget`, `custom_channel`, `imessage`, `telegram`, `instagram_private`, `line`, `viber`, `tiktok`, `email`, `linkedin`, `skool`.

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/channels?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "whatsapp", "action": "add" }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "added": ["whatsapp"],
  "removed": []
}
```

> Dies ändert nur, über welche Kanäle die Kampagne beworben wird – es entscheidet nicht darüber, wer auf einen Kanal antwortet. Siehe dazu [Kampagnentypen](#campaign-types) oben und [Kampagne an eingehende Kanäle weiterleiten](#route-a-campaign-to-incoming-channels) unten.

---

## Kommentar-zu-DM (Instagram und Facebook)

Kommentar-zu-DM verwandelt einen Kommentar unter einem Ihrer Beiträge in eine private Unterhaltung: Jemand kommentiert, der Bot sendet eine Direktnachricht (DM) und die Kampagne übernimmt ab diesem Punkt die Unterhaltung. Dies wird vollständig über das Kampagnenobjekt konfiguriert, es gibt also keinen reinen UI-Teil dabei.

Verbinden Sie zuerst die Facebook-Seite – siehe [Kanalverbindung](channels.md#instagram--messenger-meta). Legen Sie dann die unten stehenden Felder mit [`PUT /campaigns/{campaignId}`](#update-a-campaign) fest.

> **Die Kampagne muss `Live` sein.** Die Kommentarüberwachung erfasst nur Kampagnen, deren `status` auf `Live` gesetzt ist (beliebige Groß-/Kleinschreibung – siehe [Kampagnentypen](#campaign-types)). Jeder andere Status deaktiviert sie stillschweigend, und ein erfundener Status wie `"Active"` wird jetzt mit einem `400` abgelehnt, anstatt gespeichert zu werden. Gültige Status sind unter anderem `Draft`, `Pending Approval`, `Scheduled`, `Live`, `Paused`, `Completed`, `Sent` und `Failed`.

**Felder**

| Feld | Typ | Beschreibung |
|---|---|---|
| `monitor_instagram_posts` | boolean | Überwache jeden Instagram-Beitrag auf der verbundenen Seite. |
| `instagram_post_ids` | string[] | Überwache nur diese Instagram-Beiträge. Leer lassen, wenn `monitor_instagram_posts` aktiviert ist. |
| `instagram_comment_delay_minutes` | number | Warte so viele Minuten nach einem Kommentar, bevor die DM gesendet wird. |
| `monitor_facebook_posts` | boolean | Überwache jeden Facebook-Beitrag auf der verbundenen Seite. |
| `facebook_post_ids` | string[] | Überwache nur diese Facebook-Beiträge. |
| `facebook_comment_delay_minutes` | number | Verzögerung vor der DM, in Minuten. |
| `public_comment_reply_instructions` | string | Anleitung für die sichtbare Antwort, die unter dem Kommentar selbst hinterlassen wird. Überschreibt den Standardtext "Check deine DMs". |
| `first_response_mode` | string | `"ai"` (Standard) generiert die erste DM und die öffentliche Antwort. `"exact_text"` sendet deinen Wortlaut wortwörtlich, ohne KI-Generierung und ohne Guthabenverbrauch. |
| `first_response_exact_text` | string | Die wortwörtliche erste DM, verwendet wenn `first_response_mode` auf `"exact_text"` steht. Erforderlich, damit dieser Modus wirksam wird. |
| `first_response_exact_text_variants` | string[] | Zusätzliche Formulierungen für die erste DM. Eine wird pro Versand zufällig ausgewählt, sodass wiederholte DMs nicht byte-identisch sind. |
| `public_comment_reply_exact_text` | string | Die wortwörtliche öffentliche Antwort im `"exact_text"`-Modus. Leer lassen, um die öffentliche Antwort zu überspringen und nur die DM zu senden. |
| `public_comment_reply_exact_text_variants` | string[] | Zusätzliche Formulierungen für die öffentliche Antwort. |
| `monitor_instagram_followers` | boolean | Behandle einen neuen Follower als Auslöser und sende eine erste DM (Instagram-Privatkonten). |
| `follower_outreach_instructions` | string | Anleitung für diese erste DM bei neuen Followern. |
| `respond_to_instagram_story_replies` | boolean | Ob die KI auf Antworten zu deinen Instagram-Stories antwortet. Standard `true`. Setze `false`, damit Story-Antworten im Chat landen (mit angehängter Story), ohne eine KI-Antwort. Live-Einstellung – kein Teil des Entwurfs, muss also nicht veröffentlicht werden. |

**Ein Feld leeren**

Diese Felder werden entfernt, anstatt auf `null` gesetzt zu werden, wenn Sie `null` senden, sodass der Bot auf seine Standardwerte zurückgreift: `instagram_post_ids`, `facebook_post_ids`, `instagram_comment_delay_minutes`, `facebook_comment_delay_minutes`, `public_comment_reply_instructions`, `follower_outreach_instructions`, `first_response_exact_text`, `first_response_exact_text_variants`, `public_comment_reply_exact_text`, `public_comment_reply_exact_text_variants`.

> **Ein unbekannter Schlüssel weist die gesamte Anfrage zurück.** `PUT /campaigns/{campaignId}` validiert den gesamten Body gegen eine Positivliste. Ein nicht erkannter Schlüssel führt zu `400` für die gesamte Anfrage – er wird nicht stillschweigend ignoriert, und keines der anderen Felder in diesem Body wird geschrieben.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "Live",
    "monitor_instagram_posts": true,
    "instagram_comment_delay_minutes": 2,
    "first_response_mode": "exact_text",
    "first_response_exact_text": "Hey! Sending the details over now.",
    "first_response_exact_text_variants": [
      "Hi there, here are the details you asked for.",
      "Thanks for commenting, here is what you need."
    ],
    "public_comment_reply_exact_text": "Just sent you a DM."
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      status: "Live",
      monitor_instagram_posts: true,
      instagram_comment_delay_minutes: 2,
      first_response_mode: "ai",
      public_comment_reply_instructions:
        "Tell them to check their message requests folder too.",
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "status": "Live",
        "monitor_facebook_posts": True,
        "facebook_post_ids": None,
        "facebook_comment_delay_minutes": 5,
    },
)
data = res.json()
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

> Die sichtbare Antwort unter dem Kommentar erfordert die Kommentar-Antwort-Funktion in Ihrem Plan. Ohne diese wird die DM dennoch gesendet und die öffentliche Antwort übersprungen.

---

## Eine Kampagne mit KI optimieren

`POST /campaigns/{campaignId}/optimize`

Führt dieselbe KI-Überarbeitung aus wie die Funktionen „Optimieren“ und das Feedback bei negativem Daumen-nach-unten im Dashboard: Es nimmt Ihr Feedback entgegen, schreibt die Anweisungen des Bots um und stellt das Ergebnis als neuen Entwurf zur Überprüfung bereit.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `user_feedback` | Eines von beiden ist erforderlich | Freitext-Feedback, das beschreibt, was verbessert werden soll. |
| `thumbs_down_feedback` | Eines von beiden ist erforderlich | Feedback, das durch einen Daumen-nach-unten bei einer bestimmten Bot-Antwort erfasst wurde. |
| `thumbs_down_message` | Nein | Die Bot-Nachricht, auf die sich das Daumen-nach-unten-Feedback bezieht. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/optimize?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_feedback": "Make the tone more casual and mention the free trial earlier." }'
```

**Antwort** (`202` — die Überarbeitung läuft im Hintergrund)

```json
{ "success": true, "campaign_id": "NBCXrhqGPSFsd6MV7pRo" }
```

Fragen Sie [`GET /campaigns/{campaignId}`](#get-a-campaign) ab und beobachten Sie `test_bot.status`: Es wechselt sofort zu `"Optimizing"` und dann zurück zu `"Draft"`, sobald die Überarbeitung in `test_bot` landet. Von dort aus verhält es sich wie jeder andere Dashboard-Entwurf – überprüfen Sie ihn und veröffentlichen Sie ihn dann im Dashboard, um ihn live zu schalten. Ein `409` bedeutet, dass für diese Kampagne bereits eine Optimierung läuft.

> Die Optimierung kostet Credits, genau wie jeder andere KI-Vorgang in Ihrem Konto.

---

## Einen Kontakt einer Kampagne zuweisen

`POST /campaigns/{campaignId}/contacts/{contactId}/assign`

Fügt einen bestehenden Kontakt einer Kampagne hinzu und sendet auf Wunsch sofort die Eröffnungsnachricht der Kampagne. Dies ist der Weg, um die genehmigte WhatsApp-Vorlage einer Kampagne an einen Kontakt zu senden: Die Vorlage, mit der eine Kampagne genehmigt wurde, gehört zu dieser Kampagne, erscheint daher nicht in der [Templates API](templates.md)-Bibliothek und kann nicht über `/whatsapp-templates/send` gesendet werden.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `sendOpeningMessage` | Nein | `true` sendet die Eröffnungsnachricht der Kampagne (die genehmigte WhatsApp-Vorlage bei einer WhatsApp-Kampagne), sobald der Kontakt zugewiesen wurde. Standardmäßig `false`. |
| `triggerAIResponse` | Nein | `true` lässt die KI stattdessen ihre eigene erste Nachricht schreiben. Standardmäßig `false`. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/contacts/contact_abc123/assign?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sendOpeningMessage": true }'
```

**Antwort**

```json
{
  "success": true,
  "data": { "contactId": "contact_abc123", "campaignId": "NBCXrhqGPSFsd6MV7pRo" }
}
```

> **Guthaben:** Das Senden der Eröffnungsnachricht bei einer WhatsApp-Kampagne wird wie der Versand einer Vorlage berechnet, basierend auf dem Land des Empfängers und der Kategorie der Vorlage. Bei anderen Kanälen ist die Eröffnungsnachricht eine normale ausgehende Nachricht.

---

## Eine Kampagne an eingehende Kanäle weiterleiten

Diese Endpunkte verwalten, welche Kampagne auf neue, unbekannte Kontakte in einem Kanal antwortet. **Bevorzugen Sie Entry Points** für neue Integrationen (siehe Hinweis unter [Kampagnentypen](#campaign-types)) – diese bleiben nützlich für die Arbeit mit Kampagnen, die auf die ältere Weise weiterleiten, sowie zur Lösung von Konflikten bei der Kanalzuständigkeit zwischen zwei eingehenden Kampagnen.

### Eine Kampagne eingehenden Kanälen zuweisen

`POST /campaigns/{campaignId}/incoming-routing`

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `channels` | Ja | Array von Kanälen, für die diese Kampagne bei neuen, unbekannten Kontakten antworten soll. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/incoming-routing?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channels": ["whatsapp", "instagram"] }'
```

**Antwort**

```json
{
  "success": true,
  "uid": "abc123",
  "campaignId": "NBCXrhqGPSFsd6MV7pRo",
  "channels": ["whatsapp", "instagram"],
  "failed": []
}
```

`channels` listet nur die Kanäle auf, die tatsächlich an diese Kampagne weitergeleitet wurden; `failed` listet alle auf, die dies nicht wurden. Wenn jeder angeforderte Kanal fehlschlägt, schlägt die Anfrage selbst fehl.

### Eingehende Weiterleitung einer Kampagne löschen

`DELETE /campaigns/{campaignId}/incoming-routing`

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `channelToUnassign` | Nein | Löscht die Weiterleitung nur für diesen einen Kanal. Lassen Sie dies weg, um alle Kanäle zu löschen, auf die diese Kampagne derzeit antwortet. |

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/incoming-routing?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channelToUnassign": "instagram" }'
```

**Antwort**

```json
{
  "success": true,
  "uid": "abc123",
  "campaignId": "NBCXrhqGPSFsd6MV7pRo",
  "channelsRemoved": ["instagram"]
}
```

### Eine inaktive Kampagne reaktivieren

`POST /campaigns/{campaignId}/reactivate`

Holt eine Kampagne aus `Ended`, `Completed`, `Paused` oder `Draft` zurück und beansprucht ihre Kanäle erneut. Funktioniert nur bei `Incoming from Unknown Contacts` oder `Combined` Kampagnen – eine Kampagne, die bereits `Live` ist, wird als Erfolg gewertet, bei dem nichts weiter zu tun ist.

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/reactivate?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "data": {
    "success": true,
    "channelsReactivated": ["whatsapp"],
    "channelsBlockedByConflict": [],
    "campaignType": "Incoming from Unknown Contacts"
  }
}
```

Ein Kanal, der bereits von einem Agenten einer anderen Kampagne beansprucht wurde, erscheint in `channelsBlockedByConflict`, anstatt den gesamten Aufruf fehlschlagen zu lassen – verwenden Sie [eine in Konflikt stehende eingehende Kampagne stoppen](#stop-a-conflicting-incoming-campaign) weiter unten, um ihn zuerst freizugeben, wenn Sie möchten, dass diese Kampagne ihn übernimmt. Ein `400` wird für einen Kampagnentyp zurückgegeben, der keine Reaktivierung unterstützt, oder für einen Status, der nicht zu den oben genannten inaktiven Zuständen gehört.

### Eine in Konflikt stehende eingehende Kampagne stoppen

`POST /campaigns/{campaignId}/stop-incoming`

Gibt die Kanäle dieser Kampagne von der ANDEREN Kampagne frei, die sie derzeit belegt, damit diese Kampagne sie als Nächstes beanspruchen kann. Dies ist die REST-Version dessen, was das Dashboard automatisch tut, wenn Sie eine eingehende Kampagne in einem Kanal starten, den bereits jemand anderes bedient.

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/stop-incoming?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "ended_campaign_ids": [],
  "released_channels": ["whatsapp"],
  "cleared_entire_field": false
}
```

`released_channels` wird leer zurückgegeben, wenn diese Kampagne bereits jeden Kanal besitzt, den sie bewirbt – es gibt nichts zu übernehmen.

---

## Kostenschätzungen

Schätzen Sie die Kosten für den Start einer Kampagne, bevor Sie sie versenden.

### Kostenschätzung für WhatsApp-Vorlagen

`GET /campaigns/{campaignId}/template-cost-estimate`

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/template-cost-estimate?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "billing_mode": "credits",
  "data": {
    "countries": [
      {
        "countryCode": "1",
        "name": "United States",
        "iso": "US",
        "flag": "🇺🇸",
        "contactCount": 120,
        "costPerContact": 2,
        "subtotal": 240
      }
    ],
    "totalContacts": 120,
    "totalTemplateCost": 240,
    "templateCategory": "marketing",
    "billing_mode": "credits",
    "service_messages_billable_soon": false
  }
}
```

`billing_mode` ist `"credits"` auf dem verwalteten WhatsApp-Kanal. Auf einem Kanal, bei dem Meta Ihr eigenes WhatsApp Business-Konto direkt abrechnet, werden `costPerContact`, `subtotal` und `totalTemplateCost` als `null` zurückgegeben – niemals als `0`, was als kostenlos interpretiert würde –, da es keinen Guthabenbetrag zu melden gibt.

### SMS-Kostenschätzung

`GET /campaigns/{campaignId}/sms-cost-estimate`

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/sms-cost-estimate?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "billing_mode": "twilio_direct",
  "data": {
    "totalContacts": 120,
    "messageLength": 87,
    "segmentsPerMessage": 1,
    "totalSegments": 120,
    "estimatedCostUsd": 0.96,
    "priceUnit": "USD per segment",
    "billedByTwilio": true
  }
}
```

SMS werden immer über Ihr eigenes Twilio-Konto versendet (siehe [SMS-Anbieter](../settings/sms-provider.md)), daher wird dies immer direkt von Twilio in Rechnung gestellt – `estimatedCostUsd` ist eine Schätzung dieser Twilio-Rechnung, keine Guthabenbelastung.

---

## Limit-Prüfungen

Überprüfen Sie ein Limit vor dem Start, anstatt erst bei einem fehlgeschlagenen Versand davon zu erfahren.

### Kampagnenbezogene Prüfungen

`GET /campaigns/{campaignId}/limits/ai-credit-messaging` — ob das Starten oder Planen dieser Kampagne das KI-Guthaben-Limit für Nachrichten Ihres Kontos überschreiten würde.

`GET /campaigns/{campaignId}/limits/messaging` — ob das tägliche Nachrichtenlimit Ihres Kontos überschritten würde.

```bash
curl "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/limits/messaging?apiKey=YOUR_API_KEY"
```

**Antwort** (Limit nicht überschritten)

```json
{
  "success": true,
  "data": "Campaign is within the daily messaging limit."
}
```

Stattdessen wird ein `400` zurückgegeben, wenn das Limit überschritten würde, wobei der Grund in `error` angegeben ist.

### Kontobezogene Prüfungen

`GET /campaigns/limits/campaigns` — ob Sie das monatliche Limit für die Kampagnenerstellung Ihres Abonnements erreicht haben.

`GET /campaigns/limits/contacts` — ob Sie das Kontaktlimit Ihres Abonnements erreicht haben.

```bash
curl "https://api.youraiconnector.com/v1/campaigns/limits/campaigns?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "data": "You can create 3 more campaigns this month."
}
```

---

## Kampagnen-Statistiksummen

`GET /campaigns/stats/totals`

Summen der gesendeten und beantworteten Nachrichten für jede Kampagne UND jeden KI-Agenten in Ihrem Konto über einen gleitenden Zeitraum — dieselben Zahlen, die auf der Kampagnenlistenseite neben jeder Zeile angezeigt werden, in einem einzigen Aufruf anstelle einer Anfrage pro Kampagne.

| Abfrageparameter | Beschreibung |
|---|---|
| `days` | Größe des gleitenden Zeitraums, 1-365. Standardwert ist 90. |

```bash
curl "https://api.youraiconnector.com/v1/campaigns/stats/totals?days=30&apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "byCampaign": {
    "NBCXrhqGPSFsd6MV7pRo": { "sent": 1204, "replied": 318 }
  },
  "byAgent": {
    "agent_abc123": { "sent": 1204, "replied": 318 }
  },
  "windowDays": 30
}
```

`byAgent` ist eine eigene Zusammenfassung und keine Summe von `byCampaign` — der Datenverkehr eines Kontos, das nativ auf KI-Agenten basiert, kann ohne Kampagnen erfolgen und wäre sonst hier unsichtbar.

---

## Eine Kampagne im Playground testen

Der Playground ermöglicht es Ihnen, eine Unterhaltung mit dem Bot einer Kampagne zu führen, ohne einen echten Kanal oder einen echten Kontakt zu berühren. Es ist dieselbe Sandbox wie das Test-Panel im Dashboard und ist vollständig über die API verfügbar.

Der Ablauf ist: Erstellen Sie einen versteckten Testkontakt, senden Sie eine Nachricht und fragen Sie dann die Kampagne nach der Antwort des Bots ab. Antworten werden asynchron generiert, daher erscheinen sie in `test_messages` der Kampagne und nicht im Antwort-Body.

> **Der Playground läuft über die API-Kosten-Credits.** Eine Testkonversation, die mit einem API-Schlüssel gestartet wird, wird zum normalen KI-Nachrichtentarif berechnet, genau wie eine echte Antwort, und erscheint in Ihrem Nutzungsverlauf als regulärer Eintrag. Das Testen über das Dashboard bleibt kostenlos. Der Unterschied ist beabsichtigt: Ein Testlauf leistet dieselbe KI-Arbeit wie ein Live-Lauf; ein unbegrenzter API-Playground wäre also eine Möglichkeit, unbegrenzt KI auf Kosten anderer zu nutzen.

### Schritt 1 - Testkontakt erstellen

`POST /campaigns/{campaignId}/try-out/contact`

Erstellt den versteckten Testkontakt und verknüpft ihn mit der Kampagne. Alle Body-Felder sind optional; alles, was Sie weglassen, greift auf eine integrierte Beispielidentität (John Doe) zurück.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `first_name` | Nein | Vorname des Testkontakts. |
| `last_name` | Nein | Nachname des Testkontakts. |
| `email` | Nein | E-Mail-Adresse des Testkontakts. |
| `phone` | Nein | Telefonnummer des Testkontakts. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/try-out/contact?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "first_name": "Maria", "last_name": "Lopez" }'
```

**Antwort**

```json
{
  "success": true,
  "contactId": "8kQx1vNbA2fLpR7d"
}
```

### Schritt 2 - Eingehende Nachricht aufzeichnen

`POST /campaigns/{campaignId}/try-out/messages`

Hängt Nachrichten an den Test-Thread an. Senden Sie die Nachricht des Besuchers zuerst hierher, damit sie im Konversationsverlauf erscheint, den der Bot liest.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `messages` | Ja | Array von Nachrichtenobjekten, maximal 200 pro Anfrage. |
| `messages[].body` | Ja | Der Nachrichtentext. |
| `messages[].direction` | Ja | `"inbound"` für den Besucher, `"outbound"` für den Bot. |
| `messages[].timestamp` | Nein | ISO-8601-Zeichenfolge oder Epochen-Millisekunden. |
| `messages[].role` | Nein | Optionale Rollenbezeichnung. |
| `messages[].name` | Nein | Optionaler Anzeigename. |
| `ignoreCounter` | Nein | Ganzzahl. Setzt den Ignorieren-Zähler der Kampagne beim gleichen Schreibvorgang zurück. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/try-out/messages?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "body": "Do you ship to Belgium?",
        "direction": "inbound",
        "timestamp": "2026-07-22T09:30:00Z"
      }
    ]
  }'
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo",
  "appended": 1
}
```

### Schritt 3 - Den Bot um eine Antwort bitten

`POST /campaigns/{campaignId}/try-out/test-message`

Leitet die Nachricht an die KI-Pipeline weiter. Dies ist der Aufruf, der tatsächlich eine Bot-Antwort generiert.

| Feld | Erforderlich | Beschreibung |
|---|---|---|
| `message` | Ja | Der neueste Nachrichtentext des Besuchers. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/try-out/test-message?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Do you ship to Belgium?" }'
```

**Antwort**

```json
{
  "success": true,
  "data": "Published"
}
```

`"Published"` bedeutet, dass die Nachricht an die KI-Pipeline gesendet wurde. `"Ignored"` bedeutet, dass eine neuere Testnachricht diese überschrieben hat – der Playground fasst eine schnelle Folge von Nachrichten etwa vier Sekunden nach der letzten Nachricht zu einer einzigen Antwort zusammen, genau wie eine echte Konversation darauf wartet, dass jemand zu Ende schreibt. Aufgrund dieses Zusammenfassungsfensters dauert es einige Sekunden, bis dieser Aufruf zurückkehrt.

### Schritt 4 - Die Antwort lesen

`GET /campaigns/{campaignId}`

Die Antwort des Bots wird an das `test_messages`-Array der Kampagne angehängt. Fragen Sie die Kampagne so lange ab, bis ein neuer `outbound`-Eintrag erscheint.

```json
{
  "success": true,
  "campaign": {
    "id": "NBCXrhqGPSFsd6MV7pRo",
    "test_messages": [
      { "body": "Do you ship to Belgium?", "direction": "inbound" },
      { "body": "Yes, we ship across the EU.", "direction": "outbound" }
    ]
  }
}
```

### Playground zurücksetzen

`POST /campaigns/{campaignId}/try-out/reset`

Löscht die gesamte Sandbox: entfernt den Testkontakt, bereinigt `test_messages` und gibt die Antwortsperren des Bots frei. Verwenden Sie dies zwischen Testläufen.

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/NBCXrhqGPSFsd6MV7pRo/try-out/reset?apiKey=YOUR_API_KEY"
```

**Antwort**

```json
{
  "success": true,
  "campaign_id": "NBCXrhqGPSFsd6MV7pRo"
}
```

### Weitere Playground-Endpunkte

| Endpunkt | Funktion |
|---|---|
| `DELETE /campaigns/{campaignId}/try-out/contact` | Löscht nur den aktuellen Testkontakt und hebt dessen Verknüpfung auf, wobei `test_messages` erhalten bleibt. Ist auch erfolgreich, wenn kein Kontakt verknüpft ist. |
| `POST /campaigns/{campaignId}/try-out/transfer` | Startet einen neuen Playground, der mit einer bestehenden Konversation vorbefüllt wird, in einer einzigen Anfrage: ersetzt den Testkontakt und überschreibt `test_messages`. Der Body akzeptiert `first_name`, `last_name`, `messages` (kann leer sein) und `ignoreCounter`. Bevorzugen Sie dies gegenüber dem Löschen-dann-Erstellen-dann-Anhängen-Verfahren, da dies Ihren Rate-Limit-Verbrauch verdreifacht. |
| `POST /campaigns/{campaignId}/try-out/messages/replace` | Überschreibt `test_messages` vollständig, anstatt Daten anzuhängen. Verwenden Sie dies zum Kürzen oder Zurücksetzen eines Threads. |
| `POST /campaigns/{campaignId}/try-out/contact/reset-ignore-counter` | Setzt nur den Ignorieren-Zähler des Testkontakts zurück, für Wiederholungs- und Repeat-Abläufe nach einem Sendevorgang. |

---

## Fehler der Kampagnen-API

Kampagnen-Endpunkte geben den Standard-Fehlerumschlag zurück:

```json
{
  "success": false,
  "error": "Campaign not found"
}
```

| Status | Wann dies bei einem Kampagnen-Endpunkt auftritt |
|---|---|
| `400` | Ein erforderliches Feld fehlt oder ist ungültig (zum Beispiel ein fehlerhafter `type`, ein Nicht-Boolescher `enabled` oder ein unbekannter Wochentags-Schlüssel). Wird auch von einem [Limit-Prüfungs](#limit-checks)-Endpunkt zurückgegeben, wenn das Limit überschritten würde, sowie von [Reactivate](#reactivate-a-dormant-campaign) für einen Kampagnentyp oder -status, der dies nicht unterstützt. |
| `404` | Die Kampagne wurde nicht gefunden – entweder existiert sie nicht oder sie gehört zu einem anderen Konto. |
| `409` | Eine [Optimierung](#optimize-a-campaign-with-ai) läuft bereits für diese Kampagne. |

Die gemeinsamen Codes, die jeder Endpunkt zurückgeben kann — `401`, `403` (Ihr Plan beinhaltet keinen API-Zugriff), `429` (Ratenbegrenzung) und `500` — sind zusammen mit Hinweisen zur Wiederholung unter [Fehler & Paginierung](errors-and-pagination.md) aufgeführt.

---

## Verwandte Themen

- [Einen Kanal einer Kampagne zuweisen](channels.md#route-a-channel-to-a-campaign) — leiten Sie Instagram, WhatsApp oder jeden anderen Kanal an den KI-Agenten weiter, der ihn beantworten soll, indem Sie Einstiegspunkte verwenden.
- [KI-gestützte Follow-up-Vorlagen generieren](templates.md#generate-follow-up-templates-with-ai) — starten Sie einen Hintergrundprozess, der die WhatsApp-Follow-up-Vorlagen einer Kampagne erstellt.
- [FAQs-API](faqs.md) — verwalten Sie die Frage-Antwort-Einträge, die Ihre Kampagnen verwenden.
- [API-Zugriff](../integrations/api-access.md) — generieren Sie Ihren API-Schlüssel.
- [Authentifizierung](authentication.md) — alle Möglichkeiten, Ihren Schlüssel zu übermitteln.
