# Envoyer une campagne WhatsApp par API

URL: https://wa.genuka.com/docs/guides/campaigns-api
Language: French

> Envoyer une campagne WhatsApp par API : template marketing, destinataires, lancement, quotas par forfait, limites marketing de Meta et suivi des envois.

Pour envoyer une campagne WhatsApp par API avec Genuka WA, vous faites approuver un template
`MARKETING` par Meta, vous créez la campagne avec `POST /api/v1/campaigns` et sa liste de
destinataires, puis vous la lancez avec `POST /api/v1/campaigns/{id}/launch`. Chaque destinataire
est suivi jusqu'à la lecture, et Meta facture les messages délivrés directement à votre propre
compte WhatsApp Business.

*Mis à jour le 8 octobre 2026*

## Ce qu'il faut avant d'envoyer une campagne

* **Un numéro connecté** et son `connectionId` — voir [Connecter un numéro](https://wa.genuka.com/docs/onboarding).
* **Une clé API**, utilisée uniquement côté serveur — voir [Authentification](https://wa.genuka.com/docs/authentication).
* **Un moyen de paiement sur votre compte Meta.** Genuka est Meta Tech Provider, pas BSP : Meta
  facture votre compte WhatsApp Business (WABA) directement, et un client onboardé par un Tech
  Provider doit y ajouter son propre moyen de paiement
  ([Meta, Partners](https://developers.facebook.com/documentation/business-messaging/whatsapp/solution-providers/overview)).
  Sans lui, le template est approuvé mais chaque envoi revient en erreur `131042`.
* **Des destinataires qui ont accepté de recevoir vos messages.** C'est une règle de WhatsApp, pas
  une bonne pratique — la section sur l'opt-in, plus bas, la détaille.

## Comment créer le template marketing ?

Hors de la fenêtre de service de 24 heures, seul un template approuvé est délivré. Une campagne en
utilise toujours un. Soumettez-le avec la catégorie `MARKETING` :

```bash title="POST /api/v1/templates"
curl -X POST https://wa.genuka.com/api/v1/templates \
  -H "Authorization: Bearer $GENUKA_WA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "connectionId": "con_1",
    "name": "promo_octobre",
    "language": "fr",
    "category": "MARKETING",
    "components": [
      { "type": "BODY",
        "text": "Bonjour {{1}}, -20 % sur toute la boutique jusqu’à dimanche.",
        "example": { "body_text": [["Awa"]] } },
      { "type": "BUTTONS", "buttons": [
        { "type": "URL", "text": "Voir les offres", "url": "https://example.com/promo" }
      ] }
    ]
  }'
```

La réponse est un `201` qui porte l'`id` du template et son statut. Meta l'examine —
l'examen peut prendre jusqu'à 24 heures
([Meta, Template fundamentals](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/overview)).
Le verdict arrive sur vos [webhooks](https://wa.genuka.com/docs/webhooks) (`template.status_changed`) et sur
`GET /api/v1/templates/{id}`. Une campagne ne part qu'avec un template `approved`.

Chaque variable du corps (`{{1}}`, `{{2}}`…) exige un exemple, sinon le template est refusé. La
[référence API](https://wa.genuka.com/docs/api#templates) couvre les en-têtes média, les paramètres nommés et les
boutons.

## Comment créer et lancer la campagne ?

1. ### Créez la campagne

   `POST /api/v1/campaigns` prend quatre champs, tous obligatoires : `connectionId`, `templateId`,
   `name` et `recipients`. Chaque destinataire porte son numéro au format international (`+` et
   indicatif pays) et ses propres `variables`. La campagne est créée en statut `draft` : rien n'est
   encore envoyé.

2. ### Lancez-la

   `POST /api/v1/campaigns/{id}/launch` envoie chaque destinataire encore `pending` et répond avec le
   décompte : `sent`, `failed`, `skipped`. Un `sent` veut dire que Meta a accepté le message, pas qu'il
   est arrivé — la livraison et la lecture arrivent ensuite, par webhook.

3. ### Suivez les statuts

   Lisez les compteurs sur `GET /api/v1/campaigns/{id}` et le détail par destinataire sur
   `GET /api/v1/campaigns/{id}/recipients`. La section sur le suivi, plus bas, détaille les deux.

**curl**

```bash
# 1. Créer la campagne (statut draft)
curl -X POST https://wa.genuka.com/api/v1/campaigns \
  -H "Authorization: Bearer $GENUKA_WA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "connectionId": "con_1",
    "templateId": "tpl_123",
    "name": "Promo octobre",
    "recipients": [
      { "to": "+237690000001", "variables": ["Awa"] },
      { "to": "+237690000002", "variables": ["Paul"] }
    ]
  }'
# { "data": { "id": "cmp_9", "name": "Promo octobre", "status": "draft", "_count": { "recipients": 2 } } }

# 2. La lancer
curl -X POST https://wa.genuka.com/api/v1/campaigns/cmp_9/launch \
  -H "Authorization: Bearer $GENUKA_WA_API_KEY"
# { "data": { "sent": 2, "failed": 0, "skipped": 0 } }
```

**Node.js**

```ts
const API = "https://wa.genuka.com/api/v1";

async function post<T>(path: string, body?: unknown): Promise<T> {
  const response = await fetch(`${API}${path}`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GENUKA_WA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: body === undefined ? undefined : JSON.stringify(body),
  });
  // Un 524 du CDN (lancement trop long, voir les limites plus bas) n'a pas de corps JSON.
  const json = await response.json().catch(() => ({}));
  if (!response.ok) {
    throw new Error(`${response.status} ${json.error ?? "no_json_body"}: ${json.message ?? ""}`);
  }
  return json.data as T;
}

const campaign = await post<{ id: string }>("/campaigns", {
  connectionId: "con_1",
  templateId: "tpl_123",
  name: "Promo octobre",
  recipients: [
    { to: "+237690000001", variables: ["Awa"] },
    { to: "+237690000002", variables: ["Paul"] },
  ],
});

const result = await post<{ sent: number; failed: number; skipped: number }>(
  `/campaigns/${campaign.id}/launch`,
);
console.log(result); // { sent: 2, failed: 0, skipped: 0 }
```

**Python**

```python
import os
import requests

API = "https://wa.genuka.com/api/v1"
HEADERS = {
    "Authorization": f"Bearer {os.environ['GENUKA_WA_API_KEY']}",
    "User-Agent": "acme-crm/1.0 (+https://example.com)",
}

created = requests.post(f"{API}/campaigns", headers=HEADERS, timeout=30, json={
    "connectionId": "con_1",
    "templateId": "tpl_123",
    "name": "Promo octobre",
    "recipients": [
        {"to": "+237690000001", "variables": ["Awa"]},
        {"to": "+237690000002", "variables": ["Paul"]},
    ],
})
created.raise_for_status()
campaign_id = created.json()["data"]["id"]

# Au-delà de 2 minutes environ, le CDN répond 524 alors que l'envoi continue côté
# serveur : ne relancez pas, suivez le statut de la campagne (voir les limites plus bas).
launched = requests.post(f"{API}/campaigns/{campaign_id}/launch", headers=HEADERS, timeout=150)
launched.raise_for_status()
print(launched.json()["data"])  # {'sent': 2, 'failed': 0, 'skipped': 0}
```

**PHP**

```php
<?php
function genuka_post(string $path, ?array $body = null): array
{
    $ch = curl_init("https://wa.genuka.com/api/v1" . $path);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 150,
        CURLOPT_USERAGENT => "acme-crm/1.0 (+https://example.com)",
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer " . getenv("GENUKA_WA_API_KEY"),
            "Content-Type: application/json",
        ],
        CURLOPT_POSTFIELDS => $body === null ? "" : json_encode($body),
    ]);
    $json = json_decode(curl_exec($ch), true);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    if ($status >= 400) {
        // Un 524 du CDN (lancement trop long, voir les limites plus bas) n'a pas de corps JSON.
        throw new RuntimeException("{$status} " . ($json['error'] ?? 'no_json_body'));
    }
    return $json["data"];
}

$campaign = genuka_post("/campaigns", [
    "connectionId" => "con_1",
    "templateId" => "tpl_123",
    "name" => "Promo octobre",
    "recipients" => [
        ["to" => "+237690000001", "variables" => ["Awa"]],
        ["to" => "+237690000002", "variables" => ["Paul"]],
    ],
]);

print_r(genuka_post("/campaigns/{$campaign['id']}/launch")); // sent, failed, skipped
```

`variables` est un tableau positionnel pour les paramètres du corps. Pour un en-tête média, un
bouton dynamique ou des paramètres nommés, passez un objet à la place —
`{ "body": [...], "bodyNamed": { "first_name": "Awa" }, "header": {...}, "buttons": [...] }` —
la même forme que [l'envoi d'un template](https://wa.genuka.com/docs/api#messages). Les paramètres d'un template à
paramètres nommés vont dans `bodyNamed` : placés dans `body`, ils partiraient comme des
paramètres positionnels.

### Pourquoi le lancement est-il refusé ?

Ces contrôles ont lieu avant le premier envoi : un lancement refusé n'a rien envoyé. Les refus les
plus courants :

| Statut | Code                    | Cause                                                                                                                                                             |
| ------ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `402`  | `plan_limit_messages`   | La liste ne tient pas dans le quota restant de la période. Tous les destinataires `pending` comptent, y compris ceux qui seront ensuite écartés comme désinscrits |
| `402`  | `subscription_past_due` | L'essai ou la période payée est échu                                                                                                                              |
| `400`  | `send_template`         | Le template n'est pas `approved` (en examen, refusé, en pause) — le message dit lequel                                                                            |
| `409`  | `send_config`           | Le numéro a été déconnecté de l'API depuis l'application WhatsApp Business ([coexistence](https://wa.genuka.com/docs/guides/coexistence)) : reconnectez-le                             |
| `409`  | `number_released`       | Le numéro a été libéré de votre forfait : reconnectez-le par l'Embedded Signup                                                                                    |
| `403`  | `account_deactivated`   | Le client propriétaire du numéro est suspendu                                                                                                                     |
| `404`  | `campaign_not_found`    | L'`id` n'existe pas ou n'est pas à la portée de votre clé                                                                                                         |

À la création, un `templateId` et un `connectionId` qui appartiennent à deux clients différents
répondent `400 template_connection_mismatch`, et une liste sans aucun `to` exploitable
`400 no_valid_recipients`. Les autres codes sont dans la [référence des erreurs](https://wa.genuka.com/docs/api#erreurs).

## Combien de messages une campagne peut-elle envoyer ?

Genuka ne facture jamais le message. Votre forfait inclut en revanche un **quota de messages
sortants par numéro payé et par période de facturation**, partagé entre les envois API et les
destinataires de campagne. Le quota de la période vaut : numéros payés × quota unitaire du palier.
Le compteur repart de zéro à chaque nouvelle période : chaque mois sur un abonnement mensuel, au
renouvellement sur un abonnement annuel.

| Palier     | Numéros max | Messages inclus par numéro et par période |
| ---------- | ----------- | ----------------------------------------- |
| Starter    | 5           | 500                                       |
| Growth     | 15          | 5 000                                     |
| Scale      | 100         | 30 000                                    |
| Enterprise | sur mesure  | sur mesure                                |

Exemple : 3 numéros en Growth donnent 15 000 messages pour la période. L'essai gratuit de 7 jours
tourne sur le palier Growth avec un numéro, soit 5 000 messages. Seuls les messages acceptés par
Meta sont décomptés : un envoi que Meta refuse à l'appel ne consomme rien, mais un message accepté
puis signalé `failed` par webhook reste décompté. Les tarifs sont sur la
[page de prix](https://wa.genuka.com/#pricing) et en Markdown sur [/pricing.md](https://wa.genuka.com/pricing.md).

## Quelles limites Meta impose-t-il aux campagnes marketing ?

Le quota Genuka n'est pas la seule limite. Meta en applique quatre, indépendantes de votre forfait :

| Limite Meta                           | Ce qu'elle dit                                                                                                                                                                                                                                                                                                           | Ce que vous voyez                                                                                                                                                                                                |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plafond d'envoi**                   | Nombre de destinataires uniques joignables hors fenêtre de service, par 24 heures glissantes, au niveau du portefeuille Business : 250 pour un portefeuille neuf, puis 2 000, 10 000, 100 000, illimité ([doc](https://developers.facebook.com/documentation/business-messaging/whatsapp/messaging-limits))              | WhatsApp Manager, **Account tools > Messaging limits** (même page). Le `messagingLimitTier` de `GET /api/v1/numbers?refresh=true` n'est qu'indicatif : il vient d'un champ que Meta a déprécié et peut être vide |
| **Plafond marketing par utilisateur** | WhatsApp peut ne pas délivrer un template marketing à quelqu'un qui en reçoit beaucoup et en lit peu. Attendez au moins 24 heures avant de réessayer ([doc](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/marketing-templates/per-user-limits/))                                   | Erreur `131049` sur le webhook de statut, destinataire `failed`                                                                                                                                                  |
| **Numéros des États-Unis**            | WhatsApp ne délivre pas actuellement de templates marketing aux numéros américains (même page)                                                                                                                                                                                                                           | Échec du destinataire                                                                                                                                                                                            |
| **Débit**                             | 80 messages par seconde par numéro par défaut, 20 pour un numéro en coexistence ([débit](https://developers.facebook.com/documentation/business-messaging/whatsapp/throughput), [coexistence](https://developers.facebook.com/documentation/business-messaging/whatsapp/embedded-signup/onboarding-business-app-users/)) | Le lancement est cadencé dessus                                                                                                                                                                                  |

Le plafond marketing par utilisateur n'est pas actif pour les envois depuis ou vers l'Espace
économique européen, le Royaume-Uni, le Japon et la Corée du Sud (même page Meta).

Les templates `MARKETING` d'une campagne sont d'abord proposés à la
[Marketing Messages API](https://developers.facebook.com/documentation/business-messaging/whatsapp/marketing-messages/get-started)
de Meta ; si votre compte n'y a pas accès, l'envoi repasse sur l'endpoint classique sans
interrompre la campagne.

### Combien coûte une campagne chez Meta ?

Meta facture par message délivré, au tarif de la catégorie du template et de l'indicatif du pays
du destinataire, sur votre portefeuille Business
([Meta, Pricing](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)).
Genuka n'y ajoute aucune marge et ne voit jamais passer ce paiement.

## Faut-il un opt-in pour une campagne WhatsApp ?

Oui. La politique WhatsApp Business n'autorise à contacter quelqu'un que s'il vous a donné son
numéro **et** a confirmé vouloir recevoir vos messages
([WhatsApp Business Messaging Policy](https://whatsappbusiness.com/policy/)). Meta précise que la
demande doit nommer votre entreprise et dire clairement à quoi la personne s'abonne, par le canal
de votre choix — site, SMS, formulaire papier
([Meta, Get opt-in](https://developers.facebook.com/documentation/business-messaging/whatsapp/getting-opt-in)).
Une qualité durablement basse fait limiter le numéro par Meta (même page).

Genuka applique la désinscription pour vous sur les campagnes marketing :

* Quand un utilisateur arrête les messages marketing depuis WhatsApp, Meta l'annonce par webhook ;
  Genuka l'enregistre. Un envoi refusé avec `131050` (« ce destinataire a choisi de ne plus
  recevoir de messages marketing ») l'enregistre aussi.
* Au lancement d'une campagne `MARKETING`, ces contacts sont écartés **avant** tout envoi et
  passent en statut `skipped`, avec le motif. Ils ne consomment ni quota ni facturation Meta.
* Les campagnes `UTILITY` et `AUTHENTICATION` ne sont pas filtrées : ce ne sont pas des messages
  marketing.

Un mot-clé maison (« répondez STOP ») n'est pas interprété automatiquement : les réponses vous
arrivent sur `message.received`, et c'est à vous de retirer ces contacts de vos listes.

## Comment suivre les résultats d'une campagne ?

`GET /api/v1/campaigns/{id}` renvoie la campagne, son template, son numéro et un objet `stats` qui
compte les destinataires par statut :

```json title="GET /api/v1/campaigns/cmp_9"
{
  "data": {
    "id": "cmp_9",
    "name": "Promo octobre",
    "status": "completed",
    "template": { "id": "tpl_123", "name": "promo_octobre", "language": "fr", "status": "approved" },
    "_count": { "recipients": 1200 },
    "stats": { "read": 640, "delivered": 410, "sent": 95, "failed": 41, "skipped": 14 }
  }
}
```

Chaque destinataire n'est compté qu'une fois, sous son statut le plus avancé : un message lu
figure dans `read`, pas dans `delivered`. Le taux de livraison se lit donc
`(delivered + read) / (total − skipped)`.

| Statut      | Signification                                                           |
| ----------- | ----------------------------------------------------------------------- |
| `pending`   | Pas encore envoyé                                                       |
| `sent`      | Accepté par Meta                                                        |
| `delivered` | Arrivé sur le téléphone                                                 |
| `read`      | Lu — seulement si le destinataire a activé les confirmations de lecture |
| `failed`    | Refusé, avec le motif de Meta dans `errorMessage`                       |
| `skipped`   | Écarté au lancement : désinscrit du marketing                           |

Pour les échecs, `GET /api/v1/campaigns/{id}/recipients?status=failed&limit=1000` liste chaque
destinataire avec `errorMessage`, `sentAt`, `deliveredAt`, `readAt` et `failedAt` (200 lignes par
défaut, 1 000 au maximum). En temps réel, abonnez un endpoint à `message.delivered`,
`message.read`, `message.failed` et `user_preference.stopped` — voir [Webhooks](https://wa.genuka.com/docs/webhooks).

### Comment renvoyer aux destinataires bloqués par le plafond marketing ?

Le plafond marketing par utilisateur se signale après l'envoi : Meta accepte le message, puis le
webhook de statut revient `failed` avec l'erreur `131049`
([Meta, Per-user limits](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/marketing-templates/per-user-limits/)).
Le destinataire passe en `failed`, avec le texte de Meta dans `errorMessage` (Meta décrit cette
erreur ainsi : « This message was not delivered to maintain healthy ecosystem engagement »). Un
nouvel appel à `launch` ne le renverra pas : il ne reprend que les destinataires `pending`.

Pour retenter ces personnes, attendez au moins 24 heures, listez
`GET /api/v1/campaigns/{id}/recipients?status=failed`, gardez ceux qui portent ce motif (ou le code
`131049` reçu sur `message.failed`) et créez une nouvelle campagne avec eux. Dans le cas plus rare
où Meta refuse l'envoi lui-même avec `131049`, le destinataire reste `pending`, et un nouvel appel à
`launch` 24 heures plus tard le reprend.

## Limites de la version actuelle

* **Le lancement est synchrone et borné dans le temps.** L'appel parcourt la liste un destinataire
  après l'autre : chaque envoi attend la réponse de Meta puis l'enregistrement de son statut, si
  bien que le débit réel reste bien en dessous du plafond du numéro. Au-delà de 2 minutes environ,
  le CDN qui protège l'API répond `524` — une page d'erreur, pas du JSON — alors que l'envoi
  continue côté serveur
  ([Cloudflare, erreur 524](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-524/)).
  Gardez des campagnes de quelques centaines de destinataires et découpez une grosse audience en
  plusieurs campagnes.
* **Après un `524`, suivez la campagne au lieu de la relancer.** Interrogez
  `GET /api/v1/campaigns/{id}` jusqu'à ce que `status` ne soit plus `running`. N'appelez jamais
  `launch` sur une campagne `running` : rien ne l'en empêche aujourd'hui, et deux exécutions en
  parallèle enverraient deux fois le message aux destinataires que la première n'a pas encore
  atteints.
* **Une exécution trop longue est interrompue.** Le serveur ne laisse pas un appel tourner
  indéfiniment. Si la campagne est encore `running` 15 minutes après l'appel, l'exécution a été
  coupée : les destinataires restés `pending` n'ont pas été envoyés, et un nouvel appel à `launch`
  les reprend.
* **Pas de planification.** Aucun champ de date : appelez `launch` au moment voulu, depuis votre
  propre tâche planifiée.

## Et si je préfère une interface plutôt qu'une API ?

Genuka WA n'a pas de console de campagnes : `/api/v1/campaigns` est une brique d'intégration
(template + destinataires + statuts). Si vous voulez segmenter une clientèle et lancer des
campagnes sans écrire de code, [Genuka Core](https://genuka.com), la plateforme de gestion
commerciale de Genuka, le fait : elle catégorise vos clients, analyse leur comportement d'achat
et lance des campagnes WhatsApp, SMS et email ciblées.

## FAQ

### Puis-je envoyer une campagne à des contacts qui ne m'ont jamais écrit ?

Oui, avec un template approuvé et leur opt-in. C'est précisément le rôle du template : il est le
seul message délivré hors de la fenêtre de 24 heures. Le plafond d'envoi de Meta (250 destinataires
uniques par 24 heures pour un portefeuille neuf) s'applique à ces envois.

### Combien coûte une campagne WhatsApp avec Genuka WA ?

Deux lignes séparées. Meta facture chaque template délivré à votre portefeuille Business, selon la
catégorie et le pays du destinataire. Genuka facture un abonnement par numéro WhatsApp, avec un
quota de messages inclus, et ne prend aucune marge sur les tarifs de Meta.

### Que se passe-t-il si un destinataire s'est désinscrit ?

Sur une campagne `MARKETING`, il est écarté avant l'envoi et marqué `skipped`. Il ne consomme pas
votre quota et Meta ne vous facture rien pour lui.

### Pourquoi `sent` est-il élevé mais `delivered` faible ?

`sent` signifie seulement que Meta a accepté le message. Les accusés de livraison arrivent ensuite
par webhook ; s'ils ne viennent pas, regardez `failed` et les erreurs `131049` (plafond marketing)
ou `131026` (destinataire injoignable).

### Puis-je relancer la même campagne ?

Oui, une fois qu'elle n'est plus `running` (`completed` ou `failed`) : `launch` n'envoie alors que
les destinataires encore `pending`, jamais un message déjà parti. Ne la relancez pas pendant
qu'elle est `running`, même après un `524` : attendez qu'elle en sorte, ou 15 minutes si elle y
reste (voir les limites ci-dessus).

## Sources

* Meta — [Messaging limits](https://developers.facebook.com/documentation/business-messaging/whatsapp/messaging-limits)
* Meta — [Per-user marketing template message limits](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/marketing-templates/per-user-limits/)
* Meta — [Throughput](https://developers.facebook.com/documentation/business-messaging/whatsapp/throughput)
* Meta — [Pricing on the WhatsApp Business Platform](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)
* Meta — [Get opt-in for WhatsApp](https://developers.facebook.com/documentation/business-messaging/whatsapp/getting-opt-in)
* Meta — [Template fundamentals](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/overview)
* Meta — [Marketing Messages API: get started](https://developers.facebook.com/documentation/business-messaging/whatsapp/marketing-messages/get-started)
* Meta — [Partners (Tech Providers et Solution Partners)](https://developers.facebook.com/documentation/business-messaging/whatsapp/solution-providers/overview)
* Meta — [Error codes](https://developers.facebook.com/documentation/business-messaging/whatsapp/support/error-codes)
* Meta — [Onboard WhatsApp Business app users](https://developers.facebook.com/documentation/business-messaging/whatsapp/embedded-signup/onboarding-business-app-users/)
* WhatsApp — [Business Messaging Policy](https://whatsappbusiness.com/policy/)
* Cloudflare — [Error 524: a timeout occurred](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-524/)
* Genuka — [genuka.com](https://genuka.com)
