
# API szablonów WhatsApp

Szablony wiadomości WhatsApp to gotowe wiadomości, które zostały zatwierdzone do wysyłki poza standardowym 24-godzinnym oknem konwersacji — na przykład wiadomość powitalna, przypomnienie o wizycie lub zachęta do ponownego kontaktu. To API umożliwia programowe wyświetlanie, tworzenie, edytowanie, przesyłanie, sprawdzanie, usuwanie i wysyłanie szablonów.

Wszystkie poniższe ścieżki są względne względem bazowego adresu URL API:

```
https://api.youraiconnector.com/v1
```

Każde żądanie musi zostać uwierzytelnione. Zobacz [Uwierzytelnianie](authentication.md), aby poznać cztery akceptowane metody. Przykłady na tej stronie używają nagłówka `X-API-Key` (oraz jednej formy parametru zapytania dla cURL).

::: note
**Uwaga:** Szablony działają w kanale WhatsApp Business API, więc ta część API wymaga zarówno dostępu do API, jak i planu obejmującego kanały WhatsApp. Bez nich żądania są odrzucane z kodem `403`.
:::


---

## Praca z subkontami (agencje)


---

## Stany zatwierdzenia

Ponieważ wiadomości wysyłane poza otwartą konwersacją muszą najpierw zostać sprawdzone przez WhatsApp, każdy szablon posiada status zatwierdzenia `status`:

| Status | Znaczenie |
|---|---|
| `draft` | Utworzony lub zapisany, ale jeszcze nie wysłany do weryfikacji. Nadal możesz go edytować. |
| `received` | Przesłany i przyjęty do kolejki weryfikacji. |
| `pending` | W trakcie weryfikacji. |
| `approved` | Zatwierdzony do wysyłki. |
| `rejected` | Odrzucony. Pole `rejection_reason` wyjaśnia dlaczego; popraw go, a następnie prześlij ponownie. |

Tylko szablony o statusie `draft` i `rejected` mogą być edytowane lub (ponownie) przesyłane. Gdy szablon ma status `approved`, jest zablokowany — jeśli potrzebujesz zmian, utwórz nowy.

> **Automatyczne zatwierdzanie:** Niektóre kanały nie wymagają zewnętrznego kroku weryfikacji. Szablony utworzone lub przesłane dla kampanii w takim kanale są natychmiast zapisywane jako `approved`, bez identyfikatora treści (`sid`).

---

## Szablony na kontach połączonych z Meta

Te punkty końcowe działają w ten sam sposób niezależnie od tego, z jakiego połączenia WhatsApp korzysta Twoje konto, ale to, co dzieje się w tle, jest inne:

- W przypadku **zarządzanego połączenia WhatsApp**, szablony są rejestrowane u dostawcy wiadomości, a `sid` to identyfikator treści dostawcy (`HXXXXXXXX…`).
- W przypadku konta, którego numer działa w ramach **własnego konta WhatsApp Business** (dowolna opcja połączenia z Meta), szablony są tworzone i sprawdzane **na tym koncie WhatsApp Business**, a `sid` to własny identyfikator szablonu Meta — ciąg numeryczny, taki jak `"3394843740694756"`. `status` nadal używa wartości z powyższej tabeli, a `rejection_reason` nadal zawiera wyjaśnienie od Meta.

Istnieją dwa dodatkowe punkty końcowe: jeden służący do sprawdzenia, z jakiego połączenia korzystasz, a drugi do uzgodnienia listy szablonów z Twoim kontem WhatsApp Business. Szablony, które już istnieją na koncie WhatsApp Business, są importowane do Twojej biblioteki podczas synchronizacji, więc późniejsze wywołanie `GET /whatsapp-templates` wyświetli je tak samo, jak każdy inny szablon.

### Sprawdzanie, na jakim połączeniu działają szablony

`GET /whatsapp-templates/provider`

| Pole | Opis |
|---|---|
| `provider` | `twilio`, gdy szablony są rejestrowane u zarządzanego dostawcy wiadomości, `meta`, gdy znajdują się na Twoim własnym koncie WhatsApp Business. |
| `lane` | Z jakiego połączenia z Meta korzystasz — `meta_cloud_api` (Twoja własna aplikacja Meta) lub `meta_embedded` (połączenie przez naszą aplikację Meta). `null` w przypadku połączenia zarządzanego. |
| `waba_id` | Konto WhatsApp Business, na którym tworzone są szablony, lub `null`. |
| `templates_enabled` | `false`, gdy połączenie z Meta nie zostało jeszcze zakończone (brak konta WhatsApp Business lub zapisanego tokena dostępu). Tworzenie lub przesyłanie szablonów zakończy się niepowodzeniem z błędem `400`, dopóki nie zostanie to zrobione. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/provider?apiKey=YOUR_API_KEY"
```

**JavaScript**

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

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/provider",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "provider": "meta",
  "lane": "meta_cloud_api",
  "waba_id": "2357661648036355",
  "templates_enabled": true
}
```

