L’API di WhatsApp, documentata.
REST per inviare e leggere, webhook firmati per ricevere e un server MCP pronto per il tuo agente. Integra WhatsApp nel tuo prodotto con line_id e API keys.
Da zero al tuo primo messaggio in 3 passaggi.
1. Collega una linea
Nella console, scansiona il QR con il WhatsApp del numero che vuoi usare. Ottieni un line_id.
2. Crea una chiave API
Nella console, genera una chiave API. Inizia con wzb_live_ e viene mostrata solo una volta.
3. Chiama l’API
Usa il tuo line_id e la tua API key per inviare il primo messaggio (esempio qui sotto).
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: TU_OPERACION_UNICA" \
-d '{"line_id":"TU_LINE_ID","to":"+34600000000","message":"Ciao da WAzion Bridge"}'
La console è dove gestisci le linee, le chiavi API e i webhook. La documentazione descrive la stessa API che puoi provare lì.
Base dell’API e autenticazione.
| Base REST | https://www.wazion.com/api/bridge/v1 |
|---|---|
| Server MCP | https://www.wazion.com/api/bridge/mcp |
| Intestazione | Authorization: Bearer wzb_live_... |
Tutta la richiesta viene autenticata con una API key nell’intestazione Authorization (si accetta anche X-Bridge-Key). Le chiavi API si creano nella console e iniziano per wzb_live_. Ogni risposta include un’intestazione X-Request-Id utile per supporto e debug. L’API supporta CORS (Access-Control-Allow-Origin: *).
Authorization: Bearer wzb_live_xxxxxxxxxxxxxxxxxxxxxxxx Content-Type: application/json
Come è organizzato Bridge.
line_id
Identifica una linea di WhatsApp connessa tramite QR. Ogni richiesta di invio o lettura utilizza un line_id.
API key
Credenziale wzb_live_ che autentica la tua applicazione. Puoi crearne, ruotarle e revocarle diverse nella console.
Webhook
Ricevi eventi in entrata (messaggi, stati) firmati con HMAC nell’URL che configuri.
Lavori sempre con line_id e API keys. Bridge nasconde la sessione interna di WhatsApp: non esponi né usi la session_key.
Endpoint REST.
| Azione | Endpoint |
|---|---|
| Conto, piano e limiti | GET /v1/me |
| Consumo del periodo | GET /v1/usage |
| Elencare le linee | GET /v1/lines |
| Dettaglio di una linea | GET /v1/lines/{line_id} |
| Invia testo | POST /v1/messages/send |
| Invia media | POST /v1/messages/send-media |
| Rispondere citando | POST /v1/messages/reply |
| Controllare lo stato di una spedizione | GET /v1/messages/status |
| Reagire con emoji | POST /v1/messages/react |
| Segna come letto | POST /v1/messages/read |
| Archiviare chat | POST /v1/chats/archive |
| Elencare le chat | GET /v1/chats |
| Leggere messaggi | GET /v1/messages |
| Elencare / creare webhook | GET /v1/webhooks · POST /v1/webhooks |
| Provare un webhook | POST /v1/webhooks/{id}/test |
POST /v1/messages/send
| Parametro | Tipo | Descrizione | |
|---|---|---|---|
line_id | string | obbligatorio | Linea connessa da cui viene inviato. |
to | string | obbligatorio | Telefono di destinazione in formato internazionale, ad esempio +34600000000. |
message | string | obbligatorio | Testo del messaggio. |
archive_policy | enum | opzionale | never · always · preserve_if_previously_archived |
Le spedizioni send, send-media e reply richiedono l’intestazione Idempotency-Key. Le letture GET /v1/chats e GET /v1/messages limitano il risultato a 500 e 200 rispettivamente.
Invia un messaggio nella tua lingua.
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send \
-H "Authorization: Bearer wzb_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1001" \
-d '{"line_id":"line_xxx","to":"+34600000000","message":"Pedido confirmado"}'
// Node 18+ (fetch nativo)
const res = await fetch("https://www.wazion.com/api/bridge/v1/messages/send", {
method: "POST",
headers: {
"Authorization": "Bearer wzb_live_xxx",
"Content-Type": "application/json",
"Idempotency-Key": "order-1001"
},
body: JSON.stringify({
line_id: "line_xxx",
to: "+34600000000",
message: "Pedido confirmado"
})
});
console.log(await res.json());
import requests
r = requests.post(
"https://www.wazion.com/api/bridge/v1/messages/send",
headers={
"Authorization": "Bearer wzb_live_xxx",
"Idempotency-Key": "order-1001",
},
json={
"line_id": "line_xxx",
"to": "+34600000000",
"message": "Pedido confirmado",
},
)
print(r.json())
<?php
$ch = curl_init("https://www.wazion.com/api/bridge/v1/messages/send");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer wzb_live_xxx",
"Content-Type: application/json",
"Idempotency-Key: order-1001",
],
CURLOPT_POSTFIELDS => json_encode([
"line_id" => "line_xxx",
"to" => "+34600000000",
"message" => "Pedido confirmado",
]),
]);
echo curl_exec($ch);
Invia immagine, video, audio o documento.
Usa media_type con uno de questi valori: image, video, audio, document. Il campo media_url deve essere un’URL pubblica che il server possa scaricare.
| Parametro | Tipo | Descrizione | |
|---|---|---|---|
line_id | string | obbligatorio | Linea di spedizione. |
to | string | obbligatorio | Telefono di destinazione. |
media_url | string (URL) | obbligatorio | URL pubblica del file. |
media_type | enum | opzionale | image · video · audio · document (per difetto immagine) |
caption | string | opzionale | Testo allegato al file. |
curl -X POST https://www.wazion.com/api/bridge/v1/messages/send-media \
-H "Authorization: Bearer wzb_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: media-1001" \
-d '{"line_id":"line_xxx","to":"+34600000000","media_url":"https://tu-cdn.com/foto.jpg","media_type":"image","caption":"Ciao"}'
Idempotenza.
Le spedizioni send, send-media e reply richiedono l’intestazione Idempotency-Key con un identificatore unico della tua operazione. Durante un’occorrenza, ripetere la stessa chiave con lo stesso corpo restituisce lo stato salvato senza reinviare né consumare nuovamente quota. Una chiave completata può avviare una nuova occorrenza quando scade la sua retention di 24 ore; i retry di rete dell’occorrenza attiva conservano sempre la stessa identità interna.
-H "Idempotency-Key: pedido-1001"
Le risposte queued, processing e sent_unconfirmed includono status_url per consultare GET /v1/messages/status. Solo sent con message_id conferma l’invio; sent_unconfirmed richiede riconciliazione o revisione manuale e Bridge non lo reinvia né restituisce automaticamente la sua quota. Se riutilizzi la stessa chiave attiva con un corpo diverso, ricevi 409 idempotency_conflict.
GET https://www.wazion.com/api/bridge/v1/messages/status?endpoint=messages%2Fsend&idempotency_key=pedido-1001
Ricevere eventi firmati.
Crea un webhook con un URL HTTPS pubblica. Bridge invierà un POST a quell’URL ad ogni evento. Ogni webhook ha il proprio segreto. (wzb_whsec_...) che viene mostrato una sola volta al crearlo.
Eventi a cui puoi iscriverti: message.received, message.sent, message.status, line.connected, line.disconnected. line.status è un alias di abbonamento che include entrambi gli eventi di linea.
Il campo event del corpo e l’intestazione X-WAzion-Bridge-Event usano sempre il nome normalizzato. event_id e X-WAzion-Bridge-Event-Id conservano la stessa identità in tutti i tentativi di ripetizione.
Ogni consegna include queste intestazioni:
X-WAzion-Bridge-Event: message.received
X-WAzion-Bridge-Signature: sha256=<hmac>
Content-Type: application/json
{
"event": "message.received",
"line_id": "line_xxx",
"data": { ... }
}
Verificare la firma
La firma è un HMAC-SHA256 del corpo in chiaro utilizzando il segreto del webhook. Confronta sempre prima di elaborare:
// Node.js
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
);
}
<?php
// PHP
$raw = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_WAZION_BRIDGE_SIGNATURE"] ?? "";
$expected = "sha256=" . hash_hmac("sha256", $raw, $secret);
if (!hash_equals($expected, $sig)) { http_response_code(401); exit; }
Puoi lanciare un evento di prova al tuo webhook dalla console o con POST /v1/webhooks/{id}/test.
Gestione degli errori.
Gli errori di autenticazione, account e server utilizzano una busta normalizzata:
{
"ok": false,
"error": { "code": "unauthorized", "message": "...", "retryable": false }
}
Gli errori di validazione e di business utilizzano una forma piatta con il codice in errore:
{ "error": "quota_exceeded", "message": "Monthly quota exceeded", "metric": "sent_messages", "used": 10000, "limit": 10000, "plan": "pro" }
| Codice | HTTP | Significato |
|---|---|---|
unauthorized | 401 | Chiave API assente, non valida o revocata. |
subscription_required | 402 | L’abbonamento Bridge non è attivo. |
validation_error | 400 | Mancano campi o sono invalidi. |
line_not_found | 404 | Il line_id non esiste nel tuo account. |
line_not_connected | 409 | La linea non è connessa a WhatsApp. |
idempotency_key_required | 428 | Manca l’Idempotency-Key in una spedizione durevole. |
idempotency_conflict | 409 | Stessa Idempotency-Key con corpo diverso. |
quota_exceeded | 429 | Hai superato la quota del periodo. |
line_limit_reached | 429 | Hai raggiunto il massimo di righe del piano. |
server_error | 500 | Errore interno; puoi riprovare. |
Quote per piano.
- Le quote (messaggi inviati, eventi webhook, numero di righe) sono per account e vengono conteggiate all’interno del tuo ciclo di fatturazione.
- Superando una quota ricevi 429 (quota_exceeded o line_limit_reached) con il dettaglio di used, limit e plan.
- GET /v1/chats restituisce al massimo 500 chat e GET /v1/messages al massimo 200 messaggi per richiesta.
- Per stabilità di WhatsApp, le spedizioni di una stessa linea sono distanziate di alcuni secondi; distribuisci le spedizioni massicce nel tempo.
Controlla il tuo consumo in qualsiasi momento con GET /v1/usage. I limiti concreti di ogni piano sono in la pagina dei piani.
Server MCP per il tuo agente.
Bridge espone un server MCP (Model Context Protocol) affinché il tuo agente possa inviare e leggere WhatsApp senza scrivere codice REST. Aggiungilo con:
claude mcp add --transport http wazion-bridge \ https://www.wazion.com/api/bridge/mcp \ --header "Authorization: Bearer wzb_live_xxx"
La risposta initialize restituisce Mcp-Session-Id. Il cliente deve restituire quell’intestazione: insieme all’id JSON-RPC e agli argomenti identifica in modo durevole le spedizioni MCP. Se il cliente non conserva le sessioni, deve fornire idempotency_key esplicitamente in send, send-media e reply.
| Tool | Parametri |
|---|---|
bridge_list_lines | — |
bridge_send_message | line_id, to, message, archive_policy? |
bridge_send_media | line_id, to, media_url, media_type?, caption? |
bridge_reply_message | line_id, to, message, quoted_message_id |
bridge_react_message | line_id, jid, message_id, emoji |
bridge_get_chats | line_id, limit?, archived? |
bridge_get_messages | line_id, phone, limit? |
bridge_archive_chat | line_id, phone, archive? |
Pronto per integrare.
Collega una linea, crea la tua API key e prova ogni endpoint dalla console.