WAuto API v1

Integra WhatsApp nella tua applicazione tramite semplici chiamate REST.

Base URL
http://www.telmio.it/api/v1
Autenticazione Bearer

Ogni richiesta deve includere la tua API key nell'header Authorization.

JSON everywhere

Tutte le richieste e risposte usano Content-Type: application/json.

CORS abilitato

Tutti gli endpoint supportano richieste cross-origin.

Autenticazione

Genera la tua API key dalla Dashboard → API Keys e includila in ogni richiesta:

Header HTTP
Authorization: Bearer wa_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

In alternativa, puoi passare la chiave come query parameter ?api_key= (sconsigliato per produzione) oppure nel body JSON come campo api_key.

Gestione errori

Tutte le risposte di errore hanno lo stesso schema:

{
  "success": false,
  "error": "Descrizione dell'errore"
}
HTTP StatusSignificato
200Successo
400Parametri mancanti o non validi
401API key mancante o non valida
403API key disabilitata o consenso mancante
405Metodo HTTP non supportato
502Errore downstream (sistema WhatsApp)

POST /messages/send

Invia un messaggio WhatsApp (testo o media) a un numero di telefono.

Richiesta
CampoTipoRichiestoDescrizione
phonestringrequiredNumero in formato internazionale senza + (es: 393312345678)
messagestringoptionalTesto del messaggio. Obbligatorio se non si invia un media.
media_urlstringoptionalURL pubblico del file media da inviare. Alternativo a media_base64.
media_base64stringoptionalContenuto del file media codificato in Base64. Alternativo a media_url. Max 16 MB decoded.
media_mimestringoptionalMIME type del file (es: image/jpeg, application/pdf). Obbligatorio con media_base64.
media_typestringoptionalTipo media: image video audio document. Obbligatorio con media_url o media_base64.
media_captionstringoptionalDidascalia per immagini e video.
media_filenamestringoptionalNome del file (utile per documenti).
force_consentbooloptionalSe true invia il messaggio anche se il contatto non ha ancora dato il consenso. Default: false. Usare con attenzione: rispettare le normative GDPR/Privacy.
Esempi
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "message": "Ciao! Come possiamo aiutarti?"
}
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "media_url": "https://example.com/promo.jpg",
  "media_type": "image",
  "media_caption": "La nostra offerta speciale!"
}
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "media_base64": "/9j/4AAQSkZJRgABAQAA...",
  "media_mime": "image/jpeg",
  "media_type": "image",
  "media_caption": "La nostra offerta speciale!"
}

// media_base64: contenuto del file codificato in Base64 (max 16 MB)
// media_mime:   MIME type del file (obbligatorio con media_base64)
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "media_url": "https://example.com/catalogo.pdf",
  "media_type": "document",
  "media_filename": "catalogo-2026.pdf",
  "media_caption": "Il nostro catalogo aggiornato"
}
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "media_base64": "JVBERi0xLjQKJ...",
  "media_mime": "application/pdf",
  "media_type": "document",
  "media_filename": "catalogo-2026.pdf",
  "media_caption": "Il nostro catalogo aggiornato"
}

// media_base64: contenuto del file codificato in Base64 (max 16 MB)
// media_mime:   MIME type del file (obbligatorio con media_base64)
curl -X POST 'http://www.telmio.it/api/v1/messages/send' \
  -H 'Authorization: Bearer wa_xxxx' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"393312345678","message":"Ciao!"}'
POST http://www.telmio.it/api/v1/messages/send
Authorization: Bearer wa_xxxx
Content-Type: application/json

{
  "phone": "393312345678",
  "message": "Ciao! Ti contatto per informarti sulla nostra offerta.",
  "force_consent": true
}
Risposta
{
  "success": true,
  "message_id": "3EB09762AC334B998BA875"
}

OUTBOUND Webhook in uscita

A differenza degli endpoint sopra (che tu chiami per inviare messaggi), questo è WAuto che chiama il tuo servizio: ogni messaggio in arrivo sul numero WhatsApp collegato viene inoltrato via POST all'URL che configuri, così un servizio esterno può leggerlo/interpretarlo (es. un bot, un CRM, un sistema di ticketing).

Configura URL e attivazione da Dashboard → API Keys → Webhook in uscita. Il secret di firma viene generato automaticamente al primo salvataggio con un URL valido.
Richiesta che riceverai
HeaderValore
Content-Typeapplication/json
X-WhatsAuto-Signature sha256=<hmac> — HMAC-SHA256 del corpo della richiesta (raw JSON), calcolato con il tuo secret. Verifica sempre questa firma prima di elaborare la richiesta.
Corpo della richiesta
CampoTipoDescrizione
eventstringSempre "message.received"
message_idint|nullID interno del messaggio in WAuto
wa_message_idstring|nullID del messaggio lato sistema WhatsApp
fromstringNumero del mittente (senza @s.whatsapp.net)
tostring|nullNumero/device che ha ricevuto il messaggio
typestringtext audio image document
bodystring|nullTesto del messaggio (per gli audio, il testo trascritto)
media_urlstring|nullURL del media, se presente
transcriptionstring|nullTrascrizione dell'audio, se disponibile (duplica body per i messaggi audio)
timestampstringData/ora del messaggio, YYYY-MM-DD HH:MM:SS
Esempio
POST https://tuo-servizio.example.com/webhook
Content-Type: application/json
X-WhatsAuto-Signature: sha256=5d41402abc4b2a76b9719d911017c59...