### Synchronizacja szablonów z Meta

Odświeża status zatwierdzenia każdego szablonu znajdującego się na Twoim koncie WhatsApp Business i importuje każdy szablon, który tam istnieje, ale nie ma go jeszcze w Twojej bibliotece. Można bezpiecznie wywoływać tak często, jak chcesz. W przypadku połączenia zarządzanego nie ma nic do synchronizacji, więc wywołanie nic nie robi i po prostu informuje, ile masz szablonów.

`POST /whatsapp-templates/meta-sync`

| Pole | Opis |
|---|---|
| `imported` | Szablony znalezione na koncie WhatsApp Business, które zostały dodane do Twojej biblioteki przez to wywołanie. |
| `updated` | Istniejące szablony, których status lub szczegóły uległy zmianie. |
| `total` | Szablony w Twojej bibliotece po synchronizacji. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "provider": "meta",
  "imported": 2,
  "updated": 5,
  "total": 12
}
```

### Bezpośrednia komunikacja z Meta (zaawansowane)

Jeśli potrzebujesz czegoś, czego powyższe punkty końcowe nie udostępniają — nagłówków szablonów, stopek, przycisków lub w pełni ręcznie zbudowanego szablonu — `/v1/meta-templates` przekazuje Twoje żądanie bezpośrednio do interfejsu API szablonów Meta, bez zapisywania czegokolwiek w Twojej bibliotece szablonów. Działa to tylko na kontach, których numer działa na własnym koncie WhatsApp Business; w przypadku połączenia zarządzanego każde wywołanie zwraca `400` z prośbą o wcześniejsze połączenie aplikacji Meta.

| Punkt końcowy | Co robi |
|---|---|
| `GET /meta-templates` | Wyświetla listę szablonów na Twoim koncie WhatsApp Business wraz z ich najnowszym statusem. Dodaj `?name=`, aby przefiltrować do jednej konkretnej nazwy szablonu. Zwraca `{ "success": true, "templates": [...] }`. |
| `POST /meta-templates` | Tworzy szablon i przesyła go do sprawdzenia przez Meta w jednym kroku. Wymaga `name`, `language` i `body` (lub pełnej tablicy `components` zamiast `body`). Opcjonalnie: `variables` (tablica ciągów znaków), `category` (`MARKETING`, `UTILITY` lub `AUTHENTICATION`), `header`, `footer`, `buttons`. Zwraca `201` wraz z `{ "success": true, "template": {...} }`. |
| `DELETE /meta-templates/{name}` | Usuwa szablon według jego nazwy w Meta — **każdy jego język**. Dodaj `?hsm_id=` z identyfikatorem szablonu Meta, aby usunąć tylko jeden język. Zwraca `{ "success": true, "name": "..." }`. |

Szablon odrzucony przez Meta zwraca `400` wraz z wyjaśnieniem Meta w `error`.

---

## Wyświetlanie listy szablonów

Zwraca wszystkie szablony na Twoim koncie wraz z lekkim podsumowaniem każdego z nich.

`GET /whatsapp-templates`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY"
```

**JavaScript**

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

**Python**

```python
import requests

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

**Odpowiedź**

```json
{
  "success": true,
  "data": [
    {
      "id": "template_abc123",
      "name": "welcome_message",
      "status": "approved",
      "language": "en",
      "body": "Hi {{first_name}}, thanks for reaching out!"
    },
    {
      "id": "template_def456",
      "name": "appointment_reminder",
      "status": "pending",
      "language": "en",
      "body": "Hi {{first_name}}, this is a reminder about your appointment."
    }
  ]
}
```

---

## Pobieranie szablonu

Zwraca pełne szczegóły pojedynczego szablonu, w tym jego zmienne, status i znaczniki czasu.

`GET /whatsapp-templates/{templateId}`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

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

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template": {
    "id": "template_abc123",
    "name": "welcome_message",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "language": "en",
    "variables": ["first_name"],
    "status": "approved",
    "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "type": "general",
    "category": "marketing",
    "rejection_reason": null,
    "campaign_id": "campaign123",
    "date_created": "2026-06-01T10:00:00.000Z",
    "date_updated": "2026-06-02T08:30:00.000Z",
    "submitted_at": "2026-06-01T10:05:00.000Z",
    "approved_at": "2026-06-02T08:30:00.000Z"
  }
}
```

