# Onboarding ospitato (il tuo cliente collega il suo numero)

`POST /v1/onboarding-links`

Quando il numero è del tuo cliente e non vuoi chiedergli le sue credenziali di Meta, è lui stesso a collegare il suo WhatsApp in una pagina con **il tuo marchio** — senza login, senza vedere il nostro marchio, senza che tu tocchi l'app di Meta. Ci sono **due modi**, scegli il tuo:

**1. Mandagli un link (senza codice).** Generi il link dal pannello (Numeri → 'Invia un link a un cliente') e glielo passi tu (via WhatsApp, email, come preferisci). Ideale per collegare i clienti uno alla volta. Non devi scrivere niente.

**2. Integralo nel tuo sistema (con codice).** Il tuo cliente tocca 'Collega WhatsApp' dentro il TUO prodotto e si collega da solo, senza che tu intervenga. Il flusso: il tuo backend chiama `POST /v1/onboarding-links` con `label`, `externalId` (e `returnOrigin` se userai un popup) → riceve un `url` → lo mandi lì con un **reindirizzamento** (il più robusto, consigliato su mobile) o un **popup** (sembra integrato). Quando finisce, il risultato ti arriva via `postMessage` E tramite il webhook `connection.created` con il tuo `externalId`. Lo snippet di frontend e gli esempi di backend sono qui sotto.

In entrambi i casi puoi fissare la modalità (`cloud_api`/`coexistence`; se la ometti, la pagina collega in Coexistence senza offrire una scelta) e la lingua della pagina (`lang`: es/it/en/pt, oppure omettila per rilevarla dal browser). Il token è **monouso** e scade: la scadenza è configurabile (`expiresIn` in secondi, da 5 min a 30 giorni) — via API il valore predefinito è **1 ora**, dal pannello **7 giorni**.

## Esempi

### cURL

```bash
curl -X POST https://api.waiaconnect.com/v1/onboarding-links \
  -H "Authorization: Bearer wc_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label":"López Pharmacy","externalId":"pharmacy-42","lang":"es","returnOrigin":"https://app.yourcompany.com","expiresIn":3600}'
# → { "url": "https://…/c/<token>", "expiresAt": "…", "publicId": "onb_…" }
# Send url to your customer. It is shown ONCE; the token is consumed only when they connect.
```

### Node.js

```javascript
// Call this from YOUR backend when your customer taps "Connect WhatsApp".
const res = await fetch("https://api.waiaconnect.com/v1/onboarding-links", {
  method: "POST",
  headers: { "Authorization": "Bearer wc_live_YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
  "label": "López Pharmacy",
  "externalId": "pharmacy-42",
  "lang": "es",
  "returnOrigin": "https://app.yourcompany.com",
  "expiresIn": 3600
})
});
const { url } = await res.json(); // https://…/c/<token> — hand this to the browser (redirect or popup)
```

### PHP

```php
<?php
// Call this from YOUR backend when your customer taps "Connect WhatsApp".
$ch = curl_init("https://api.waiaconnect.com/v1/onboarding-links");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer wc_live_YOUR_API_KEY", "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["label" => "López Pharmacy","externalId" => "pharmacy-42","lang" => "es","returnOrigin" => "https://app.yourcompany.com","expiresIn" => 3600]),
]);
$out = json_decode(curl_exec($ch), true);
echo $out["url"]; // https://…/c/<token> — hand this to the browser (redirect or popup)
```

### Python

```python
import requests
# Call this from YOUR backend when your customer taps "Connect WhatsApp".
res = requests.post("https://api.waiaconnect.com/v1/onboarding-links",
  headers={"Authorization": "Bearer wc_live_YOUR_API_KEY", "Content-Type": "application/json"},
  json={"label":"López Pharmacy","externalId":"pharmacy-42","lang":"es","returnOrigin":"https://app.yourcompany.com","expiresIn":3600})
res.raise_for_status()
print(res.json()["url"])  # https://…/c/<token> — hand this to the browser (redirect or popup)
```

Generi un link con il marchio del tuo cliente; lui collega il suo numero senza entrare nel tuo pannello né vedere il nostro marchio. Ricevi `connection.created` con il tuo `externalId`. Il dettaglio completo (diagramma, snippet del popup, e perché mai in un iframe) è dentro il pannello, con i tuoi dati reali.

## Note

- L'URL (con il token) viene restituito UNA sola volta, come una API key — mandalo e salvalo.
- Il token si consuma solo quando viene **creata la connessione**, non quando si apre la pagina. Se il tuo cliente chiude la finestra o gli salta la connessione a internet, **riapre lo STESSO link** e continua — finché non scade.
- **Il webhook è la fonte affidabile.** Il `postMessage` si perde se il tuo cliente chiude la finestra; il webhook `connection.created` no. Conferma lato server con quell'evento.
- ⚠ **Mai dentro un iframe:** lì il popup di Embedded Signup si rompe (restrizioni sui popup + blocco dei cookie di terze parti). Usa un reindirizzamento o un popup di primo livello.
- Per il **popup**, `returnOrigin` è obbligatorio: è l'origine https esatta a cui rispondiamo (mai `*`), validata quando crei il link.
- Il tuo cliente non vede MAI il nostro marchio né entra nel tuo pannello; tu non entri MAI nel suo account Meta. Configura il tuo marchio in Impostazioni → Marchio.
- Stati del link: `pending` (non usato), `used` (ha già collegato), `expired` (scaduto), `revoked` (l'hai annullato tu). Revoca un link in sospeso con `DELETE /v1/onboarding-links/:id`.
- **Sezione Link del pannello:** lì vedi quelli che hai mandato (di entrambi i tipi), a quale cliente, quando scadono e a che punto sono — **non aperto** / **aperto e non completato** / **completato**. Un link senza attività era ambiguo: non c'era modo di distinguere "non l'ha visto" da "si è bloccato nel modulo", che richiedono azioni diverse.
- 🔒 Dell'apertura registriamo **solo che è avvenuta e quando** (la prima, l'ultima e quante volte). **Niente del visitatore**: né IP, né browser, né referer. `GET /v1/onboarding-links` restituisce `engagement`, `firstOpenedAt`, `lastOpenedAt` e `openCount`.
- Dal pannello puoi **copiare di nuovo l'URL** di un link ancora valido (owner/admin, con registro di audit). Quello di un link usato/scaduto/revocato non viene mostrato: non servirebbe a niente.
