ExoVoIPManuale sviluppatori

Autenticazione

Ogni richiesta (tranne GET /health) richiede una chiave API. Il pannello usa le stesse API con la sessione dell'utente.

Chiavi API

Formato: exo_live_<id><segreto> oppure exo_test_<id><segreto>. Due modi equivalenti di inviarla:

# Entrambe le forme sono equivalenti
curl -s https://centralino.exovoip.it/api/v1/extensions -H "X-API-Key: $EXOPBX_API_KEY"
curl -s https://centralino.exovoip.it/api/v1/extensions -H "Authorization: Bearer $EXOPBX_API_KEY"

Ogni chiave ha:

ProprietàSignificato
ScopePermessi concessi (es. extensions:read, calendars:write).
IP consentitiFacoltativo: solo questi indirizzi o reti (CIDR). Da altri IP: 403 IP_NOT_ALLOWED.
ScadenzaFacoltativa. Dopo la scadenza: 401 API_KEY_EXPIRED.
AziendaLe chiavi create dal pannello di un'azienda operano solo su quella azienda.

Il segreto è salvato come impronta (SHA-256): Exobyte non può recuperarlo. Se lo perdi, ruota la chiave.

Creazione, rotazione e revoca via API

Servono gli scope api_keys:read / api_keys:write.

curl -s -X POST https://centralino.exovoip.it/api/v1/api-keys \
  -H "X-API-Key: $EXOPBX_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Integrazione CRM","scopes":["extensions:read","cdr:read","live:read"],
       "allowedIps":["203.0.113.10"],"expiresAt":"2027-12-31T23:00:00.000Z"}'

La rotazione crea una nuova chiave con gli stessi permessi; la precedente resta valida per il periodo di sovrapposizione indicato, così puoi aggiornare i sistemi senza interruzioni.

# La vecchia chiave resta valida per 24 ore, poi scade
curl -s -X POST https://centralino.exovoip.it/api/v1/api-keys/12/rotate \
  -H "X-API-Key: $EXOPBX_API_KEY" -H "Content-Type: application/json" \
  -d '{"overlapHours":24}'

curl -s -X POST https://centralino.exovoip.it/api/v1/api-keys/12/revoke -H "X-API-Key: $EXOPBX_API_KEY"
DescrizioneRichiestaScopeMetodo SDK
Elenco chiavi APIGET /v1/api-keysapi_keys:readapiKeys.list() · py: api_keys.list()
Crea chiave (segreto mostrato una volta)POST /v1/api-keysapi_keys:writeapiKeys.create() · py: api_keys.create()
Dettaglio chiaveGET /v1/api-keys/:idapi_keys:readapiKeys.get() · py: api_keys.get()
Modifica nome, scope, IP, scadenzaPATCH /v1/api-keys/:idapi_keys:writeapiKeys.update() · py: api_keys.update()
Rotazione con periodo di sovrapposizionePOST /v1/api-keys/:id/rotateapi_keys:writeapiKeys.rotate() · py: api_keys.rotate()
Revoca immediataPOST /v1/api-keys/:id/revokeapi_keys:writeapiKeys.revoke() · py: api_keys.revoke()
Log di utilizzoGET /v1/api-keys/:id/usageapi_keys:readapiKeys.usage() · py: api_keys.usage()
Consumi giornalieri (30 giorni)GET /v1/api-keys/:id/usage/statsapi_keys:readapiKeys.usageStats() · py: api_keys.usage_stats()

Scope

Formato <risorsa>:<azione>. <risorsa>:* concede tutte le azioni della risorsa, * tutti gli scope aziendali.

ScopeCosa permette
extensions:read / extensions:writeInterni, credenziali SIP, deviazioni, codici funzione
trunks:read / trunks:writeLinee SIP dell'azienda
numbers:read / numbers:writeNumeri e loro destinazione
inbound_routes:read / inbound_routes:writeRegole in entrata
outbound_routes:read / outbound_routes:writeRegole di uscita e blocchi
calendars:read / calendars:writeOrari, festività, eccezioni, forzature
ivrs:read / ivrs:writeMenu vocali
ring_groups:read / ring_groups:writeGruppi di squillo
queues:read / queues:writeCode e operatori
media:read / media:writeMessaggi vocali e musica d'attesa
recordings:read / recordings:writeRegistrazioni, trascrizioni, regole e impostazioni
voicemail:read / voicemail:writeSegreteria
contacts:read / contacts:writeRubrica
cdr:readRegistro chiamate
live:readStato in tempo reale ed eventi
calls:controlControllo chiamate
notifications:read / notifications:writeNotifiche email e Telegram
webhooks:read / webhooks:writeWebhook
api_keys:read / api_keys:writeChiavi API

Scope di piattaforma (solo chiavi globali Exobyte): tenants:*, security:*, system:*. Una chiave aziendale non può mai ottenerli, nemmeno con *.

Ruoli del pannello

Gli utenti del pannello hanno permessi in base al ruolo:

RuoloPermessi
Amministratore piattaformaTutto, su tutte le aziende
Amministratore aziendaTutti gli scope aziendali
SupervisoreLettura, tempo reale e controllo chiamate
UtenteSolo il proprio interno: dettagli, segreteria, registro chiamate, tempo reale

Chiavi globali e X-Tenant-Id

Le chiavi globali (create dall'amministratore della piattaforma) operano su tutte le aziende:

  • sugli endpoint di un'azienda l'header X-Tenant-Id è obbligatorio (altrimenti 400 TENANT_REQUIRED);
  • sugli endpoint con vista globale (linee, numeri, registro chiamate, chiavi, tempo reale, webhook) senza header si ottengono i dati di tutte le aziende, ognuno con il proprio tenantId;
  • sui flussi SSE e WebSocket l'azienda si può indicare anche con ?tenantId=.

Per le chiavi aziendali l'header è ignorato; un valore diverso dalla propria azienda restituisce 403.

# Chiave globale (piattaforma): azienda indicata con X-Tenant-Id
curl -s https://centralino.exovoip.it/api/v1/extensions \
  -H "X-API-Key: $EXOPBX_API_KEY" \
  -H "X-Tenant-Id: 3"

Aziende sospese

Con l'azienda sospesa le chiavi aziendali funzionano in sola lettura: le scritture restituiscono 403 TENANT_SUSPENDED. Con l'azienda disattivata l'accesso è negato.

Buone pratiche

  • Una chiave per integrazione, con i soli scope necessari.
  • Limita gli IP quando l'integrazione gira su server con indirizzo fisso.
  • Ruota le chiavi periodicamente e revoca subito quelle non più usate.
  • Non inserire chiavi in pagine web pubbliche o app distribuite: usale solo lato server.
  • Controlla l'utilizzo di ogni chiave dal pannello (richieste, errori, ultimi accessi).