
# WhatsApp Templates API

WhatsApp-meddelandemallar är förskrivna meddelanden som har godkänts för utskick utanför det normala 24-timmarsfönstret för konversationer — till exempel ett välkomstmeddelande, en påminnelse om en bokning eller en uppmaning till återengagemang. Detta API låter dig lista, skapa, redigera, skicka in, kontrollera, radera och skicka mallar programmatiskt.

Alla sökvägar nedan är relativa till API:ets bas-URL:

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

Varje begäran måste autentiseras. Se [Autentisering](authentication.md) för de fyra accepterade metoderna. Exemplen på denna sida använder `X-API-Key`-huvudet (och en form med frågeparameter för cURL).

::: note
**Obs:** Mallar körs via WhatsApp Business API-kanalen, så denna del av API:et kräver både API-åtkomst och en plan som inkluderar WhatsApp-kanaler. Utan dessa kommer förfrågningar att avvisas med ett `403`.
:::


---

## Arbeta med underkonton (byråer)


---

## Godkännandestatusar

Eftersom meddelanden som skickas utanför en öppen konversation först måste granskas av WhatsApp, har varje mall en godkännandestatus `status`:

| Status | Betydelse |
|---|---|
| `draft` | Skapad eller sparad men ännu inte skickad för granskning. Du kan fortfarande redigera den. |
| `received` | Inskickad och accepterad i granskningskön. |
| `pending` | Under granskning. |
| `approved` | Godkänd för utskick. |
| `rejected` | Avvisad. Fältet `rejection_reason` förklarar varför; åtgärda det och skicka in igen. |

Endast mallar med status `draft` och `rejected` kan redigeras eller (åter)skickas in. När en mall är `approved` är den låst — skapa en ny om du behöver göra ändringar.

> **Automatisk godkännande:** Vissa kanaler kräver inte ett externt granskningssteg. Mallar som skapas eller skickas in för en kampanj på en sådan kanal lagras omedelbart som `approved`, utan något innehålls-ID (`sid`).

---

## Mallar på Meta-anslutna konton

Dessa slutpunkter fungerar på samma sätt oavsett vilken WhatsApp-anslutning ditt konto körs på, men vad som händer bakom dem skiljer sig åt:

- På en **hanterad WhatsApp-anslutning** registreras mallar hos meddelandeleverantören och `sid` är leverantörens innehålls-ID (`HXXXXXXXX…`).
- På ett konto vars nummer körs på ett **eget WhatsApp Business-konto** (något av Meta-anslutningsalternativen), skapas och granskas mallar **i det WhatsApp Business-kontot** och `sid` är Metas eget mall-ID — en numerisk sträng som `"3394843740694756"`. `status` använder fortfarande värdena i tabellen ovan, och `rejection_reason` innehåller fortfarande Metas förklaring.

Det finns två extra slutpunkter för detta: en för att fråga vilken anslutning du använder, och en för att stämma av din mallista med ditt WhatsApp Business-konto. Mallar som redan finns i WhatsApp Business-kontot importeras till ditt bibliotek genom synkroniseringen, så en `GET /whatsapp-templates` efteråt listar dem som vilken annan mall som helst.

### Kontrollera vilken anslutning mallar körs på

`GET /whatsapp-templates/provider`

| Fält | Beskrivning |
|---|---|
| `provider` | `twilio` när mallar är registrerade hos den hanterade meddelandeleverantören, `meta` när de finns i ditt eget WhatsApp Business-konto. |
| `lane` | Vilken Meta-anslutning som används — `meta_cloud_api` (din egen Meta-app) eller `meta_embedded` (ansluten via vår Meta-app). `null` på en hanterad anslutning. |
| `waba_id` | Det WhatsApp Business-konto som mallarna skapas i, eller `null`. |
| `templates_enabled` | `false` när Meta-anslutningen inte är slutförd ännu (inget WhatsApp Business-konto eller åtkomsttoken lagrat). Att skapa eller skicka in mallar misslyckas med ett `400` tills den är det. |

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