Szablon, który nie istnieje na Twoim koncie, zwraca `404` wraz z `{ "success": false, "error": "Template not found" }`.

---

## Utwórz szablon

Tworzy szablon wiadomości powitalnej kampanii i przesyła go do zatwierdzenia w jednym kroku.

`POST /whatsapp-templates`

| Pole | Wymagane | Opis |
|---|---|---|
| `campaign_id` | Tak | Kampania, do której należy szablon. |
| `name` | Tak | Nazwa szablonu. |
| `language` | Tak | Kod języka, na przykład `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Tak | Treść wiadomości, do 1024 znaków. |
| `variables` | Nie | Uporządkowana lista nazw zmiennych użytych w treści. |

Symbole zastępcze zmiennych mogą być zapisane jako `{{first_name}}`, `{first_name}` lub `[first_name]` — wszystkie są normalizowane do postaci z podwójnym nawiasem klamrowym.

Wynik zależy od kanałów kampanii:

- **Kampania WhatsApp Business API:** treść jest wysyłana do weryfikacji przez WhatsApp. Odpowiedź zawiera `campaign_status` (`received` lub `pending`) oraz `template_sid`.
- **Kanał bez zewnętrznego kroku weryfikacji:** szablon jest zapisywany i automatycznie zatwierdzany (`campaign_status: "approved"`, `template_sid: null`).
- **Brak kanału WhatsApp w kampanii:** nic nie jest tworzone, a `campaign_status` ma wartość `not_applicable`.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign123",
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "campaign123",
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign123",
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Odpowiedź** (przesłano do weryfikacji)

```json
{
  "success": true,
  "campaign_status": "pending",
  "template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

---

## Tworzenie samodzielnego szablonu

Tworzy szablon w Twojej bibliotece szablonów bez wiązania go z wiadomością powitalną kampanii. Jest to krok tworzenia w cyklu życia, który opisuje reszta tej strony: utwórz go tutaj, edytuj, prześlij do weryfikacji, sprawdź jego status i usuń, gdy nie będzie już potrzebny.

`POST /whatsapp-templates/docs`

| Pole | Wymagane | Opis |
|---|---|---|
| `name` | Tak | Nazwa szablonu. |
| `language` | Tak | Kod języka, na przykład `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Tak | Treść wiadomości, do 1024 znaków. |
| `variables` | Nie | Uporządkowana lista nazw zmiennych użytych w treści. |
| `status` | Nie | `draft` (domyślnie) zapisuje go bez przesyłania; `submitted` od razu dodaje go do kolejki weryfikacji WhatsApp. |
| `type` | Nie | `general` (domyślnie) lub `smart_followup`. |
| `category` | Nie | `marketing`, `utility`, `authentication` lub `authentication-international`. |
| `campaign_id` | Nie | Łączy szablon z jedną z Twoich kampanii. |

> **Szablony uwierzytelniania (kod jednorazowy).** WhatsApp nie akceptuje szablonów uwierzytelniania z dowolnym tekstem: treść wiadomości jest ustalona przez WhatsApp, a szablon musi zawierać przycisk „kopiuj kod”. Gdy tworzysz szablon za pomocą `category: "authentication"`, przesyłamy go dla Ciebie w tej ustalonej formie. Twój `body` jest zachowany jako podgląd widoczny w aplikacji, ale tekst, który otrzymuje Twój kontakt, to własne sformułowanie WhatsApp (kod, przypomnienie o bezpieczeństwie i informacja o 10-minutowym czasie ważności). Zadeklaruj dokładnie jedną zmienną, na przykład `["code"]`, i przekaż kod podczas wysyłania (zobacz pole `variables` w sekcji [Wysyłanie szablonu do kontaktu](#send-a-template-to-a-contact)). Kod musi mieć mniej niż 15 znaków.

> **Którego narzędzia tworzenia użyć?** Użyj tego, gdy chcesz stworzyć szablon, który możesz samodzielnie edytować i przesłać. Użyj `POST /whatsapp-templates` (powyżej), gdy chcesz ustawić wiadomość powitalną kampanii — to wymaga `campaign_id` i zapisuje ją bezpośrednio w kampanii.

Szablon utworzony jako `submitted` jest wysyłany do weryfikacji WhatsApp w tle, więc sprawdź punkt końcowy statusu, aby poznać wynik, zamiast oczekiwać go w odpowiedzi.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/docs?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"],
    "status": "draft",
    "category": "marketing"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/docs", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
    status: "draft",
    category: "marketing",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/docs",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
        "status": "draft",
        "category": "marketing",
    },
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "status": "draft"
}
```

Brak `name`, `language` lub `body`, nieobsługiwany język, `status` inny niż `draft` lub `submitted`, nieznany `type` lub `category`, albo treść przekraczająca 1024 znaki zwraca `400` z wyjaśniającym `error`. `campaign_id`, który nie jest jedną z Twoich kampanii, zwraca `404`.

---

## Zaktualizuj szablon

Edytuje szablon, który nie został jeszcze zatwierdzony. Edytować można tylko szablony o statusie `draft` lub `rejected`. Podaj dowolną kombinację `name`, `body`, `language` oraz `variables` — zmienione zostaną tylko przesłane pola.

`PUT /whatsapp-templates/{templateId}`

> Edycja **nie** powoduje ponownego przesłania szablonu do weryfikacji. Następnie użyj punktu końcowego przesyłania.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi {{first_name}}, here is an update for you.",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi {{first_name}}, here is an update for you.",
      variables: ["first_name"],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "body": "Hi {{first_name}}, here is an update for you.",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template_id": "template_abc123"
}
```

Próba edycji szablonu, który jest już `approved` (lub w inny sposób nie podlega edycji), wysłanie pustych pól lub wysłanie nieprawidłowej wartości zwraca `400` wraz z wyjaśniającym `error`.

---

## Prześlij szablon do zatwierdzenia

Przesyła szablon `draft` lub `rejected` do weryfikacji. Szablony w kanale, który nie wymaga zewnętrznej weryfikacji, są zatwierdzane natychmiast; wszystkie pozostałe są wysyłane do WhatsApp, a zwrócony `status` (zazwyczaj `received` lub `pending`) jest zapisywany w szablonie.

`POST /whatsapp-templates/{templateId}/submit`

> **Szablony uzupełniające** muszą deklarować i używać wymaganych zmiennych przed przesłaniem: symbolu zastępczego imienia oraz symbolu zastępczego kontekstu osobistego w przypadku inteligentnych wiadomości uzupełniających.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "status": "pending",
  "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

---

## Sprawdź status zatwierdzenia

Lekki punkt końcowy do odpytywania o bieżący status szablonu. Status jest odczytywany z zapisanego rekordu, który jest okresowo odświeżany w tle, więc bardzo niedawne zatwierdzenie lub odrzucenie może pojawić się z niewielkim opóźnieniem.

`GET /whatsapp-templates/{templateId}/status`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "name": "welcome_message",
  "status": "approved",
  "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "rejection_reason": null,
  "date_updated": "2026-06-02T08:30:00.000Z"
}
```

