
# Créer une intégration de bout en bout

Ce guide vous accompagne dans tout ce dont vous avez besoin pour exécuter <span data-t="appName">Your AI Connector</span> depuis votre propre code, sans jamais ouvrir le tableau de bord. À la fin, vous aurez construit une intégration minimale qui :

1. S'authentifier avec une clé API
2. Créer un agent IA et configurer son comportement d'assistant
3. Connecter un canal de messagerie (nous utilisons WhatsApp Web comme exemple pratique) et le diriger vers l'agent
4. Importer des contacts
5. Envoyer et lire des messages
6. Lire les analyses
7. S'abonner aux webhooks pour des événements en temps réel

Chaque étape renvoie vers le guide de ressources complet afin que vous puissiez approfondir les détails si nécessaire. Cette page est la carte ; les guides de ressources sont le terrain.

> **Avant de commencer.** L'accès à l'API est une fonctionnalité payante. Si votre forfait ne l'inclut pas, chaque requête renverra `403`. Consultez [Accès API](../integrations/api-access.md) pour confirmer qu'il est activé, et [Authentification](authentication.md) pour connaître toutes les façons de transmettre votre clé.

Tous les chemins ci-dessous sont relatifs à l'URL de base :

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

---

## Étape 1 — Obtenir une clé API et effectuer votre première requête

Votre clé API se trouve dans l'application sous **Paramètres → Intégrations → Clé API** — sa propre section sous Intégrations, distincte des Webhooks, qui n'apparaît que si l'accès API est inclus dans le forfait. Générez-en une, copiez-la et stockez-la dans un endroit sûr (un coffre-fort de secrets côté serveur ou une variable d'environnement — jamais dans le code du navigateur). Les instructions complètes sont disponibles dans [Accès API](../integrations/api-access.md).

Une fois que vous avez une clé, confirmez qu'elle fonctionne en appelant le point de terminaison de santé. Il existe plusieurs façons d'envoyer la clé ; la plus simple est le paramètre de requête `?apiKey=`, mais pour du code réel, préférez l'en-tête `X-API-Key` afin que la clé ne se retrouve jamais dans les journaux du serveur ou l'historique du navigateur.

**cURL**

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

**JavaScript**

```javascript
const BASE = "https://api.youraiconnector.com/v1";
const headers = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };

const res = await fetch(`${BASE}/health`, { headers });
const data = await res.json();
console.log(data); // { "success": true, ... }
```

**Python**

```python
import requests

BASE = "https://api.youraiconnector.com/v1"
HEADERS = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

res = requests.get(f"{BASE}/health", headers=HEADERS)
print(res.json())  # { "success": true, ... }
```

Chaque réponse réussie est enveloppée dans la même structure — un champ `success: true` ainsi que les données de résultat. Les erreurs renvoient `success: false` avec un message `error` et un `error_code`. Consultez [Erreurs et pagination](errors-and-pagination.md) pour la liste complète et pour savoir comment les points de terminaison de liste paginent avec `?limit` et `?cursor`.

> **Limite de débit.** Les requêtes authentifiées sont limitées à **300 par minute** (avec un plafond plus large de 1 200 par minute par compte). Tout dépassement renvoie `429` ; veuillez patienter et réessayer.

---

## Étape 2 — Créer un agent IA

Un **agent IA** est l'unité qui contient le comportement de votre assistant : ses instructions, son objectif, ses heures d'activité et sa manière de communiquer avec les contacts. C'est lui qui répond aux conversations, c'est donc la première chose à créer.

Créez-en un avec `POST /agents`. `name` est le seul champ qui mérite d'être envoyé au départ ; tout le reste peut être défini avec l'appel bot-config ci-dessous.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inbound WhatsApp Leads",
    "language": "en"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/agents`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Inbound WhatsApp Leads",
    language: "en",
  }),
});
const { agent_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/agents",
    headers=HEADERS,
    json={"name": "Inbound WhatsApp Leads", "language": "en"},
)
agent_id = res.json()["agent_id"]
```

Une création réussie renvoie `201` avec le nouvel ID :

```json
{
  "success": true,
  "agent_id": "abc123agent"
}
```

**Enregistrez l'identifiant `agent_id`** — vous y ferez référence lors du routage des canaux.

### Configurer l'assistant

`PUT /agents/{agentId}/bot-config` définit le comportement de l'assistant. Il *fusionne* les champs que vous envoyez avec la configuration existante, donc tout ce que vous omettez est préservé :

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/abc123agent/bot-config" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Greet warmly, answer questions about our services, and offer to book a call.",
    "goal": "Book a discovery call.",
    "ai_speed": "balanced"
  }'
