Documentazione sviluppatori

Collega il tuo software alla tua inbox SyBox

Invia messaggi WhatsApp dal tuo numero, mostra i dati dei tuoi clienti accanto a ogni chat, registra casi, ricevi ogni evento sul tuo server e aggiungi una chat dal vivo al tuo sito web. Il percorso di invio usa il formato della WhatsApp Cloud API, quindi al codice scritto per Meta bastano un nuovo URL di base e una chiave SyBox.

URL di basehttps://api.smartsybox.com

Per iniziare

1. Autenticazione API & Chiavi Dispositivo

Tutte le richieste API richiedono un'autenticazione sicura tramite intestazione X-Device-Key e X-Device-Secret.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>

Il segmento di versione è accettato in qualsiasi forma v<n> (v26.0, v1.0, …) — mantieni quella che usa già il tuo codice. Il {phone-number-id} è l'ID del tuo numero WhatsApp, esattamente come su Meta.

Il {phone-number-id} compare dopo id sulla scheda del numero in Impostazioni › Messaggistica › Canali. Una chiave di invio è legata a un solo numero e invia solo da quel numero.

cURL
curl -X POST https://api.smartsybox.com/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

La scheda di ogni chiave in Impostazioni › Integrazioni › Chiavi API mostra quando è stata usata l'ultima volta — il modo più rapido per vedere se le tue chiamate arrivano.

Per iniziare

Autenticazione e chiavi

Ogni chiamata porta una chiave nell'intestazione Authorization come token Bearer. Ogni chiave ha un solo compito: una chiave creata per inviare non può registrare un caso, e una chiave creata per registrare casi non può inviare. Conserva ogni chiave sul tuo server — l'unica eccezione è la chiave pubblica della Live Chat, pensata per stare nelle tue pagine.