---

## Usuń szablon

Usuwa rekord szablonu z Twojego konta.

`DELETE /whatsapp-templates/{templateId}`

::: warning
**Ważne:** W przypadku połączenia zarządzanego usuwany jest tylko zapisany rekord — treść, którą WhatsApp już zatwierdził, może pozostać zarejestrowana u dostawcy usług przesyłania wiadomości. Na koncie działającym w ramach własnego konta WhatsApp Business szablon jest usuwany również z tego konta. W obu przypadkach, jeśli kampania nadal korzysta z tego szablonu, należy przekierować tę kampanię na inny szablon **przed** usunięciem, w przeciwnym razie wysyłki, które na nim polegają, zakończą się niepowodzeniem.
:::


**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
  { 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/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "note": "The template record was removed from your account. Content already approved by WhatsApp may remain registered with the messaging provider."
}
```

---

## Wyślij szablon do kontaktu

Wysyła zatwierdzony szablon do kontaktu, nawet jeśli nie ma otwartej konwersacji — powoduje to ponowne otwarcie sesji czatu. Możesz wskazać kontakt za pomocą `contactId` lub `phoneNumber` oraz wybrać szablon za pomocą `whatsappTemplateId` lub `templateName`.

`POST /whatsapp-templates/send`

| Pole | Wymagane | Opis |
|---|---|---|
| `contactId` | Jedno z tych dwóch | Identyfikator kontaktu. |
| `phoneNumber` | Jedno z tych dwóch | Numer telefonu kontaktu (z kodem kraju, bez spacji). Wyszukiwany lub tworzony w razie potrzeby. |
| `whatsappTemplateId` | Jedno z tych dwóch | Identyfikator szablonu. |
| `templateName` | Jedno z tych dwóch | Nazwa szablonu, tak jak jest widoczna w aplikacji. |
| `firstName` | Nie | Używane do wypełnienia nowo utworzonego kontaktu. |
| `lastName` | Nie | Używane do wypełnienia nowo utworzonego kontaktu. |
| `email` | Nie | Używane do wypełnienia nowo utworzonego kontaktu. |
| `variables` | Nie | Jawne wartości dla zmiennych szablonu, kluczowane według nazwy zmiennej, na przykład `{ "code": "482913" }`. Wartość podana tutaj ma pierwszeństwo przed polami kontaktu dla tej zmiennej; zmienne, które pominiesz, są nadal wypełniane z kontaktu, jak opisano poniżej. W ten sposób przekazujesz kod jednorazowy do szablonu uwierzytelniania. |

Treść szablonu obsługuje zaawansowane podstawianie zmiennych:

- **Zmienne podstawowe:** `{{first_name}}`, `{{email}}`, `{{company}}`
- **Wartości domyślne:** `{{first_name|there}}` wyświetla `there`, jeśli pole jest puste
- **Transformacje:** `{{company|uppercase}}`, `{{name|lowercase}}`, `{{name|capitalize}}`
- **Połączone:** `{{company|Your Company|uppercase}}`

> **Kredyty:** Wysłanie szablonu zużywa kredyty. Dokładny koszt zależy od kraju odbiorcy oraz kategorii szablonu.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactId": "contact123",
    "whatsappTemplateId": "template_abc123"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contactId: "contact123",
    whatsappTemplateId: "template_abc123",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/send",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contactId": "contact123",
        "whatsappTemplateId": "template_abc123",
    },
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "data": "WhatsApp template message sent successfully"
}
```