**Svar**

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

### Synkronisera mallar från Meta

Uppdaterar godkännandestatusen för varje mall som finns i ditt WhatsApp Business-konto och importerar alla mallar som finns där men som ännu inte finns i ditt bibliotek. Det är säkert att anropa så ofta du vill. På en hanterad anslutning finns det inget att synkronisera, så anropet gör ingenting och rapporterar bara hur många mallar du har.

`POST /whatsapp-templates/meta-sync`

| Fält | Beskrivning |
|---|---|
| `imported` | Mallar som hittades i WhatsApp Business-kontot och som lades till i ditt bibliotek genom detta anrop. |
| `updated` | Befintliga mallar vars status eller detaljer ändrades. |
| `total` | Mallar i ditt bibliotek efter synkroniseringen. |

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

**Svar**

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

### Kommunicera direkt med Meta (avancerat)

Om du behöver något som slutpunkterna ovan inte exponerar — mallhuvuden, sidfötter, knappar eller en helt handbyggd mall — skickar `/v1/meta-templates` din förfrågan direkt vidare till Metas eget mall-API, utan att lagra något i ditt mallbibliotek. Det fungerar endast på konton vars nummer körs på ett eget WhatsApp Business-konto; på en hanterad anslutning returnerar varje anrop `400` med en uppmaning att ansluta en Meta-app först.

| Slutpunkt | Vad den gör |
|---|---|
| `GET /meta-templates` | Listar mallarna på ditt WhatsApp Business-konto med deras senaste status. Lägg till `?name=` för att filtrera till ett exakt mallnamn. Returnerar `{ "success": true, "templates": [...] }`. |
| `POST /meta-templates` | Skapar en mall och skickar in den för granskning hos Meta i ett steg. Kräver `name`, `language` och `body` (eller en komplett `components`-array istället för `body`). Valfritt: `variables` (array av strängar), `category` (`MARKETING`, `UTILITY` eller `AUTHENTICATION`), `header`, `footer`, `buttons`. Returnerar `201` med `{ "success": true, "template": {...} }`. |
| `DELETE /meta-templates/{name}` | Tar bort mallen via dess Meta-namn — **alla språk** av den. Lägg till `?hsm_id=` med Metas mall-ID för att ta bort ett enskilt språk istället. Returnerar `{ "success": true, "name": "..." }`. |

En mall som Meta nekar returnerar `400` med Metas egen förklaring i `error`.

---

## Lista mallar

Returnerar alla mallar på ditt konto, med en lättviktig sammanfattning av varje.

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

**Svar**

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

---

## Hämta en mall

Returnerar fullständig information om en enskild mall, inklusive dess variabler, status och tidsstämplar.

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

**Svar**

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

En mall som inte finns på ditt konto returnerar `404` med `{ "success": false, "error": "Template not found" }`.

---

## Skapa en mall

Skapar en mall för ett kampanjmeddelande och skickar in den för godkännande i ett steg.

`POST /whatsapp-templates`

