
# Creare un'integrazione end-to-end

Questa guida illustra tutto ciò che serve per eseguire <span data-t="appName">Your AI Connector</span> dal proprio codice, senza mai aprire la dashboard. Alla fine avrai creato un'integrazione minima che:

1. Autenticazione con una chiave API
2. Creazione di un Agente IA e configurazione del suo comportamento come assistente
3. Connessione di un canale di messaggistica (utilizziamo WhatsApp Web come esempio pratico) e associazione all'Agente
4. Importazione dei contatti
5. Invio e lettura dei messaggi
6. Lettura delle analisi
7. Sottoscrizione ai webhook per eventi in tempo reale

Ogni passaggio rimanda alla guida completa alle risorse, così da poter approfondire i dettagli quando necessario. Questa pagina è la mappa; le guide alle risorse sono il territorio.

> **Prima di iniziare.** L'accesso all'API è una funzionalità a pagamento. Se il tuo piano non lo include, ogni richiesta restituirà `403`. Consulta [Accesso API](../integrations/api-access.md) per verificare che sia abilitato e [Autenticazione](authentication.md) per tutti i modi in cui passare la tua chiave.

Tutti i percorsi sottostanti sono relativi all'URL di base:

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

---

## Passaggio 1 — Ottieni una chiave API ed effettua la tua prima richiesta

La tua chiave API si trova nell'app in **Impostazioni → Integrazioni → Chiave API** — una sezione dedicata all'interno di Integrazioni, separata dai Webhook, che appare solo quando l'accesso API è incluso nel piano. Generane una, copiala e conservala in un luogo sicuro (un archivio segreto lato server o una variabile d'ambiente — mai nel codice del browser). Le istruzioni complete sono disponibili in [Accesso API](../integrations/api-access.md).

Una volta ottenuta una chiave, verifica che funzioni chiamando l'endpoint di stato. Esistono diversi modi per inviare la chiave; il più semplice è il parametro di query `?apiKey=`, ma per il codice reale preferisci l'intestazione `X-API-Key` in modo che la chiave non finisca mai nei log del server o nella cronologia del browser.

**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, ... }
```

Ogni risposta corretta è racchiusa nello stesso involucro: un campo `success: true` più i dati del risultato. Gli errori restituiscono `success: false` con un messaggio `error` e un `error_code`. Consulta [Errori e Paginazione](errors-and-pagination.md) per l'elenco completo e per sapere come gli endpoint di elenco paginano con `?limit` e `?cursor`.

> **Limite di frequenza.** Le richieste autenticate hanno un limite di **300 al minuto** (con un tetto massimo più ampio di 1.200 al minuto per account). Il superamento di tale limite restituisce `429`; attendi e riprova.

---

## Passaggio 2 — Creare un Agente IA

Un **Agente IA** è l'unità che contiene il comportamento del tuo assistente: le sue istruzioni, il suo obiettivo, i suoi orari di attività e come interagisce con i contatti. È l'entità che risponde a una conversazione, quindi è la prima cosa naturale da creare.

Creane uno con `POST /agents`. `name` è l'unico campo che vale la pena inviare inizialmente; tutto il resto può essere impostato con la chiamata bot-config qui sotto.

**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"]
```

Una creazione riuscita restituisce `201` con il nuovo ID:

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

**Salva l'`agent_id`** — lo userai come riferimento quando instradi i canali.

### Configurare l'assistente

`PUT /agents/{agentId}/bot-config` imposta il comportamento dell'assistente. *Unisci* i campi che invii alla configurazione esistente, quindi tutto ciò che tralasci viene preservato:

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

Imposta gli orari di attività con `PUT /agents/{agentId}/active-hours` in modo che l'assistente risponda solo durante l'orario lavorativo; al di fuori di tali finestre non risponderà automaticamente.

> **Base di conoscenza.** Per far sì che l'assistente risponda basandosi sui tuoi contenuti, allega le FAQ. Consulta la [guida alle FAQ](faqs.md).

> **Legacy: campagne classiche.** Gli account che dispongono ancora di una pagina **Campagne** creano lo stesso comportamento dell'assistente su una campagna (`POST /campaigns` con un oggetto `type` e un oggetto `bot`, quindi `PUT /campaigns/{campaignId}/bot-config`). L'elenco completo dei campi della campagna e i controlli del ciclo di vita sono nella [guida alle Campagne](campaigns.md). Se stai creando qualcosa di nuovo, crea un Agente.

---

## Passaggio 3 — Connetti un canale