Żądanie, w którym brakuje zarówno identyfikatora kontaktu, jak i obu identyfikatorów szablonu, zwraca `400`. Jeśli Twoje konto nie posiada danych uwierzytelniających potrzebnych do wysyłki, odpowiedzią jest `403`.

---

## Utwórz lub zaktualizuj aktywny szablon kampanii

Druga para punktów końcowych dla szablonu otwierającego kampanii, określona za pomocą ścieżki, a nie `campaign_id` w treści. Są to punkty, których należy użyć w przypadku kampanii, która jest już aktywna: w przeciwieństwie do [Utwórz szablon](#create-a-template) powyżej, aktualizacja w tym miejscu powoduje również ponowne przesłanie szkiców działań następczych kampanii do weryfikacji, dzięki czemu szablon otwierający i jego działania następcze pozostają zsynchronizowane.

`POST /whatsapp-templates/campaign/{campaignId}` tworzy szablon otwierający kampanii. `PUT /whatsapp-templates/campaign/{campaignId}` edytuje go — kampania musi już posiadać szablon, w przeciwnym razie zostanie zwrócony błąd `400`.

| Pole | Wymagane | Opis |
|---|---|---|
| `name` | Tak | Nazwa szablonu. |
| `language` | Tak | Kod języka, na przykład `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Tak | Treść wiadomości, do 1024 znaków. |
| `variables` | Tak | Uporządkowana lista nazw zmiennych użytych w treści. Przekaż pustą tablicę, jeśli szablon nie używa żadnych. |

**cURL** (tworzenie)

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "campaign_status": "pending",
  "template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "message": "WhatsApp template created and campaign updated successfully."
}
```

Aby edytować, zmień metodę na `PUT` i użyj tych samych pól — spowoduje to ponowne przesłanie szablonu otwierającego (oraz szkiców działań następczych kampanii w przypadku kampanii WhatsApp API) do weryfikacji.

Kampania, która nie należy do Twojego konta, zwróci `404`; kampania należąca do innego konta, do którego nie masz uprawnień, zwróci `403`. Edycja kampanii bez istniejącego szablonu zwróci `400`.

---

## Wyślij szablon do istniejącego kontaktu

Prostsza alternatywa dla [Wyślij szablon do kontaktu](#send-a-template-to-a-contact) powyżej, określona za pomocą ścieżki: zarówno szablon, jak i kontakt muszą już istnieć — nic nie jest wyszukiwane po nazwie ani tworzone w locie.

`POST /whatsapp-templates/{templateId}/send-to-contact`

| Pole | Wymagane | Opis |
|---|---|---|
| `contactId` | Tak | Identyfikator kontaktu. Musi należeć do Twojego konta. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": "contact123" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactId: "contact123" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactId": "contact123"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "data": "WhatsApp template message sent successfully"
}
```

> **Kredyty:** Wysyłanie zużywa kredyty, wyceniane w ten sam sposób, co powyższy punkt końcowy. `contactId`, którego brakuje lub który nie znajduje się na Twoim koncie, zwraca `403`; `templateId`, który nie istnieje, zwraca `404`.

---

## Masowe wysyłanie szablonu

Wyślij jeden szablon do wielu kontaktów w jednym wywołaniu, z podglądem kosztów, który możesz wyświetlić przed zatwierdzeniem.

### Najpierw oszacuj koszt

Zwraca koszt wysyłki w podziale na kraje docelowe, bez faktycznego wysyłania wiadomości i pobierania kredytów. Cennik szablonów zależy od kraju docelowego, dlatego obliczenia muszą być wykonywane po stronie serwera w oparciu o rzeczywiste kontakty, a nie szacowane po stronie klienta.

`POST /whatsapp-templates/{templateId}/estimate-bulk-cost`

| Pole | Wymagane | Opis |
|---|---|---|
| `contactIds` | Tak | Kontakty do wyceny, maksymalnie 500 na wywołanie. Duplikaty są liczone raz. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contact123", "contact456"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
```

**Odpowiedź**

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

`skippedContacts` zlicza identyfikatory, których brakowało, które nie należały do Ciebie lub nie zawierały numeru telefonu — szacunek obejmuje tylko pozostałe, więc wartość niezerowa oznacza, że rzeczywista wysyłka dotrze do mniejszej liczby kontaktów niż wybrano.

### Wyślij partię

Wysyła szablon do każdego kontaktu na liście, rozwiązując wszelkie inteligentne zmienne dla każdego kontaktu i pobierając kredyty za każdą wysyłkę.

`POST /whatsapp-templates/{templateId}/bulk-send`

| Pole | Wymagane | Opis |
|---|---|---|
| `contactIds` | Tak | Kontakty, do których ma zostać wysłana wiadomość, maksymalnie 5000 na wywołanie. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contact123", "contact456"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "data": { "sent": 118, "failed": 2, "total": 120 }
}
```

Kontakt, w przypadku którego wystąpił błąd (nie znaleziono, brak na koncie lub błąd wysyłania), jest pomijany i liczony w `failed` zamiast przerywać przetwarzanie partii. Pusta wartość `contactIds`, przekroczenie 5000 identyfikatorów przy wysyłce (500 przy szacowaniu) lub brak `templateId` skutkuje zwróceniem `400`.

---

## Ponowienie nieudanej wiadomości

Dwa punkty końcowe służące do ponownego wysłania wiadomości, która nie została dostarczona, bez tworzenia nowego rekordu wiadomości ani ponownego zużywania kredytów.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry-template` ponawia próbę wysłania konkretnie nieudanej wiadomości szablonowej — ponownie pobiera zawartość szablonu z kampanii, jeśli nieudana wiadomość jeszcze jej nie zawiera. W ten sposób można ponowić tylko wiadomości o statusie `failed` i typie `template`.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry` jest niezależny od kanału i działa dla każdej nieudanej wiadomości niebędącej szablonem (na przykład WhatsApp Web), kierując ją na odpowiednią ścieżkę wysyłki w oparciu o kanał wiadomości. Akceptuje status `failed`, `failed_connection`, `limit_exceeded` lub `queued_retry`.

Żaden z punktów końcowych nie wymaga treści żądania (request body).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "data": "Message retry initiated successfully"
}
```