| Fält | Krävs | Beskrivning |
|---|---|---|
| `campaign_id` | Ja | Kampanjen som mallen tillhör. |
| `name` | Ja | Ett namn för mallen. |
| `language` | Ja | Språkkod, till exempel `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Ja | Meddelandetexten, upp till 1024 tecken. |
| `variables` | Nej | Ordnad lista över variabelnamn som används i brödtexten. |

Variabelplatshållare kan skrivas som `{{first_name}}`, `{first_name}` eller `[first_name]` — de normaliseras alla till formen med dubbla klammerparenteser.

Resultatet beror på kampanjens kanaler:

- **WhatsApp Business API-kampanj:** innehållet skickas för granskning av WhatsApp. Svaret innehåller `campaign_status` (`received` eller `pending`) och en `template_sid`.
- **En kanal utan ett externt granskningssteg:** mallen lagras och godkänns automatiskt (`campaign_status: "approved"`, `template_sid: null`).
- **Ingen WhatsApp-kanal i kampanjen:** ingenting skapas och `campaign_status` är `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()
```

**Svar** (inskickad för granskning)

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

---

## Skapa en fristående mall

Skapar en mall i ditt mallbibliotek utan att koppla den till ett kampanjmeddelande. Detta är skapandesteget i livscykeln som resten av denna sida följer: skapa den här, redigera den, skicka in den för granskning, kontrollera dess status och ta bort den när du inte längre behöver den.

`POST /whatsapp-templates/docs`

| Fält | Obligatoriskt | Beskrivning |
|---|---|---|
| `name` | Ja | Ett namn för mallen. |
| `language` | Ja | Språkkod, till exempel `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Ja | Meddelandetexten, upp till 1024 tecken. |
| `variables` | Nej | Ordnad lista över variabelnamn som används i brödtexten. |
| `status` | Nej | `draft` (standard) lagrar den utan att skicka in; `submitted` köar den för WhatsApp-granskning direkt. |
| `type` | Nej | `general` (standard) eller `smart_followup`. |
| `category` | Nej | `marketing`, `utility`, `authentication` eller `authentication-international`. |
| `campaign_id` | Nej | Kopplar mallen till en av dina kampanjer. |