```

Définissez les heures d'activité avec `PUT /agents/{agentId}/active-hours` afin que l'assistant ne réponde que pendant les heures de bureau ; en dehors de ces plages, il ne répond pas automatiquement.

> **Base de connaissances.** Pour que l'assistant réponde à partir de votre propre contenu, joignez des FAQ. Consultez le [guide des FAQ](faqs.md).

> **Héritage : campagnes classiques.** Les comptes qui possèdent encore une page **Campagnes** créent le même comportement d'assistant sur une campagne à la place (`POST /campaigns` avec un objet `type` et `bot`, puis `PUT /campaigns/{campaignId}/bot-config`). La liste complète des champs de campagne et les contrôles de cycle de vie se trouvent dans le [guide des campagnes](campaigns.md). Si vous développez quelque chose de nouveau, créez un agent.

---

## Étape 3 — Connecter un canal

Un agent a besoin d'un moyen d'envoyer et de recevoir des messages. Sept flux de connexion peuvent être pilotés depuis l'API : WhatsApp Business, WhatsApp Web, Instagram et Messenger ensemble (un flux Meta partagé), les comptes personnels Instagram, Telegram, LINE et Viber. Les autres canaux — SMS, e-mail, widget de chat et canaux personnalisés entre autres — sont configurés dans le tableau de bord plutôt que via REST, et une fois connectés, les points de terminaison de messagerie, de contact et de routage fonctionnent exactement de la même manière. `GET /channels` est la source de vérité en temps réel pour ce qui est réellement connecté à un compte donné :

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

L'ensemble complet des flux de connexion/déconnexion pour chaque canal est documenté dans le [Guide des canaux](channels.md). Ci-dessous, nous parcourons **WhatsApp Web** de bout en bout, car il présente le modèle le plus intéressant : un flux de couplage par code QR que votre wrapper doit rendre et interroger.

### Exemple pratique : coupler WhatsApp Web par code QR

Le couplage WhatsApp Web est une danse en trois appels — **démarrer**, **récupérer le QR**, **interroger jusqu'à la connexion**.

**1. Démarrer la session de couplage.** Indiquez le numéro que vous souhaitez connecter au format E.164.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+15551230000" }'
```

```javascript
await fetch(`${BASE}/channels/whatsapp-web/connections`, {
  method: "POST",
  headers,
  body: JSON.stringify({ phone_number: "+15551230000" }),
});
```

```python
requests.post(
    f"{BASE}/channels/whatsapp-web/connections",
    headers=HEADERS,
    json={"phone_number": "+15551230000"},
)
```

**2. Récupérer le code QR et le montrer à l'utilisateur.** Interrogez ce point de terminaison toutes les 10 à 15 secondes. La réponse inclut la charge utile `qr_code` brute (rendez-la vous-même sous forme d'image QR) et une `qr_data_url` prête à être affichée.

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000/qr?apiKey=YOUR_API_KEY"
```

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "status": "qr_pending",
  "qr_code": "2@abc...",
  "qr_data_url": "data:image/png;base64,iVBORw0KGgo..."
}
```

Dans l'interface utilisateur de votre wrapper, insérez `qr_data_url` directement dans une `<img src="...">` et demandez à l'utilisateur de le scanner depuis **WhatsApp → Appareils connectés** sur son téléphone. Si le QR expire (une réponse `410`), recommencez à partir de l'étape 1 pour en obtenir un nouveau.

**3. Interroger le statut jusqu'à la connexion.** Une fois que l'utilisateur a scanné, continuez à interroger le point de terminaison de statut jusqu'à ce qu'il indique `connected` (le service peut également signaler `open`). Traitez `disconnected` et `not_initialized` comme des échecs terminaux.

```python
import time

PHONE = "+15551230000"
while True:
    res = requests.get(
        f"{BASE}/channels/whatsapp-web/connections/{PHONE}/status",
        headers=HEADERS,
    )
    status = res.json()["status"]
    if status in ("connected", "open"):
        print("Connected!")
        break
    if status in ("disconnected", "not_initialized"):
        raise RuntimeError(f"Pairing failed: {status}")
    time.sleep(5)
```

```javascript
async function waitForConnection(phone) {
  while (true) {
    const res = await fetch(
      `${BASE}/channels/whatsapp-web/connections/${encodeURIComponent(phone)}/status`,
      { headers }
    );
    const { status } = await res.json();
    if (status === "connected" || status === "open") return;
    if (status === "disconnected" || status === "not_initialized") {
      throw new Error(`Pairing failed: ${status}`);
    }
    await new Promise((r) => setTimeout(r, 5000));
  }
}
```

> **Attention.** Chaque numéro WhatsApp Web connecté entraîne des frais de maintenance mensuels récurrents jusqu'à ce que vous le déconnectiez (`DELETE /channels/whatsapp-web/connections/{phoneNumber}`).