HTTP
Authorization: Bearer YOUR_KEY
Content-Type: application/json
ChiaveA cosa serve
Invia tramite WhatsAppPOST /v{n}/{phone-number-id}/messages
Apri una praticaPOST /v1/case
Ricevi da un programmaPOST /v1/inbound
Chiave pubblica · lcpk_<script … data-key="lcpk_…">
Chiave di firma per gli utenti connessi · lcid_Utenti connessi: la chiave di firma
Chiave del server (per la tua schermata di chat) · lcsk_/v1/livechat/*
Chiave di firma delle risposte · lcwh_x-sybox-signature
Chiave di firmaX-Hub-Signature-256

Per iniziare

9. SDK & Librerie di Integrazione

Disponibili SDK per cURL, JavaScript/Node.js, Python, PHP e C# .NET.

  1. Panoramica API
  2. Invio Messaggi
  3. Webhook & Eventi
  4. Integrazione ERP

API WhatsApp

2. Invio Messaggi WhatsApp & Omnicanale

Invia messaggi di testo, immagini, documenti e modelli approvati Meta tramite le nostre rotte REST.

POST/v26.0/{phone-number-id}/messagesAuthorization: Bearer <DEVICE_KEY>
curl -X POST https://api.smartsybox.com/v26.0/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer YOUR_DEVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "15551234567",
    "type": "text",
    "text": { "body": "Hello from SyBox" }
  }'

Esempio di risposta

La risposta include l'ID univoco del messaggio e lo stato di consegna in tempo reale.

200 OK · application/json
{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "15551234567", "wa_id": "15551234567" }],
  "messages": [{ "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgARGBI…" }]
}

API WhatsApp

3. Webhook Eventi in Tempo Reale

Poiché il corpo viene inoltrato senza modifiche, è supportato ogni tipo di messaggio della Cloud API: modelli, immagini, documenti, messaggi interattivi. Ecco l'invio di un modello.

{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "name": "order_shipped",
    "language": { "code": "en_US" },
    "components": [{
      "type": "body",
      "parameters": [{ "type": "text", "text": "#10432" }]
    }]
  }
}

Il testo libero raggiunge un cliente solo entro 24 ore dal suo ultimo messaggio. Fuori da questa finestra invia un modello approvato: lì SyBox rifiuta il testo libero con il codice 131047 prima che arrivi a Meta.

API WhatsApp

Regole e limiti delle chiavi

Ogni chiave di invio ha le proprie regole, impostate quando la crei: testo libero, modelli o entrambi; media sì o no; quali modelli; quali paesi dei destinatari; gli orari in cui può inviare; e un limite giornaliero. SyBox rifiuta un invio che ne viola una prima che arrivi a Meta.

StatoQuando
404Una risposta vuota: il Gateway API è disattivato, oppure la chiave non appartiene a nessuno spazio di lavoro. Controlla l'interruttore in cima a Impostazioni › Integrazioni › Chiavi API.
401La chiave manca o non è riconosciuta.
403La chiave non è una chiave di invio, oppure invia da un numero a cui non è associata.
403Il messaggio viola una delle regole della chiave: testo libero, modelli, media, nome del modello, paese o orari.
403Meta ha messo in pausa il modello o lo ha limitato per la sua valutazione della qualità.
400La finestra di 24 ore è chiusa (codice 131047): invia invece un modello.
400Il corpo non è un JSON valido, oppure il numero WhatsApp della chiave non è più connesso.
409Meta ha bloccato per ora gli invii da questo numero.
429È stato raggiunto il limite giornaliero della chiave o il limite di messaggistica WhatsApp del numero.
502Impossibile raggiungere Meta. Riprova.

Il conteggio giornaliero riparte a mezzanotte UTC, e un invio non riuscito non viene conteggiato.

API WhatsApp

8. Gestione Errori & Codici di Stato HTTP

Gli errori arrivano da due fonti, ed entrambe usano la struttura di errore di Meta, così un client Cloud API esistente li legge senza modifiche. Un errore di Meta torna esattamente come Meta lo ha inviato, con il codice di stato di Meta. Un errore di una delle regole di SyBox ha il type SyBoxGatewayError, e il suo message indica quale regola ha rifiutato la chiamata.

{
  "error": {
    "message": "(#131030) Recipient phone number not in allowed list",
    "type": "OAuthException",
    "code": 131030
  }
}

Il tuo sistema in SyBox

4. Integrazione Pannello ERP Integrato nel Chat

Mostra informazioni di fatturazione, saldi e ordini del cliente direttamente nella barra laterale della conversazione.

Aggiungi il tuo endpoint in Impostazioni › Integrazioni › API ERP. Ogni chiamata è una POST con la tua chiave in Authorization e la richiesta in un solo campo, data, che contiene una stringa JSON — così ciascuna delle due parti può aggiungere campi in seguito senza rompere l'altra. Rispondi entro 15 secondi.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: lookup
X-Sybox-Lang: en
X-Sybox-Theme: light
X-Sybox-Agent: 6f1c…
X-Sybox-Number: 104857600000000
Content-Type: application/json

{ "data": "{\"phone\":\"15551234567\",\"email\":\"customer@example.com\",\"ref\":\"\"}" }

Ogni chiamata dice anche chi sta chiedendo: X-Sybox-Lang (la lingua dell'utente — rispondi in quella lingua), X-Sybox-Theme (light o dark, per una risposta html), X-Sybox-Agent (l'id dell'utente) e X-Sybox-Number (la linea su cui si trova la conversazione).

Configura i webhook ERP nelle impostazioni dello spazio di lavoro.

renderAs

Rendering di schede personalizzate ERP per gli operatori dell'assistenza.

renderAsDescrizione
tableRighe e colonne. content è un array di oggetti semplici (o { rows: [ … ] }); le loro chiavi diventano le intestazioni delle colonne.
cards · kpiPiccoli riquadri, come un saldo o il numero di ordini. content è un array di { label, value } (o { cards: [ … ] }).
feed · list · threadUna sequenza cronologica di schede. content è un array di { title, text, date, tags, media: [{ type, url, name }] }.
messageUn solo record presentato come un'unica scheda in stile messaggio.
htmlIl tuo HTML, come stringa in content. Solo per markup generato da te.
sectionsPiù blocchi in una sola risposta: content è { sections: [ { title, renderAs, content } ] }.
jsonL'impostazione predefinita quando renderAs manca: SyBox mostra il tuo content come JSON formattato.

Riferimenti ai campi dati dinamici importati.

5. Catalogo Prodotti & Schede Articoli ERP

Lo stesso endpoint può anche rispondere alle ricerche di prodotti. L'utente digita ciò che il cliente sta chiedendo, SyBox lo invia come "q", e la tua risposta viene mostrata come schede prodotto accanto alla chat — con un invio con un tocco che inserisce il link del prodotto nell'editor di testo.

POST YOUR_ERP_URL
Authorization: Bearer YOUR_ERP_KEY
X-Sybox-Action: products

# the decoded "data":
{ "q": "wireless keyboard", "phone": "15551234567", "email": "customer@example.com", "ref": "" }
CampoDescrizione
nameobbligatorioNome Prodotto
price · oldPrice · currencyPrezzo Unitario
available · stockDisponibilità Magazzino
imageURL Immagine Articolo
linkLink Scheda Prodotto
noteNote e specifiche tecniche

Supporta prezzi con valute multiple e controllo delle giacenze di magazzino.

Il tuo sistema in SyBox

6. Gestione Contatti & Profili CRM

Crea, aggiorna e ricerca schede clienti e contatti aziendali via API.

POST/v1/caseAuthorization: Bearer <CASE_KEY>
curl -X POST https://api.smartsybox.com/v1/case \
  -H "Authorization: Bearer $SYBOX_CASE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_unique_id": "CUST-10432",
    "header": "Screen replacement not delivered",
    "description": "Paid on 12 Aug, promised in 3 days, still nothing.",
    "department_id": 5,
    "ext_ref": "TICKET-99817"
  }'

Campi contatto personalizzabili

CampoDescrizione
customer_unique_idIl tuo id del cliente — la stessa chiave usata dalla sincronizzazione dei clienti. Se non hai un id, invia invece phone.
phoneIl numero di telefono del cliente, se non hai un id.
header · descriptionNe è richiesto almeno uno. L'intestazione è la riga che gli utenti vedono nell'elenco.
department_idobbligatoriointegerObbligatorio. Il dipartimento in cui è registrato il caso: il numero mostrato accanto in Impostazioni › Dipartimenti (ad esempio #5).
ext_refRiferimento Esterno
sectionintegerDa 1 a 4: la scheda dei casi in cui va. Predefinito 1.
deadlinestringUna data di scadenza, YYYY-MM-DD.
notifybooleanPredefinito true: nella conversazione del cliente in SyBox compare una nota con il numero del caso. Al cliente non viene inviato nulla. Con false la nota non viene aggiunta.
sourcestringIl nome del programma mostrato su quella nota. Predefinito ERP.

La risposta contiene il numero del caso, quello che il tuo staff comunica al cliente. Un nuovo tentativo con lo stesso ext_ref risponde "duplicate": true con il caso già esistente, senza customer_id.

Il cliente deve essere già in SyBox. Se l'id non viene trovato, SyBox esegue una sincronizzazione dei clienti con il tuo sistema e cerca di nuovo; se non lo trova ancora, la risposta è 404 — mai un caso registrato su un cliente inventato.

Sincronizzazione automatica con Google Contacts se abilitata.

Il tuo sistema in SyBox

7. Limiti di Richiesta & Quote

Per garantire la stabilità della piattaforma, le richieste API sono soggette a limiti di frequenza per spazio di lavoro.

POST/v1/inboundAuthorization: Bearer <INBOUND_KEY>

Le chiavi di questo tipo non vengono più create: una chiave Ricevi da un programma già esistente continua a funzionare. Per una nuova integrazione, registra un caso — SyBox scrive la nota nella conversazione al posto tuo.

cURL
curl -X POST https://api.smartsybox.com/v1/inbound \
  -H "Authorization: Bearer $SYBOX_INBOUND_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "15551234567",
    "text": "Order 4821 has left the warehouse.",
    "source": "Warehouse"
  }'
CampoDescrizione
phoneobbligatoriostringIl numero di telefono del cliente, con il prefisso internazionale.
textobbligatoriostringIl messaggio.
sourcestringIl nome del programma, mostrato sul messaggio.

La risposta è {"ok": 1, "id": …}, l'id della nota nella conversazione.

I limiti standard consentono fino a 100 richieste al secondo per chiave API.

Eventi

Webhook: gli eventi sul tuo server

Aggiungi il tuo endpoint in Impostazioni › Integrazioni › Webhook, scegli gli eventi e i numeri, e SyBox invia ogni evento con una POST nel momento in cui accade. Un evento WhatsApp arriva nel formato webhook di Meta, così un handler scritto per Meta funziona senza modifiche.

EventoDescrizione
messageMessaggio in arrivoUn messaggio di un cliente.
statusStato del messaggioInviato, consegnato, letto o non riuscito — per un messaggio che hai inviato.
reactionReazioneUn cliente ha reagito a un messaggio.
Richiesta · SyBox → tu
POST YOUR_WEBHOOK_URL
Content-Type: application/json
X-Hub-Signature-256: sha256=5d1f0c…
x-sybox-signature: sha256=5d1f0c…
x-sybox-event: message
x-sybox-timestamp: 1761400000

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WABA_ID",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "display_phone_number": "15550001111", "phone_number_id": "PHONE_NUMBER_ID" },
        "contacts": [{ "profile": { "name": "Sara" }, "wa_id": "15551234567" }],
        "messages": [{
          "from": "15551234567",
          "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgASGBQ…",
          "timestamp": "1761400000",
          "type": "text",
          "text": { "body": "Is my order shipped?" }
        }]
      }
    }]
  }]
}

Media. Il link di Meta richiede un token Meta per essere aperto, quindi SyBox lo sostituisce con un link firmato alla propria copia del file, valido per 24 ore. Una nota vocale può riportare anche il testo trascritto in sybox.transcription, se il webhook lo richiede.

Altri canali — Messenger, Instagram, Telegram e Live Chat — arrivano nel formato di SyBox, solo per l'evento del messaggio:

JSON
{
  "object": "sybox",
  "event": "message",
  "channel": "telegram",
  "line": "8123456789",
  "workspace": "yourworkspace",
  "contact": { "key": "tg:6423115118", "name": "Sara" },
  "message": {
    "id": "812345",
    "timestamp": 1761400000,
    "type": "image",
    "text": "",
    "caption": "The broken part",
    "media": { "url": "https://api.smartsybox.com/…", "mime": "image/jpeg" }
  }
}

Chiave di firma

IntestazioneDescrizione
X-Hub-Signature-256sha256= seguito dall'HMAC-SHA256 esadecimale del corpo grezzo, calcolato con il segreto di firma del webhook — la stessa intestazione e lo stesso metodo di Meta.
x-sybox-signatureLo stesso valore, così un endpoint che riceve anche le chiamate di Meta può distinguere le nostre.
x-sybox-eventmessage, status o reaction.
x-sybox-timestampQuando è stato inviato, in secondi Unix.
x-sybox-signature-rsaUna seconda firma: rsa-sha256= seguito dalla RSA-SHA256 (PKCS#1 v1.5) in base64 di x-sybox-timestamp, un punto e il corpo grezzo.
x-sybox-key-idQuale delle nostre chiavi l'ha creata. La chiave pubblica si trova su https://api.smartsybox.com/.well-known/sybox-webhook-key.

Verifica la firma sui byte grezzi, prima di analizzarli, e confrontala in tempo costante:

const crypto = require('crypto');

// express.raw: the signature is over the bytes as sent, so read them before any JSON parser.
app.post('/sybox/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sent = Buffer.from(req.get('X-Hub-Signature-256') || '');
  const want = Buffer.from('sha256=' + crypto
    .createHmac('sha256', process.env.SYBOX_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex'));
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);                       // answer first, then do the work
  const event = JSON.parse(req.body);
  const kind = req.get('x-sybox-event');     // message | status | reaction
});

Preferisci non tenere un segreto condiviso sul tuo server? Verifica invece x-sybox-signature-rsa con la nostra chiave pubblica. In entrambi i casi, rifiuta un timestamp più vecchio di cinque minuti.

Rispondi con un qualsiasi 2xx entro 15 secondi. Qualsiasi altra risposta — un errore, un timeout, un reindirizzamento — viene ritentata dopo 1, 2, 4, 8, 16 e 32 minuti, poi scartata. Un evento può arrivare più di una volta: usa l'id del messaggio per ignorare un duplicato. L'indirizzo deve essere pubblico e in https.

Per fare una prova, invia un messaggio al tuo numero e guarda Ultimo invio sulla scheda del webhook: mostra la risposta del tuo server.

Live Chat

Live Chat

Aggiungi una chat al tuo sito web: i visitatori scrivono lì, il tuo team risponde in SyBox. Aggiungi il sito web in Impostazioni › Messaggistica › Canali, nella scheda Live Chat; la finestra che si apre, Codice per il tuo sito, ti fornisce il codice e le chiavi qui sotto. Le tre chiavi segrete vengono mostrate una sola volta.

ChiaveInizia conA cosa serve
Chiave pubblicalcpk_Va nelle tue pagine. Si può pubblicare senza rischi: identifica solo il sito web, e la chat compare solo sui tuoi Indirizzi del sito web.
Chiave di firma per gli utenti connessilcid_Solo sul tuo server. Firma ogni utente connesso, così nessuno può scrivere al posto di un altro.
Chiave del server (per la tua schermata di chat)lcsk_Solo sul tuo server. Solo per un sito che crea la propria schermata di chat invece di usare la chat pronta.
Chiave di firma delle rispostelcwh_Solo sul tuo server. Dimostra che una risposta inviata al tuo server proviene da SyBox.

La chat pronta richiede solo il codice. La chiave di firma serve a un sito con account utente; la chiave del server e la chiave di firma delle risposte solo a un sito con la propria schermata di chat.

Disattivare un sito web nasconde subito la chat. Le chiamate del tuo server vengono comunque accettate e salvate.

Aggiungi la chat al tuo sito

Incolla il codice una volta in ogni pagina, subito prima del tag di chiusura body. La chat compare solo sugli indirizzi in Indirizzi del sito web, e colore, posizione, titolo e messaggio di benvenuto si impostano in SyBox, non nel codice.

HTML
<script async src="https://api.smartsybox.com/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

WordPress: scarica il nostro plugin dalla stessa finestra. Shopify: nell'app Shopify di SyBox attiva Live Chat su questo negozio, poi SyBox Live Chat in Incorporamenti app — un cliente connesso viene riconosciuto senza fare altro.

Utenti connessi: la chiave di firma

Quando un utente ha effettuato l'accesso al tuo sito, il tuo server comunica alla chat chi è con un breve token — un JWT, HS256 — firmato con la chiave di firma. L'utente ha così un'unica conversazione a suo nome, su ogni dispositivo, e nessuno può aprirla digitando l'id di qualcun altro.

  1. Dopo l'accesso, il tuo server crea il token con i claim qui sotto.
  2. La pagina lo passa alla chat come identity, prima del codice della chat.
  3. Dopo un accesso senza ricaricare la pagina, chiama invece SyBoxChat('identify', token).
CampoDescrizione
subobbligatoriostringL'id del tuo utente, fino a 120 caratteri. Non può iniziare con v_.
expobbligatorionumberScadenza, in secondi Unix — non oltre un giorno da adesso. Dieci minuti vanno bene: il token viene letto solo quando la chat si apre.
namestringIl nome mostrato dalla conversazione.
emailstringL'indirizzo email dell'utente.
phonestringIl numero di telefono dell'utente.
picturestringUn indirizzo https della foto dell'utente, fino a 500 caratteri. SyBox ne conserva una propria copia e la scarica di nuovo al successivo accesso se l'indirizzo cambia.
function b64url(string $s): string { return rtrim(strtr(base64_encode($s), '+/', '-_'), '='); }

$header  = b64url(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
$payload = b64url(json_encode([
    'sub'   => (string) $user->id,
    'name'  => $user->name,
    'email' => $user->email,
    'exp'   => time() + 600,          // ten minutes
]));
$signature = b64url(hash_hmac('sha256', "$header.$payload", getenv('SYBOX_LC_SIGNING_KEY'), true));
$token = "$header.$payload.$signature";
HTML
<script>
  window.SyBoxChatConfig = { identity: "TOKEN_FROM_YOUR_SERVER", locale: "en" };
</script>
<script async src="https://api.smartsybox.com/lc/w.js" data-key="lcpk_YOUR_PUBLIC_KEY"></script>

Crea il token solo sul tuo server. Una chiave di firma in una pagina web permette a chiunque di scrivere come uno qualsiasi dei tuoi utenti. E non mettere mai nella pagina un semplice id utente al posto del token: chiunque potrebbe scegliere quale conversazione leggere.

Con Solo gli utenti connessi al mio sito attivo, un visitatore senza token non vede la chat.

A un visitatore che ha scritto in chat prima di accedere viene chiesto una sola volta, nello stesso browser, se vuole continuare quella conversazione con il suo account. Non devi fare nulla.

Controlla la chat dalla tua pagina

Il codice della chat aggiunge una funzione alla tua pagina, SyBoxChat:

JavaScript
SyBoxChat('open');                       // open the chat
SyBoxChat('close');                      // close it
SyBoxChat('identify', token);            // after a sign-in without a page reload
SyBoxChat('locale', 'fr');               // the chat's language
SyBoxChat('on', 'message', function (m) {
  // a reply arrived
});
SyBoxChat('on', 'open', function () { /* the chat opened */ });
SyBoxChat('on', 'close', function () { /* the chat closed */ });