Un Agente ha bisogno di un modo per inviare e ricevere messaggi. Sette flussi di connessione possono essere gestiti dall'API: WhatsApp Business, WhatsApp Web, Instagram e Messenger insieme (un unico flusso Meta condiviso), account personali Instagram, Telegram, LINE e Viber. I restanti canali — tra cui SMS, email, widget chat e canali personalizzati — vengono configurati nella dashboard anziché tramite REST e, una volta connessi, gli endpoint di messaggistica, contatto e instradamento funzionano esattamente allo stesso modo. `GET /channels` è la fonte di verità in tempo reale per ciò che un determinato account ha effettivamente connesso:

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

L'insieme completo dei flussi di connessione/disconnessione per ogni canale è documentato nella [Guida ai canali](channels.md). Di seguito esaminiamo **WhatsApp Web** dall'inizio alla fine, poiché mostra il modello più interessante: un flusso di accoppiamento tramite codice QR che il tuo wrapper deve renderizzare e sottoporre a polling.

### Esempio pratico: accoppiamento di WhatsApp Web tramite codice QR

L'accoppiamento di WhatsApp Web è una danza in tre chiamate: **avvio**, **recupero del QR**, **polling fino alla connessione**.

**1. Avvia la sessione di accoppiamento.** Inserisci il numero che desideri connettere nel formato 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. Recupera il codice QR e mostralo all'utente.** Esegui il polling ogni 10-15 secondi. La risposta include il payload `qr_code` grezzo (renderizzalo tu stesso come immagine QR) e un `qr_data_url` pronto per la visualizzazione.

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

Nell'interfaccia utente del tuo wrapper, inserisci `qr_data_url` direttamente in un `<img src="...">` e chiedi all'utente di scansionarlo da **WhatsApp → Dispositivi collegati** sul proprio telefono. Se il QR scade (una risposta `410`), ricomincia dal passaggio 1 per ottenerne uno nuovo.

**3. Esegui il polling dello stato finché non si connette.** Dopo che l'utente ha eseguito la scansione, continua a interrogare l'endpoint di stato finché non riporta `connected` (il servizio potrebbe anche riportare `open`). Considera `disconnected` e `not_initialized` come errori terminali.

```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));
  }
}
```

> **Attenzione.** Ogni numero WhatsApp Web connesso comporta un costo di manutenzione mensile ricorrente fino a quando non lo disconnetti (`DELETE /channels/whatsapp-web/connections/{phoneNumber}`).

### Instradare il canale verso il tuo Agente

