
# 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.dmchamp.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)

::: master-only
> **Agencje:** każdy punkt końcowy na tej stronie przyjmuje opcjonalny parametr `sub_account_id`, dzięki czemu możesz tworzyć, przesyłać i wysyłać szablony klienta za pomocą klucza agencji. Prześlij go jako parametr zapytania w `GET`/`DELETE` oraz w treści JSON w `POST`/`PUT`. Jeśli go pominiesz, żądanie zostanie wykonane w ramach Twojego własnego konta. Zobacz [API dla agencji](../agency/api-for-agencies.md).
:::

---

## 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.dmchamp.com/v1/whatsapp-templates/provider?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/meta-sync?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/template_abc123/submit" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/template_abc123/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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`.

---

## Przenieś zatwierdzony szablon kampanii do biblioteki

`POST /whatsapp-templates/from-campaign`

Szablon zatwierdzony jako wiadomość powitalna kampanii jest przypisany do tej kampanii, więc punkty końcowe biblioteki na tej stronie nie widzą go po nazwie ani identyfikatorze SID. To wywołanie kopiuje go do Twojej biblioteki szablonów jako szablon już zatwierdzony, zachowując ten sam identyfikator SID zawartości dostawcy, więc nie ma potrzeby ponownego przesyłania. Od tego momentu działa on z każdym punktem końcowym biblioteki, w szczególności [Wyślij szablon do istniejącego kontaktu](#send-a-template-to-an-existing-contact). Jest to zamiennik wysyłania szablonu kampanii za pośrednictwem przestarzałego [Campaigns API](campaigns.md#where-each-endpoint-went).

| Pole | Wymagane | Opis |
|---|---|---|
| `campaign_id` | Jedno z dwóch | Kampania, której zatwierdzony szablon powitalny chcesz umieścić w bibliotece. |
| `broadcast_id` | Jedno z dwóch | Transmisja, która odzwierciedla klasyczną kampanię; jej kampania jest dla Ciebie rozpoznawana. Natywna transmisja zwraca `400`, ponieważ jej szablon znajduje się już w bibliotece. |

**cURL**

```bash
curl -X POST "https://api.dmchamp.com/v1/whatsapp-templates/from-campaign?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "campaign_id": "campaign123" }'
```

**Odpowiedź** (`201` w przypadku utworzenia, `200` gdy biblioteka już go posiada)

```json
{
  "success": true,
  "template_id": "template_abc123",
  "created": true,
  "sid": "HXf6e5c6e85731c9be8b2e6226235e8f34",
  "status": "approved"
}
```

Ponowne wywołanie dla tej samej kampanii zwraca istniejący szablon biblioteki z `created: false`, więc można go bezpiecznie uruchamiać przy każdym wysyłaniu. Kampania, która nie należy do Ciebie, zwraca `404`; kampania, której szablon nie został jeszcze zatwierdzony, zwraca `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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.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.dmchamp.com/v1/whatsapp-templates/sender-status/+31612345678" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.dmchamp.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.dmchamp.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 wiadomości uzupełniających na WhatsApp dla Agenta AI — przypomnienia wysyłane, gdy konwersacja cichnie — na podstawie instrukcji i celu Agenta. Dostępny jest jeden punkt końcowy zadania oraz trzy starsze punkty końcowe zachowane dla istniejących integracji. Wszystkie one wykorzystują kredyty AI.

### Uruchom zadanie generowania

`POST /agents/{agentId}/template-generation`

| Pole | Opis |
|---|---|
| `type` | `all` (domyślnie) zapisuje cały zestaw. `cold_only` zapisuje tylko wiadomości dla kontaktów, które nigdy nie odpowiedziały. |

**cURL**

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

**JavaScript**

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

**Python**

```python
import requests

res = requests.post(
    "https://api.dmchamp.com/v1/agents/ag7HkQ2ZpLxR3mNb/template-generation",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"type": "all"},
)
body = res.json()
```

Istnieją dwa sposoby powrotu tej informacji, a pole `target` informuje, który z nich wystąpił:

- **`target: "agent"` z `200`** — szablony zostały przygotowane podczas rozmowy, a wynik znajduje się w `data`. Odczytaj je z `follow_up_config` Agenta ([Pobierz Agenta](agents.md#get-an-agent)). Jest to typowy przypadek.
- **`target: "campaign"` z `202`** — praca została dodana do kolejki w ramach starszej kampanii wskazanej w `campaign_id`. Monitoruj obiekt `template_generation_status` tej kampanii, aż do zakończenia:

| 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 pojawiają się w [Liście szablonów](#list-templates) i nadal podlegają zatwierdzeniu przez WhatsApp przed wysłaniem. `400` oznacza, że `type` było czymś innym niż `all` lub `cold_only`; `cold_only` wymaga wychodzącej kampanii i jest odrzucane z `409` w przypadku Agenta, który jej nie posiada; `404` oznacza, że Agent nie istnieje lub należy do innego konta.

Formularz adresowany do kampanii, `POST /campaigns/{campaignId}/template-generation`, nadal działa w przypadku istniejących integracji, ale jest przestarzały wraz z resztą [API Kampanii](campaigns.md).

### 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ń na minutę.
- [API Agentów AI](agents.md) — zarządzanie Agentami, do których przypisane są szablony.