> **Mallar för autentisering (engångskod).** WhatsApp accepterar inte fritextmallar för autentisering: meddelandetexten är förinställd av WhatsApp och mallen måste innehålla en "kopiera kod"-knapp. När du skapar en mall med `category: "authentication"` skickar vi in den i den fasta formen åt dig. Din `body` behålls som förhandsgranskningen som visas i appen, men texten som din kontakt tar emot är WhatsApps egen formulering (koden, en säkerhetspåminnelse och en notering om att den går ut om 10 minuter). Deklarera exakt en variabel, till exempel `["code"]`, och skicka med koden när du skickar (se fältet `variables` under [Skicka en mall till en kontakt](#send-a-template-to-a-contact)). Koden måste vara kortare än 15 tecken.

> **Vilken skapandemetod ska jag använda?** Använd den här när du vill ha en mall som du själv kan redigera och skicka in. Använd `POST /whatsapp-templates` (ovan) när du vill ställa in ett kampanjmeddelande — den kräver `campaign_id` och skriver direkt in i kampanjen.

En mall som skapas som `submitted` skickas för WhatsApp-granskning i bakgrunden, så kontrollera status-slutpunkten för resultatet istället för att förvänta dig det i svaret.

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

**Svar**

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

Ett saknat `name`, `language` eller `body`, ett språk som inte stöds, en `status` annan än `draft` eller `submitted`, en okänd `type` eller `category`, eller en brödtext på över 1024 tecken returnerar `400` med ett förklarande `error`. Ett `campaign_id` som inte är en av dina kampanjer returnerar `404`.

---

## Uppdatera en mall

Redigerar en mall som ännu inte har godkänts. Endast mallar med status `draft` eller `rejected` kan redigeras. Ange valfri kombination av `name`, `body`, `language` och `variables` — endast de fält du skickar ändras.

`PUT /whatsapp-templates/{templateId}`

> Redigering skickar **inte** in mallen för granskning på nytt. Använd slutpunkten för inskickning efteråt.

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

**Svar**

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

Att försöka redigera en mall som redan är `approved` (eller på annat sätt inte är redigerbar), att inte skicka några fält eller att skicka ett ogiltigt värde returnerar `400` med ett förklarande `error`.

---

## Skicka in en mall för godkännande

Skickar in en `draft`- eller `rejected`-mall för granskning. Mallar på en kanal som inte kräver extern granskning godkänns omedelbart; alla andra skickas till WhatsApp och det returnerade `status` (vanligtvis `received` eller `pending`) lagras på mallen.

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

> **Uppföljningsmallar** måste deklarera och använda sina obligatoriska variabler innan de kan skickas in: en platshållare för förnamn, plus en platshållare för personligt sammanhang för smarta uppföljningar.

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

**Svar**

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

---

## Kontrollera godkännandestatus

En lättviktig slutpunkt för att avläsa en malls aktuella status. Statusen läses från den lagrade posten, som uppdateras periodvis i bakgrunden, så ett mycket nyligen utfört godkännande eller avslag kan ta en liten stund innan det visas.

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

**Svar**

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

---

## Ta bort en mall

Tar bort mallposten från ditt konto.

`DELETE /whatsapp-templates/{templateId}`

::: warning
**Viktigt:** Vid en hanterad anslutning tas endast den lagrade posten bort — innehåll som WhatsApp redan har godkänt kan förbli registrerat hos meddelandeleverantören. På ett konto som körs på ett eget WhatsApp Business-konto raderas mallen även från det kontot. Oavsett vilket, om en kampanj fortfarande använder den här mallen, peka om kampanjen till en annan mall **innan** du raderar, annars kommer utskick som förlitar sig på den att misslyckas.
:::


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

**Svar**

```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."
}
```

---

## Skicka en mall till en kontakt

Skickar en godkänd mall till en kontakt, även när det inte finns någon öppen konversation — detta öppnar chattsessionen på nytt. Du kan rikta dig till kontakten via `contactId` eller via `phoneNumber`, och välja mall via `whatsappTemplateId` eller via `templateName`.

`POST /whatsapp-templates/send`

| Fält | Krävs | Beskrivning |
|---|---|---|
| `contactId` | Ett av dessa två | Kontaktens ID. |
| `phoneNumber` | Ett av dessa två | Kontaktens telefonnummer (med landsnummer, inga mellanslag). Slås upp eller skapas vid behov. |
| `whatsappTemplateId` | Ett av dessa två | Mallens ID. |
| `templateName` | Ett av dessa två | Mallens namn, så som det visas i appen. |
| `firstName` | Nej | Används för att fylla i en nyskapad kontakt. |
| `lastName` | Nej | Används för att fylla i en nyskapad kontakt. |
| `email` | Nej | Används för att fylla i en nyskapad kontakt. |
| `variables` | Nej | Explicita värden för mallens variabler, nycklade efter variabelnamn, till exempel `{ "code": "482913" }`. Ett värde som anges här prioriteras framför kontaktens fält för den variabeln; variabler som du utelämnar fylls fortfarande i från kontakten enligt beskrivningen nedan. Det är så här du skickar en engångskod till en autentiseringsmall. |

Mallens brödtext stöder avancerad variabelersättning:

- **Grundläggande variabler:** `{{first_name}}`, `{{email}}`, `{{company}}`
- **Standardvärden:** `{{first_name|there}}` visar `there` om fältet är tomt
- **Transformationer:** `{{company|uppercase}}`, `{{name|lowercase}}`, `{{name|capitalize}}`
- **Kombinerade:** `{{company|Your Company|uppercase}}`

> **Krediter:** Att skicka en mall förbrukar krediter. Den exakta kostnaden beror på mottagarens land och mallens kategori.

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

**Svar**

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

En begäran som saknar både en kontaktidentifierare och båda mallidentifierarna returnerar `400`. Om ditt konto saknar de meddelandeuppgifter som krävs för att skicka, blir svaret `403`.

---

## Skapa eller uppdatera en kampanjs live-mall

Ett andra par slutpunkter för en kampanjs öppningsmall, begränsade av sökväg istället för av en `campaign_id` i brödtexten. Dessa är de som ska användas för en kampanj som redan är live: till skillnad från [Skapa en mall](#create-a-template) ovan, innebär en uppdatering här även att kampanjens uppföljningsutkast skickas in för granskning på nytt, så att öppningsmallen och dess uppföljningar förblir synkroniserade.

`POST /whatsapp-templates/campaign/{campaignId}` skapar kampanjens öppningsmall. `PUT /whatsapp-templates/campaign/{campaignId}` redigerar den – kampanjen måste redan ha en mall, annars returneras `400`.

| Fält | Krävs | Beskrivning |
|---|---|---|
| `name` | Ja | Ett namn för mallen. |
| `language` | Ja | Språkkod, till exempel `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Ja | Meddelandetexten, upp till 1024 tecken. |
| `variables` | Ja | Ordnad lista över variabelnamn som används i brödtexten. Skicka en tom array om mallen inte använder några. |

**cURL** (skapa)

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

**Svar**

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

För att redigera, byt metod till `PUT` och använd samma fält – detta skickar in öppningsmallen (och kampanjens uppföljningsutkast, för en WhatsApp API-kampanj) för granskning på nytt.

En kampanj som inte tillhör ditt konto returnerar `404`; en kampanj som tillhör ett annat konto som du inte har behörighet till returnerar `403`. Att redigera en kampanj utan befintlig mall returnerar `400`.

---

## Skicka en mall till en befintlig kontakt

Ett enklare, sökvägsbaserat alternativ till [Skicka en mall till en kontakt](#send-a-template-to-a-contact) ovan: både mallen och kontakten måste redan finnas – ingenting slås upp via namn eller skapas i farten.

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

| Fält | Krävs | Beskrivning |
|---|---|---|
| `contactId` | Ja | Kontaktens ID. Måste tillhöra ditt konto. |

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

**Svar**

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

> **Krediter:** Att skicka förbrukar krediter, prissatta på samma sätt som slutpunkten ovan. En `contactId` som saknas eller inte finns på ditt konto returnerar `403`; en `templateId` som inte existerar returnerar `404`.

---

## Massutskick av en mall

Skicka en mall till många kontakter i ett enda anrop, med en kostnadsförhandsgranskning som du kan visa innan du bekräftar.

### Uppskatta kostnaden först

Returnerar vad det skulle kosta att skicka, uppdelat per destinationsland, utan att faktiskt skicka något eller förbruka några krediter. Mallprissättning sker per destinationsland, så detta måste beräknas på serversidan mot de faktiska kontakterna snarare än att uppskattas på klientsidan.

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

| Fält | Krävs | Beskrivning |
|---|---|---|
| `contactIds` | Ja | Kontakter att prissätta, upp till 500 per anrop. Dubbletter räknas en gång. |

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

**Svar**

```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` räknar id:n som saknades, inte tillhörde dig eller saknade telefonnummer — uppskattningen täcker endast resten, så ett värde som inte är noll innebär att den faktiska sändningen kommer att nå färre kontakter än du valt.

### Skicka batchen

Skickar mallen till varje kontakt i listan, löser upp eventuella smarta variabler per kontakt och debiterar krediter per sändning.

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

| Fält | Krävs | Beskrivning |
|---|---|---|
| `contactIds` | Ja | Kontakter att skicka till, upp till 5000 per anrop. |

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

**Svar**

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

En kontakt som misslyckas (hittas inte, finns inte på ditt konto eller ett sändningsfel) hoppas över och räknas i `failed` istället för att stoppa batchen. Ett tomt `contactIds`, fler än 5000 id:n vid en sändning (500 vid en uppskattning) eller ett saknat `templateId` returnerar `400`.

---

## Försök skicka ett misslyckat meddelande igen

Två slutpunkter för att skicka om ett meddelande som misslyckats, utan att skapa en ny meddelandepost eller förbruka krediter igen.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry-template` försöker skicka om ett misslyckat mallmeddelande specifikt — det löser upp mallinnehållet från kampanjen på nytt om det misslyckade meddelandet inte redan innehåller det. Endast meddelanden med status `failed` och typ `template` kan skickas om på detta sätt.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry` är kanaloberoende och fungerar för alla misslyckade icke-mallmeddelanden (till exempel WhatsApp Web), och dirigerar om till rätt sändningsväg baserat på meddelandets kanal. Den accepterar status `failed`, `failed_connection`, `limit_exceeded` eller `queued_retry`.

Ingen av slutpunkterna tar emot en förfrågningskropp (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()
```

**Svar**

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

För den kanaloberoende versionen, byt sökvägen till `.../msg_abc789/retry`. Ett meddelande vars status inte är berättigad till omförsök, eller (på mallslutpunkten) som inte är ett mallmeddelande, returnerar `400`. En saknad kontakt eller ett saknat meddelande returnerar `404`.

---

## WhatsApp Business-profil

Hantera WhatsApp Business-profilen (om, adress, beskrivning, e-post, webbplatser, företagskategori och logotyp) som visas för kontakter på WhatsApp. Fungerar både för en hanterad anslutning och ett konto som kör ett eget WhatsApp Business-konto.

### Spara profilen

`PUT /whatsapp-templates/profile`

| Fält | Krävs | Beskrivning |
|---|---|---|
| `phoneNumber` | Ja | Det WhatsApp-nummer som denna profil tillhör. Måste vara anslutet till ditt konto. |
| `about` | Nej | Kort "Om"-text som visas på profilen. |
| `address` | Nej | Företagsadress. |
| `description` | Nej | Längre företagsbeskrivning. |
| `email` | Nej | Kontakt-e-post som visas på profilen. |
| `websites` | Nej | Lista med webbadresser. Varje adress måste vara en giltig URL. |
| `vertical` | Nej | Företagskategori, till exempel `Retail` eller `Professional Services`. |
| `profilePictureHandle` | Nej | Handtaget som returneras av slutpunkten för bilduppladdning nedan, för att ställa in profilbilden. |

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

**Svar**

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

Ett saknat `phoneNumber`, en ogiltig webbadress eller ett `phoneNumber` som inte är anslutet till ditt konto returnerar `400` eller `404`.

### Ladda upp en profilbild

Laddar ner en bild från en URL som du tillhandahåller och laddar upp den till WhatsApp, vilket returnerar ett handtag. Skicka det handtaget som `profilePictureHandle` i anropet för att spara profil ovan för att ställa in den som foto — denna slutpunkt laddar bara upp bilden, den ställer inte in den automatiskt.

`POST /whatsapp-templates/profile/picture`

| Fält | Krävs | Beskrivning |
|---|---|---|
| `phoneNumber` | Ja | Det WhatsApp-nummer som denna profil tillhör. |
| `fileUrl` | Ja | En publikt tillgänglig URL till bilden som ska laddas upp. |

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

**Svar**

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

`data` är den uppladdade bildens handtag. Ett saknat `phoneNumber` eller `fileUrl`, eller ett `phoneNumber` utan sparad WhatsApp-åtkomsttoken, returnerar `400`; en oåtkomlig eller ogiltig `fileUrl` returnerar ett felmeddelande som beskriver varför nedladdningen misslyckades.

---

## Kontrollera en avsändares status

Frågar (och uppdaterar) ett anslutet WhatsApp-nummers aktuella sändningsstatus hos meddelandeleverantören. Användbart för att bekräfta att ett nummer faktiskt kan skicka meddelanden innan du förlitar dig på det.

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

**Svar**

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

`data` är ett av `ONLINE` (skickar normalt), `PENDING` (verifieras fortfarande) eller `DELETED` (leverantören känner inte längre igen denna avsändare — återanslut numret). Ett `phoneNumber` utan sparad WhatsApp-företagsinformation returnerar `404`.

---

## Generera uppföljningsmallar med AI

Plattformen kan skriva en kampanjs WhatsApp-uppföljningsmallar åt dig – de påminnelser som skickas när en konversation tystnar – utifrån kampanjens egna instruktioner och mål. Det finns en jobb-slutpunkt som körs i bakgrunden, plus tre äldre slutpunkter som behållits för befintliga integrationer. Alla använder AI-krediter.

### Starta ett genereringsjobb

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

| Fält | Krävs | Beskrivning |
|---|---|---|
| `type` | Nej | `all` (standard) skriver hela uppföljningsuppsättningen. `cold_only` skriver endast meddelanden för kontakter som aldrig svarade. |

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

**Svar** (`202`)

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

Anropet returneras så snart jobbet har köats. Läs kampanjen (`GET /campaigns/{campaignId}`, se [Campaigns API](campaigns.md)) och övervaka dess `template_generation_status`-objekt tills det är klart:

| Fält | Beskrivning |
|---|---|
| `status` | `processing` medan jobbet körs, därefter `completed` eller `failed`. |
| `progress` | 0 till 100. |
| `current_template`, `total_templates` | Hur många mallar som har skrivits hittills, av hur många jobbet kommer att skriva – 11 för en utgående eller kombinerad kampanj, 9 annars. |
| `error` | Varför ett `failed`-jobb stoppades, till exempel på grund av otillräckliga krediter. |
| `started_at`, `completed_at` | När jobbet påbörjades och avslutades. |

De genererade mallarna hamnar i kampanjen som alla andra, så de visas i [List templates](#list-templates) och går fortfarande igenom WhatsApp-godkännande innan de kan skickas. Ett `400` innebär att `type` var något annat än `all` eller `cold_only`; ett `404` innebär att kampanjen inte finns eller tillhör ett annat konto.

Agenter har en tvilling till detta anrop, `POST /agents/{agentId}/template-generation`, som skriver uppföljningarna för en agent och slutförs under anropet i det vanliga fallet – se [Generate follow-up messages](agents.md#generate-follow-up-messages) i AI Agents API.

### De äldre genereringsslutpunkterna

Tre tidigare slutpunkter utför samma arbete och behålls så att befintliga integrationer fortsätter att fungera. Ny kod bör använda jobb-slutpunkten ovan.

| Slutpunkt | Vad den gör |
|---|---|
| `POST /whatsapp-templates/campaign/{campaignId}/generate-async` | Startar uppföljningsgenerering för kampanjen i bakgrunden och returnerar `202` med `{ "success": true, "data": { "result": "success", "message": "..." } }`. Krediter debiteras i förskott (hoppas över på ett konto som tillhandahåller egen AI-nyckel) och kampanjens `template_generation_status` rapporterar framsteg exakt som ovan. |
| `POST /whatsapp-templates/campaign/{campaignId}/generate-followups` | Genererar alla nio uppföljningsmallar under anropet – för en kampanj som skapades innan automatiska uppföljningar fanns, eller en som behöver skrivas om – och returnerar `200` med `templatesGenerated` inuti `data`. |
| `POST /whatsapp-templates/agent/{agentId}/generate-followups` | Samma synkrona generering som adresseras av Agent. Svaret lägger till `agent_id`, `campaign_id` och `target`: `"campaign"` när mallarna skrevs till agentens kampanj, `"agent"` (med `campaign_id: null`) när agenten inte har någon kampanj och de lagrades på själva agenten. En saknad eller främmande agent är ett `404`. |

Alla tre kräver automatiska uppföljningar på kontot och tillräckligt med krediter – ett `400` anger vilken som saknas – och paret som adresserar kampanjer returnerar `403` när kampanjen tillhör ett annat konto.

---

## Fel i mall-API:et

Mall-slutpunkter returnerar standardfel-kuvertet:

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

Ett `404` på dessa slutpunkter innebär vanligtvis att resursen inte hittades — antingen existerar den inte eller så tillhör den ett annat konto. Ett fåtal slutpunkter (skapa/uppdatera med kampanjomfång, samt utskick till en befintlig kontakt) returnerar `403` istället när kampanjen eller kontakten tillhör någon annan snarare än att den inte existerar alls. Vissa slutpunkter inkluderar även ett `error_code`-fält som speglar HTTP-statusen. De delade koderna som varje slutpunkt kan returnera — `400`, `401`, `403` (din plan inkluderar inte API-åtkomst), `429` (hastighetsbegränsning) och `500` — listas med vägledning för återförsök i [Fel & Paginering](errors-and-pagination.md).

---

## Nästa steg

- [Autentisering](authentication.md) — de fyra sätten att autentisera en förfrågan.
- [Fel och hastighetsbegränsningar](errors-and-pagination.md) — statuskoder och gränsen på 300 förfrågningar/min.
- [Kampanj-API](campaigns.md) — hantera kampanjerna som mallar är kopplade till.