Connettere un canale lo rende operativo; instradarlo indica alla piattaforma *quale Agente IA* debba rispondere alle nuove conversazioni in entrata su di esso. Imposta il Punto di Ingresso predefinito per il canale, specificando l'Agente creato nel Passaggio 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" }'
```

Ripeti la chiamata una volta per canale — un valore predefinito per canale. Per lasciare un canale senza un Agente che risponda, chiama `DELETE /entry-points/channel-defaults?channel=whatsapp_web`; per verificare se la gerarchia dei Punti di Ingresso è attiva per l'account, chiama `GET /entry-points/routing-status`. La vecchia mappa `POST /channels/campaign` è mantenuta solo per il rollback e non viene più consultata per l'instradamento in entrata. Consulta la [guida ai Canali](channels.md) per gli altri tipi di canale e per il flusso OAuth di WhatsApp Business.

---

## Passaggio 4 — Importa i tuoi contatti

Con un canale attivo, carica le persone che vuoi raggiungere. L'endpoint di importazione accetta fino a **500 record per chiamata**. Ogni record richiede un `phone_number` in formato internazionale; tutto il resto è facoltativo. I record con numeri errati, canali non supportati o numeri già esistenti vengono ignorati — e ogni esclusione viene segnalata con il relativo indice e motivo, così da poter riprovare solo con gli elementi falliti.

**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 risposta ti indica esattamente cosa è successo:

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

Per la creazione singola, la ricerca, gli elenchi, i tag e i campi personalizzati, consulta la [Guida ai contatti](contacts.md).

---

## Passaggio 5 — Invia e leggi i messaggi

### Invia un messaggio

L'invio più semplice è **agnostico rispetto al canale**: fornisci l'identità del contatto e il corpo del messaggio, e la piattaforma lo recapiterà sul canale in cui si trova il contatto. Puoi indirizzare tramite `contact_id`, oppure tramite `channel` più il campo di identità corrispondente (`phone_number` per WhatsApp/WhatsApp Web/SMS, `instagram_id` per Instagram, e così via).

**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 consegna è **asincrona** — un `201` significa che il messaggio è stato *accettato e messo in coda*, non ancora consegnato. (I contatti con la modalità non disturbare o privata attiva vengono rifiutati con un `422`.)

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

### Leggi una conversazione

Per leggere i messaggi ricevuti, elencali per contatto, dal più recente, con paginazione a cursore. Passa il `next_cursor` da una risposta come `cursor` della successiva per risalire nella cronologia.

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

Puoi anche filtrare per tipo di contenuto (`?filter=text|media|tool_use`) o direzione (`?direction=inbound|outbound`). La [Guida ai messaggi](messages.md) copre gli allegati multimediali, la marcatura dei messaggi come letti e le visualizzazioni dei messaggi per sessione.

> **Non eseguire il polling per le risposte.** Elencare i messaggi a intervalli temporali funziona, ma spreca richieste e aggiunge latenza. Per i messaggi in arrivo, usa invece i webhook — questo è il Passaggio 7.

---

## Passaggio 6 — Leggi le analisi

Una volta che i messaggi iniziano a fluire, il riepilogo analitico fornisce conteggi aggregati su un intervallo di date: inviati, consegnati, letti, risposti, prenotati, contatti creati e crediti spesi/ricaricati. Ottieni sia i totali dell'intervallo che una serie giornaliera riempita con zeri: perfetta per un grafico di dashboard. Facoltativamente, puoi limitare l'ambito a una singola campagna con `campaign_id` (gli esempi seguenti utilizzano un ID campagna segnaposto, `abc123campaign`); ometti il parametro per ottenere i totali dell'intero account.

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

L'intervallo predefinito è di 30 giorni ed è limitato a 366. Per i record di utilizzo credito per credito e le suddivisioni dei costi dell'IA, consulta la [Guida alle analisi](analytics.md).

---

## Passaggio 7 — Iscriviti ai webhook per eventi in tempo reale

Il polling va bene per uno script rapido, ma una vera integrazione dovrebbe essere **basata su push**. I webhook consentono alla piattaforma di chiamare *il tuo* server nel momento in cui accade qualcosa: un nuovo contatto, una risposta, un appuntamento prenotato, una chat conclusa.

Per prima cosa, scopri i nomi esatti degli eventi a cui puoi iscriverti:

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

Quindi crea un'iscrizione che punti a un URL HTTPS sul tuo server. Usa le stringhe di evento esatte dalla chiamata precedente.

**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 deve utilizzare HTTPS ed essere raggiungibile pubblicamente. Da questo momento in poi, il tuo server riceverà una POST per ogni evento sottoscritto. Puoi inviare una consegna di prova, verificare lo stato di un'iscrizione e riattivare un'iscrizione disabilitata automaticamente dopo ripetuti errori: consulta la [Guida ai webhook](webhooks.md) e la pagina [Webhook](../integrations/webhooks.md) a livello di integrazioni per i formati dei payload e la verifica.

---

## Mettiamo tutto insieme

Ecco l'intero flusso a colpo d'occhio:

| Passaggio | Obiettivo | Chiamata chiave |
|---|---|---|
| 1 | Autenticazione | `GET /health` |
| 2 | Crea + configura l'assistente | `POST /agents`, `PUT /agents/{id}/bot-config`, `PUT /agents/{id}/active-hours` |
| 3 | Collega un canale e indirizzalo | `POST /channels/whatsapp-web/connections` → polling QR + stato → `PUT /entry-points/channel-defaults` |
| 4 | Carica contatti | `POST /contacts/import` |
| 5 | Invia e leggi | `POST /contacts/send`, `GET /contacts/{id}/messages` |
| 6 | Misura | `GET /analytics/summary` |
| 7 | Reagisci in tempo reale | `POST /webhooks` |

Un wrapper minimale consiste solo in queste sette chiamate collegate alla tua interfaccia utente. Da lì, aggiungi le guide specifiche per risorsa man mano che ne hai bisogno:

- [Campagne](campaigns.md) · [Contatti](contacts.md) · [FAQ](faqs.md) · [Messaggi](messages.md) · [Appuntamenti](appointments.md)
- [Canali](channels.md) · [Modelli](templates.md) · [Analisi](analytics.md) · [Webhook](webhooks.md) · [Chiavi API](api-keys.md)
- Nuovo qui? [Guida introduttiva](getting-started.md) · [Autenticazione](authentication.md) · [Errori e paginazione](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).