// Before the chat's code, every setting is optional:
window.SyBoxChatConfig = {
  identity: 'TOKEN_FROM_YOUR_SERVER',    // a signed-in user (see above)
  name: 'Sara', email: 'sara@example.com', // a visitor without an account: fills the form for them
  locale: 'ar',
  serviceWorker: 'auto'                   // 'auto' | '/your-sw.js' | 'site' | 'off'
};

Notifiche dopo la chiusura del sito

Mentre una pagina del tuo sito è aperta, una risposta compare da sola come notifica. Per raggiungere un visitatore dopo che ha chiuso il tuo sito, i browser richiedono un service worker sul tuo dominio: servi questa sola riga come /sybox-lc-sw.js nella radice del sito, come application/javascript.

/sybox-lc-sw.js
try { importScripts('https://api.smartsybox.com/lc/sw.js'); } catch (e) {}

Scegli la modalità in SyBox (Notifiche a sito chiuso) o nella pagina con serviceWorker: "auto" (il file qui sopra, l'impostazione predefinita), un tuo percorso, "site" (metti la stessa riga all'inizio del tuo service worker) o "off".

La chat non sostituisce mai un service worker già presente sul tuo sito, e il file non ha un gestore fetch, quindi non vede mai le richieste del tuo sito. Il plugin WordPress serve il file per te. Safari su iPhone non mostra notifiche per un normale sito web.