W przypadku wersji niezależnej od kanału należy zmienić ścieżkę na `.../msg_abc789/retry`. Wiadomość, której status nie kwalifikuje się do ponowienia, lub (w przypadku punktu końcowego szablonu) która nie jest wiadomością szablonową, zwraca `400`. Brak kontaktu lub wiadomości zwraca `404`.

---

## Profil WhatsApp Business

Zarządzaj profilem WhatsApp Business (informacje, adres, opis, e-mail, strony internetowe, kategoria firmy i logo) wyświetlanym kontaktom w aplikacji WhatsApp. Działa zarówno w przypadku zarządzanego połączenia, jak i konta korzystającego z własnego konta WhatsApp Business.

### Zapisz profil

`PUT /whatsapp-templates/profile`

| Pole | Wymagane | Opis |
|---|---|---|
| `phoneNumber` | Tak | Numer WhatsApp, do którego należy ten profil. Musi być połączony z Twoim kontem. |
| `about` | Nie | Krótki tekst „O mnie” wyświetlany w profilu. |
| `address` | Nie | Adres firmy. |
| `description` | Nie | Dłuższy opis firmy. |
| `email` | Nie | Adres e-mail kontaktowy wyświetlany w profilu. |
| `websites` | Nie | Tablica adresów URL stron internetowych. Każdy musi być poprawnym adresem URL. |
| `vertical` | Nie | Kategoria firmy, na przykład `Retail` lub `Professional Services`. |
| `profilePictureHandle` | Nie | Identyfikator zwrócony przez poniższy punkt końcowy przesyłania obrazu, służący do ustawienia zdjęcia profilowego. |

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/profile?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+31612345678",
    "about": "We reply within a few hours",
    "email": "support@example.com",
    "websites": ["https://example.com"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+31612345678",
    about: "We reply within a few hours",
    email: "support@example.com",
    websites: ["https://example.com"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/whatsapp-templates/profile",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+31612345678",
        "about": "We reply within a few hours",
        "email": "support@example.com",
        "websites": ["https://example.com"],
    },
)
data = res.json()
```

**Odpowiedź**

```json
{
  "success": true,
  "data": "WhatsApp Business profile updated successfully"
}
```

Brakujący `phoneNumber`, nieprawidłowy adres URL strony internetowej lub `phoneNumber` niepołączony z Twoim kontem spowoduje zwrócenie `400` lub `404`.

### Prześlij zdjęcie profilowe

Pobiera obraz z podanego adresu URL i przesyła go do WhatsApp, zwracając identyfikator. Przekaż ten identyfikator jako `profilePictureHandle` w powyższym wywołaniu zapisu profilu, aby ustawić go jako zdjęcie — ten punkt końcowy tylko przesyła obraz, nie ustawia go samodzielnie.

`POST /whatsapp-templates/profile/picture`

| Pole | Wymagane | Opis |
|---|---|---|
| `phoneNumber` | Tak | Numer WhatsApp, do którego należy ten profil. |
| `fileUrl` | Tak | Publicznie dostępny adres URL obrazu do przesłania. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+31612345678",
    "fileUrl": "https://example.com/logo.png"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+31612345678",
    fileUrl: "https://example.com/logo.png",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+31612345678",
        "fileUrl": "https://example.com/logo.png",
    },
)
data = res.json()
```