{
  "event": "message.received",
  "message_id": 1042,
  "wa_message_id": "3EB09762AC334B998BA875",
  "from": "393312345678",
  "to": "393209269241",
  "type": "text",
  "body": "Vorrei prenotare per domani alle 15",
  "media_url": null,
  "transcription": null,
  "timestamp": "2026-07-19 14:32:10"
}
Cosa deve rispondere il tuo servizio

Qualsiasi risposta HTTP 2xx entro 10 secondi è considerata un successo (il corpo della risposta viene ignorato). Se il tuo servizio non risponde in tempo o restituisce un errore, WAuto registra il fallimento nei log ma non ritenta automaticamente l'invio e continua a elaborare il messaggio normalmente (il webhook non blocca mai il resto del flusso).

Verificare la firma
const crypto = require('crypto');

function isValidSignature(rawBody, signatureHeader, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}

// Express: usa express.raw() o un middleware che ti dia il body grezzo,
// la firma va calcolata sul JSON esattamente come arrivato, non su un oggetto ri-serializzato.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-whatsauto-signature'] || '';
  if (!isValidSignature(req.body, signature, process.env.WHATSAUTO_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const message = JSON.parse(req.body);
  console.log('Nuovo messaggio:', message);
  res.sendStatus(200);
});
import hashlib
import hmac

def is_valid_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

# Flask
@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-WhatsAuto-Signature', '')
    if not is_valid_signature(request.get_data(), signature, WHATSAUTO_WEBHOOK_SECRET):
        return 'Invalid signature', 401
    message = request.get_json()
    print('Nuovo messaggio:', message)
    return '', 200
<?php
$rawBody = file_get_contents('php://input');
$signatureHeader = $_SERVER['HTTP_X_WHATSAUTO_SIGNATURE'] ?? '';
$secret = getenv('WHATSAUTO_WEBHOOK_SECRET');

$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
if (!hash_equals($expected, $signatureHeader)) {
    http_response_code(401);
    exit('Invalid signature');
}

$message = json_decode($rawBody, true);
error_log('Nuovo messaggio: ' . print_r($message, true));
http_response_code(200);

Quickstart SDK

const WHATSAUTO_KEY = 'wa_xxxx';
const API_BASE = 'http://www.telmio.it/api/v1';

async function sendMessage(phone, message) {
  const res = await fetch(`${API_BASE}/messages/send`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${WHATSAUTO_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ phone, message })
  });
  return res.json();
}

async function sendConsent(phone, firstName, lastName) {
  const res = await fetch(`${API_BASE}/consent/send`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${WHATSAUTO_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ phone, first_name: firstName, last_name: lastName })
  });
  return res.json();
}

// Uso
sendMessage('393312345678', 'Ciao dal nostro sistema!').then(console.log);
import requests

WHATSAUTO_KEY = 'wa_xxxx'
API_BASE = 'http://www.telmio.it/api/v1'

headers = {
    'Authorization': f'Bearer {WHATSAUTO_KEY}',
    'Content-Type': 'application/json'
}

def send_message(phone: str, message: str):
    r = requests.post(f'{API_BASE}/messages/send',
        headers=headers,
        json={'phone': phone, 'message': message})
    r.raise_for_status()
    return r.json()

def send_consent(phone: str, first_name='', last_name=''):
    r = requests.post(f'{API_BASE}/consent/send',
        headers=headers,
        json={'phone': phone, 'first_name': first_name, 'last_name': last_name})
    r.raise_for_status()
    return r.json()

# Uso
print(send_message('393312345678', 'Ciao dal nostro sistema!'))
<?php
define('WHATSAUTO_KEY', 'wa_xxxx');
define('API_BASE', 'http://www.telmio.it/api/v1');

function whatsauto_request(string $endpoint, array $data): array {
    $ch = curl_init(API_BASE . $endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . WHATSAUTO_KEY,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode($data),
    ]);
    $body = curl_exec($ch);
    curl_close($ch);
    return json_decode($body, true);
}

// Invia messaggio
$r = whatsauto_request('/messages/send', [
    'phone'   => '393312345678',
    'message' => 'Ciao dal nostro sistema!',
]);
print_r($r);

// Invia consenso
$r = whatsauto_request('/consent/send', [
    'phone'      => '393312345678',
    'first_name' => 'Mario',
    'last_name'  => 'Rossi',
]);
print_r($r);