La tua schermata di chat: la chiave del server

Un sito o un'app con la propria schermata di chat comunica con SyBox dal suo server invece di usare la chat pronta. Ogni chiamata porta Authorization: Bearer lcsk_…. Il tuo server identifica l'utente con il tuo id, e SyBox se ne fida perché il server possiede la chiave.

ChiamataDescrizione
POST /v1/livechat/messagesIl tuo utente scrive. client_id rende sicuro un nuovo tentativo: lo stesso id viene salvato una sola volta ("duplicate": 1).
POST /v1/livechat/uploadUn file, come dati di un modulo multipart: file, user_id, client_id. Fino a 16 MB: immagini, audio, video, PDF, testo e documenti Office.
GET /v1/livechat/messages?user_id=&since=&before=&limit=La conversazione: i messaggi dopo since e agents_read_id, il più recente dei messaggi del tuo utente letto da un agente.
POST /v1/livechat/readIl tuo utente ha letto le risposte fino a up_to.
POST /v1/livechat/editIl tuo utente modifica un proprio messaggio, entro 15 minuti.
POST /v1/livechat/deleteIl tuo utente elimina un proprio messaggio per tutti, entro 24 ore.
POST /v1/livechat/reactUna reazione a qualsiasi messaggio; un emoji vuoto la rimuove.
POST /v1/livechat/typingIl tuo utente sta scrivendo: invia on: 1 ogni pochi secondi e on: 0 quando smette.
curl -X POST https://api.smartsybox.com/v1/livechat/messages \
  -H "Authorization: Bearer $SYBOX_LC_SERVER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user":    { "id": "u42", "name": "Sara Ali", "email": "sara@example.com", "locale": "ar" },
    "message": { "client_id": "a1b2c3", "text": "Hi, is my order on its way?", "reply_to": "" }
  }'