**Odpowiedź**

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

`data` to identyfikator przesłanego zdjęcia. Brakujący `phoneNumber` lub `fileUrl`, albo `phoneNumber` bez zapisanego tokena dostępu WhatsApp, spowoduje zwrócenie `400`; nieosiągalny lub nieprawidłowy `fileUrl` spowoduje zwrócenie błędu opisującego przyczynę niepowodzenia pobierania.

---

## Sprawdź status nadawcy

Odpytuje (i odświeża) bieżący status wysyłania połączonego numeru WhatsApp u dostawcy usług przesyłania wiadomości. Przydatne do potwierdzenia, że numer faktycznie może wysyłać wiadomości, zanim zaczniesz na nim polegać.

`GET /whatsapp-templates/sender-status/{phoneNumber}`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Odpowiedź**

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

`data` to jedna z wartości: `ONLINE` (wysyłanie przebiega normalnie), `PENDING` (w trakcie weryfikacji) lub `DELETED` (dostawca nie rozpoznaje już tego nadawcy — połącz numer ponownie). `phoneNumber` bez zapisanych informacji o firmie WhatsApp spowoduje zwrócenie `404`.

---

## Generowanie szablonów działań następczych za pomocą AI

Platforma może przygotować dla Ciebie szablony działań następczych (follow-up) w WhatsApp dla kampanii — czyli przypomnienia wysyłane, gdy konwersacja wygasa — na podstawie instrukcji i celu kampanii. Dostępny jest jeden punkt końcowy zadania, który działa w tle, oraz trzy starsze punkty końcowe zachowane dla istniejących integracji. Wszystkie one wykorzystują kredyty AI.

### Uruchom zadanie generowania

`POST /campaigns/{campaignId}/template-generation`