### Router le canal vers votre agent

Connecter un canal le rend fonctionnel ; le router indique à la plateforme *quel agent IA* doit répondre aux toutes nouvelles conversations entrantes sur celui-ci. Définissez le point d'entrée par défaut du canal, en nommant l'agent que vous avez créé à l'étape 2 :

```bash
curl -X PUT "https://api.youraiconnector.com/v1/entry-points/channel-defaults" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "whatsapp_web", "agent_id": "abc123agent" }'
```

Répétez l'appel une fois par canal — un point d'entrée par défaut par canal. Pour laisser un canal sans agent pour y répondre, appelez `DELETE /entry-points/channel-defaults?channel=whatsapp_web` ; pour vérifier si la hiérarchie des points d'entrée est active pour le compte, appelez `GET /entry-points/routing-status`. L'ancien mappage `POST /channels/campaign` est conservé uniquement pour le retour en arrière et n'est plus consulté pour le routage entrant. Consultez le [guide des canaux](channels.md) pour les autres types de canaux et pour le flux OAuth de WhatsApp Business.

---

## Étape 4 — Importer vos contacts

Une fois le canal actif, chargez les personnes que vous souhaitez atteindre. Le point de terminaison d'importation accepte jusqu'à **500 enregistrements par appel**. Chaque enregistrement nécessite un `phone_number` au format international ; tout le reste est facultatif. Les enregistrements contenant des numéros incorrects, des canaux non pris en charge ou des numéros déjà existants sont ignorés — et chaque omission est signalée avec son index et sa raison, afin que vous puissiez réessayer uniquement les échecs.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/import" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee" },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "defaultChannel": "whatsapp_web"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/import`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee" },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    defaultChannel: "whatsapp_web",
  }),
});
const result = await res.json();
console.log(`${result.imported} imported, ${result.skipped.length} skipped`);
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/import",
    headers=HEADERS,
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee"},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "defaultChannel": "whatsapp_web",
    },
)
result = res.json()
print(f"{result['imported']} imported, {len(result['skipped'])} skipped")
```

La réponse vous indique exactement ce qui s'est passé :

```json
{
  "success": true,
  "imported": 2,
  "contact_ids": ["contactId1", "contactId2"],
  "skipped": []
}
```

Pour la création un par un, la liste/recherche, les listes, les étiquettes et les champs personnalisés, consultez le [Guide des contacts](contacts.md).

---

## Étape 5 — Envoyer et lire des messages

### Envoyer un message

L'envoi le plus simple est **indépendant du canal** : indiquez l'identité du contact et le corps du message, et la plateforme le délivre sur le canal utilisé par le contact. Vous pouvez cibler par `contact_id`, ou par `channel` plus le champ d'identité correspondant (`phone_number` pour WhatsApp/WhatsApp Web/SMS, `instagram_id` pour Instagram, et ainsi de suite).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/send" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp_web",
    "phone_number": "+12025551234",
    "body": "Hi Ann! Thanks for reaching out."
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/send`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    channel: "whatsapp_web",
    phone_number: "+12025551234",
    body: "Hi Ann! Thanks for reaching out.",
  }),
});
const { message_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/send",
    headers=HEADERS,
    json={
        "channel": "whatsapp_web",
        "phone_number": "+12025551234",
        "body": "Hi Ann! Thanks for reaching out.",
    },
)
message_id = res.json()["message_id"]
```

La livraison est **asynchrone** — un `201` signifie que le message a été *accepté et mis en file d'attente*, et non encore délivré. (Les contacts ayant activé le mode « ne pas déranger » ou le mode privé sont rejetés avec un `422`.)

```json
{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp_web"
}
```

### Lire une conversation

Pour lire les messages en retour, listez-les par contact, du plus récent au plus ancien, avec une pagination par curseur. Transmettez le `next_cursor` d'une réponse en tant que `cursor` de la suivante pour parcourir l'historique.

```bash
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&apiKey=YOUR_API_KEY"
```

```python
res = requests.get(
    f"{BASE}/contacts/contact123/messages",
    headers=HEADERS,
    params={"limit": 50},
)
page = res.json()
for msg in page["messages"]:
    print(msg)
next_cursor = page["next_cursor"]  # pass back as ?cursor= for the next page
```

Vous pouvez également filtrer par type de contenu (`?filter=text|media|tool_use`) ou par direction (`?direction=inbound|outbound`). Le [Guide des messages](messages.md) couvre les pièces jointes, le marquage des messages comme lus et les vues des messages par session.

> **Ne pas interroger les réponses.** Lister les messages sur une minuterie fonctionne, mais cela gaspille des requêtes et ajoute de la latence. Pour les messages entrants, utilisez plutôt des webhooks — c'est l'étape 7.