Un messaggio, nella cronologia e nelle risposte:

JSON
{
  "id": 990,
  "guid": "b81d…",
  "dir": "out",                       // "in" = your user wrote it, "out" = your team
  "type": "image",                    // text | image | audio | video | file
  "text": "Here is the tracking page",
  "media": { "url": "https://api.smartsybox.com/…", "mime": "image/png", "name": "tracking.png", "w": 1080, "h": 720 },
                                       // a voice note or a video also has "secs"
  "status": 3,                         // on your user's messages: 1 received, 3 read by an agent
  "reply_to": "7c9e…",
  "client": "a1b2c3",                  // on your user's messages: the client_id you sent
  "react_us": "",                      // your team's reaction on it
  "react_me": "👍",                    // your user's reaction on it
  "at": "2026-10-25T09:41:07Z",
  "edited": 0
}

La cronologia di un utente che non ha mai scritto risponde 404 unknown_user: mostra una conversazione vuota.

I link ai media sono firmati e funzionano per un'ora; richiedine uno nuovo quando scade. SyBox non scarica mai un file da un indirizzo che invii: caricalo. Fino a 120 chiamate al minuto per sito web.

Risposte sul tuo server: la chiave di firma delle risposte

Inserisci Indirizzo del tuo server per le risposte nel sito web. Quando il tuo team risponde, modifica, elimina o legge, SyBox invia lì l'evento con una POST, firmato con la chiave di firma delle risposte.