| Pole | Wymagane | Opis |
|---|---|---|
| `type` | Nie | `all` (domyślnie) tworzy cały zestaw działań następczych. `cold_only` tworzy tylko wiadomości dla kontaktów, które nigdy nie odpowiedziały. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "all" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ type: "all" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"type": "all"},
)
data = res.json()
```

**Odpowiedź** (`202`)

```json
{ "success": true, "campaign_id": "campaign_abc123", "type": "all" }
```

Wywołanie zwraca odpowiedź natychmiast po dodaniu zadania do kolejki. Odczytaj kampanię (`GET /campaigns/{campaignId}`, zobacz [API kampanii](campaigns.md)) i obserwuj jej obiekt `template_generation_status`, aż zadanie zostanie zakończone:

| Pole | Opis |
|---|---|
| `status` | `processing` podczas działania zadania, następnie `completed` lub `failed`. |
| `progress` | Od 0 do 100. |
| `current_template`, `total_templates` | Ile szablonów zostało dotychczas utworzonych z liczby wszystkich, które zadanie ma utworzyć — 11 dla kampanii wychodzącej lub łączonej, 9 w pozostałych przypadkach. |
| `error` | Powód zatrzymania zadania `failed`, na przykład niewystarczająca liczba kredytów. |
| `started_at`, `completed_at` | Czas rozpoczęcia i zakończenia zadania. |

Wygenerowane szablony trafiają do kampanii tak jak każde inne, więc pojawiają się w [Liście szablonów](#list-templates) i nadal przechodzą przez proces zatwierdzania WhatsApp przed wysyłką. Kod `400` oznacza, że `type` było inne niż `all` lub `cold_only`; kod `404` oznacza, że kampania nie istnieje lub należy do innego konta.

Agenci posiadają odpowiednik tego wywołania, `POST /agents/{agentId}/template-generation`, który tworzy działania następcze dla Agenta i w typowym przypadku kończy się w trakcie wywołania — zobacz [Generowanie wiadomości następczych](agents.md#generate-follow-up-messages) w API Agentów AI.

### Starsze punkty końcowe generowania

Trzy wcześniejsze punkty końcowe wykonują tę samą pracę i zostały zachowane, aby istniejące integracje działały bez zmian. Nowy kod powinien korzystać z powyższego punktu końcowego zadań.

| Punkt końcowy | Działanie |
|---|---|
| `POST /whatsapp-templates/campaign/{campaignId}/generate-async` | Uruchamia generowanie działań następczych dla kampanii w tle i zwraca `202` z `{ "success": true, "data": { "result": "success", "message": "..." } }`. Kredyty są pobierane z góry (pomijane na koncie z własnym kluczem AI), a `template_generation_status` kampanii raportuje postęp dokładnie tak, jak powyżej. |
| `POST /whatsapp-templates/campaign/{campaignId}/generate-followups` | Generuje wszystkie dziewięć szablonów działań następczych podczas wywołania — dla kampanii utworzonej przed wprowadzeniem automatycznych działań następczych lub takiej, która wymaga ponownego ich utworzenia — i zwraca `200` z `templatesGenerated` wewnątrz `data`. |
| `POST /whatsapp-templates/agent/{agentId}/generate-followups` | To samo synchroniczne generowanie, co w przypadku Agenta. Odpowiedź dodaje `agent_id`, `campaign_id` oraz `target`: `"campaign"`, gdy szablony zostały zapisane w kampanii Agenta, `"agent"` (z `campaign_id: null`), gdy Agent nie ma kampanii i zostały one zapisane bezpośrednio na Agencie. Brakujący lub obcy Agent to `404`. |

Wszystkie trzy wymagają włączonych automatycznych działań następczych na koncie oraz wystarczającej liczby kredytów — kod `400` wskazuje, czego brakuje — a para obsługująca kampanie zwraca `403`, gdy kampania należy do innego konta.

---

## Błędy API szablonów

Punkty końcowe szablonów zwracają standardową kopertę błędu:

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

`404` w tych punktach końcowych zazwyczaj oznacza, że zasób nie został znaleziony — albo nie istnieje, albo należy do innego konta. Kilka punktów końcowych (tworzenie/aktualizacja w zakresie kampanii oraz wysyłki do istniejącego kontaktu) zwraca zamiast tego `403`, gdy kampania lub kontakt należą do kogoś innego, zamiast po prostu nie istnieć. Niektóre punkty końcowe zawierają również pole `error_code` odzwierciedlające status HTTP. Wspólne kody, które może zwrócić każdy punkt końcowy — `400`, `401`, `403` (Twój plan nie obejmuje dostępu do API), `429` (limit szybkości) oraz `500` — zostały wymienione wraz ze wskazówkami dotyczącymi ponawiania prób w sekcji [Błędy i stronicowanie](errors-and-pagination.md).

---

## Następne kroki

- [Uwierzytelnianie](authentication.md) — cztery sposoby uwierzytelniania żądania.
- [Błędy i limity szybkości](errors-and-pagination.md) — kody statusu oraz limit 300 żądań/min.
- [API kampanii](campaigns.md) — zarządzanie kampaniami, do których przypisane są szablony.