---

## Étape 6 — Lire les analyses

Une fois que les messages circulent, le résumé analytique vous donne des totaux agrégés sur une plage de dates : envoyés, livrés, lus, répondus, réservés, contacts créés et crédits dépensés/rechargés. Vous obtenez à la fois les totaux sur la période et une série quotidienne remplie de zéros, idéale pour un graphique de tableau de bord. Vous pouvez éventuellement limiter la portée à une seule campagne avec `campaign_id` (les exemples ci-dessous utilisent un identifiant de campagne fictif, `abc123campaign`) ; omettez le paramètre pour obtenir les totaux à l'échelle du compte.

```bash
curl "https://api.youraiconnector.com/v1/analytics/summary?from=2026-05-01&to=2026-05-31&campaign_id=abc123campaign&apiKey=YOUR_API_KEY"
```

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  campaign_id: "abc123campaign",
});
const res = await fetch(`${BASE}/analytics/summary?${params}`, { headers });
const { totals, by_date } = await res.json();
```

```python
res = requests.get(
    f"{BASE}/analytics/summary",
    headers=HEADERS,
    params={"from": "2026-05-01", "to": "2026-05-31", "campaign_id": "abc123campaign"},
)
data = res.json()
totals = data["totals"]
by_date = data["by_date"]
```

La plage par défaut est de 30 jours et est limitée à 366. Pour des enregistrements d'utilisation crédit par crédit et des ventilations des coûts de l'IA, consultez le [guide des analyses](analytics.md).

---

## Étape 7 — S'abonner aux webhooks pour des événements en temps réel

Le polling est acceptable pour un script rapide, mais une véritable intégration doit être **basée sur le push**. Les webhooks permettent à la plateforme d'appeler *votre* serveur dès qu'un événement se produit — un nouveau contact, une réponse, un rendez-vous réservé, une discussion terminée.

Tout d'abord, découvrez les noms exacts des événements auxquels vous pouvez vous abonner :

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

```json
{
  "success": true,
  "events": [
    "Contact Created",
    "Human Alerted",
    "Appointment Booked",
    "Replies",
    "New Message",
    "Chat Concluded",
    "Task Created",
    "Daily Summary Created"
  ]
}
```

Créez ensuite un abonnement pointant vers une URL HTTPS sur votre serveur. Utilisez les chaînes d'événements exactes de l'appel ci-dessus.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Lead updates hook"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/webhooks`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Lead updates hook",
  }),
});
const { webhook_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/webhooks",
    headers=HEADERS,
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Lead updates hook",
    },
)
webhook_id = res.json()["webhook_id"]
```

```json
{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Lead updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

L'URL doit utiliser HTTPS et être accessible publiquement. À partir de là, votre serveur reçoit un POST pour chaque événement auquel vous êtes abonné. Vous pouvez envoyer une livraison de test, vérifier l'état d'un abonnement et réactiver un abonnement qui a été automatiquement désactivé après des échecs répétés — consultez le [guide des webhooks](webhooks.md) et la page [Webhooks](../integrations/webhooks.md) au niveau des intégrations pour connaître les structures de charge utile et la vérification.

---

## Synthèse

Voici l'ensemble du flux en un coup d'œil :

| Étape | Objectif | Appel clé |
|---|---|---|
| 1 | Authentification | `GET /health` |
| 2 | Créer + configurer l'assistant | `POST /agents`, `PUT /agents/{id}/bot-config`, `PUT /agents/{id}/active-hours` |
| 3 | Connecter un canal et le router | `POST /channels/whatsapp-web/connections` → scanner QR + statut → `PUT /entry-points/channel-defaults` |
| 4 | Charger les contacts | `POST /contacts/import` |
| 5 | Envoyer et lire | `POST /contacts/send`, `GET /contacts/{id}/messages` |
| 6 | Mesurer | `GET /analytics/summary` |
| 7 | Réagir en temps réel | `POST /webhooks` |

Un wrapper minimal consiste simplement en ces sept appels intégrés à votre propre interface utilisateur. À partir de là, ajoutez les guides par ressource selon vos besoins :

- [Campagnes](campaigns.md) · [Contacts](contacts.md) · [FAQ](faqs.md) · [Messages](messages.md) · [Rendez-vous](appointments.md)
- [Canaux](channels.md) · [Modèles](templates.md) · [Analyses](analytics.md) · [Webhooks](webhooks.md) · [Clés API](api-keys.md)
- Nouveau ici ? [Démarrage](getting-started.md) · [Authentification](authentication.md) · [Erreurs et pagination](errors-and-pagination.md)

Stuck on something this guide does not cover? Email [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com).