IntestazioneDescrizione
x-sybox-signaturet=TIMESTAMP,v1=SIGNATURE — TIMESTAMP in secondi Unix, SIGNATURE l'HMAC-SHA256 esadecimale di TIMESTAMP.BODY (il body grezzo), calcolato con la chiave di firma delle risposte.
x-sybox-eventmessage.created, message.updated, message.deleted o messages.read.
x-sybox-deliveryLo stesso a ogni nuovo tentativo di un evento: usalo per ignorare un duplicato.

Il corpo contiene event, line_id, user_id e message — oppure message_id per un'eliminazione e read_id per messages.read: i messaggi del tuo utente sono stati letti fino a quell'id.

const crypto = require('crypto');

app.post('/sybox/livechat', express.raw({ type: 'application/json' }), (req, res) => {
  const parts = Object.fromEntries((req.get('x-sybox-signature') || '').split(',').map(p => p.split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(401);   // older than five minutes

  const want = Buffer.from(crypto.createHmac('sha256', process.env.SYBOX_LC_REPLY_KEY)
    .update(t + '.').update(req.body).digest('hex'));
  const sent = Buffer.from(parts.v1 || '');
  if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) return res.sendStatus(401);

  res.sendStatus(200);
  const delivery = req.get('x-sybox-delivery');   // seen it already? ignore
  const evt = JSON.parse(req.body);               // { event, line_id, user_id, message | message_id | read_id }
});

Verifica la firma sul corpo grezzo, rifiuta un t più vecchio di cinque minuti e rispondi subito con 2xx. Qualsiasi altra risposta viene ritentata dopo 10 s, 30 s, 2 min, 10 min e 30 min, poi scartata. SyBox chiama solo indirizzi pubblici e non segue mai un reindirizzamento.

Codici di motivo

Ogni risposta della Live Chat è JSON — {"ok": 1, …}, oppure {"ok": 0, "error": "CODE"} con un codice invece di una frase:

CodiceStatoDescrizione
unauthorized401La chiave del server è errata o è stata sostituita.
invalid_json invalid_payload invalid_user_id400La richiesta non ha la struttura prevista.
empty_message no_file empty_file400Nessun testo e nessun file.
too_long400Il testo modificato supera i 4.096 caratteri.
not_an_emoji400emoji non è un'emoji.
not_found404Il messaggio non esiste, oppure non appartiene a questo utente.
too_late409Il tempo per modificare o eliminare è scaduto.
file_type_not_allowed400Questo tipo di file non è accettato.
file_too_large413Il file supera i 16 MB.
blocked403Il tuo team ha bloccato questo utente.
unknown_user404Ancora nessuna conversazione per questo id utente.
rate_limited429Troppe chiamate: rallenta e riprova.
maintenance503SyBox si sta aggiornando: riprova dopo Retry-After secondi.
server_error500Qualcosa non ha funzionato da parte nostra.

Sostituire una chiave

Hai perso una chiave o pensi che sia trapelata? Nella scheda del sito web, fai clic su Nuova chiave di firma, Nuova chiave del server o Nuova chiave di firma delle risposte. Una nuova chiave del server lascia funzionare quella vecchia per un giorno, così puoi passare alla nuova senza interruzioni; le altre chiavi smettono subito di funzionare.