Passa al contenuto principale

Autenticazione

Le integrazioni si autenticano presso le API di Askme AI con una chiave API. Ogni richiesta deve contenere una chiave valida nell'intestazione X-Api-Key; la chiave identifica l'organizzazione e stabilisce, tramite i suoi scope, quali operazioni sono consentite.

Generazione della chiave API​

Le chiavi si generano dalla console della propria organizzazione:

  1. Accedere alla console con un utente amministratore.
  2. Aprire Impostazioni › Chiavi API e selezionare Nuova chiave.
  3. Indicare un nome descrittivo (per esempio integrazione-crm-prod), l'applicazione di origine, le Funzioni della chiave (gli scope) ed eventualmente i limiti di frequenza e una scadenza.
  4. Selezionare Crea e copiare il valore mostrato nel dialog Chiave API generata: viene presentato una sola volta e, dopo la chiusura del dialog, non è più recuperabile.

La procedura completa, con le schermate, è descritta nel manuale.

Conservazione

Una chiave API dà accesso ai dati dell'organizzazione. Va conservata in un archivio di segreti (HashiCorp Vault, AWS Secrets Manager, variabili d'ambiente cifrate) e non deve essere inclusa nei repository di codice né nel codice eseguito dal browser.

Formato della chiave​

Tutte le chiavi hanno il prefisso amai_ seguito da una stringa opaca:

amai_3f9d8c1e0a4b2f7d6c5a8e9b3f1d2c4a8e9b3f1d2c4a8e9b

Nelle interfacce di gestione e nei log compare soltanto la parte iniziale della chiave (key_prefix), sufficiente a riconoscerla senza esporne il valore.

Intestazione di autenticazione​

Ogni richiesta alle API REST deve includere:

X-Api-Key: amai_<chiave>

Esempio cURL​

curl "https://ai.askme.it/api/v2/agents" \
-H "X-Api-Key: amai_3f9d8c1e0a4b2f7d6c5a8e9b3f1d2c4a8e9b3f1d2c4a8e9b"

Esempio Python (httpx)​

import os

import httpx

client = httpx.Client(
base_url="https://ai.askme.it/api/v2",
headers={"X-Api-Key": os.environ["ASKMEAI_API_KEY"]},
timeout=30.0,
)

resp = client.get("/agents")
resp.raise_for_status()
print(resp.json())

Esempio Node.js (fetch)​

const API_KEY = process.env.ASKMEAI_API_KEY;
const BASE = 'https://ai.askme.it/api/v2';

const resp = await fetch(`${BASE}/agents`, {
headers: { 'X-Api-Key': API_KEY },
});

if (!resp.ok) {
throw new Error(`API error ${resp.status}: ${await resp.text()}`);
}

const data = await resp.json();
console.log(data);

Intestazioni​

IntestazioneObbligatoriaDescrizione
X-Api-KeySìChiave nel formato amai_<chiave>
Content-TypeSui corpi JSONapplication/json sulle richieste POST, PUT e PATCH con corpo JSON
X-Source-AppNoApplicazione a cui attribuire consumi e conversazioni (vedere sotto)
X-External-IdNoIdentificativo opaco del sistema esterno (numero di ticket, di ordine, ...), riportato in ogni record di consumo prodotto dalla richiesta. Massimo 255 caratteri

Attribuzione con X-Source-App​

L'intestazione X-Source-App stabilisce a quale applicazione vengono attribuiti i consumi e le conversazioni generati dalla richiesta. È facoltativa: se manca, oppure se il valore non è tra quelli riconosciuti dalla piattaforma, la richiesta viene attribuita all'applicazione di origine impostata sulla chiave al momento della creazione. Un valore non riconosciuto non provoca un errore.

ValoreQuando usarlo
api_directIntegrazione del cliente che chiama direttamente le API REST (valore consigliato)
askmechatChiamate provenienti da Askme Chat
askmedeskChiamate provenienti da Askme Desk
askmesignChiamate provenienti da Askme Sign

La piattaforma riconosce anche altri valori riservati alle proprie applicazioni e ai servizi interni, che un'integrazione non deve usare. Si consiglia di mantenere lo stesso valore per tutta l'integrazione, così che i consumi siano leggibili in modo coerente nella console.

Esempio di richiesta completa​

curl -X POST "https://ai.askme.it/api/v2/chat" \
-H "X-Api-Key: amai_3f9d8c1e..." \
-H "Content-Type: application/json" \
-H "X-Source-App: api_direct" \
-H "X-External-Id: ticket-92831" \
-d '{
"agent_id": 12,
"message": "Come si effettua un reso?",
"stream": false
}'

Per ricevere la risposta in streaming (SSE) si imposta "stream": true nel corpo: l'endpoint resta POST /api/v2/chat e risponde con Content-Type: text/event-stream.

Permessi e scope​

Ogni chiave porta un elenco di scope, che stabilisce quali operazioni la chiave può eseguire. Nella console gli scope corrispondono alle Funzioni della chiave.

Il valore predefinito è *, che copre tutte le funzioni di prodotto dell'organizzazione: agenti, chat e conversazioni, basi di conoscenza, analisi, connettori e webhook, impostazioni dell'organizzazione e registro di audit. Restano escluse la gestione di utenti, ruoli e chiavi API, che richiede scope espliciti (per esempio admin.api_keys.create), e le funzioni riservate alla piattaforma, che nessuna chiave può ottenere.

Uno scope può indicare un permesso in tre modi:

FormaEsempioCopre
Codice completoknowledge_bases.readSolo quel permesso
Parte finale del codiceapi_keys.createadmin.api_keys.create
Prefisso seguito da .*agents.*Tutti i permessi che iniziano con agents.

Alla creazione e alla modifica di una chiave, uno scope che non corrisponde ad alcun permesso assegnabile viene rifiutato con 422; il corpo della risposta riporta gli scope non accettati:

{
"detail": {
"code": "API_KEY_SCOPES_REJECTED",
"message": "Scopes that cannot be assigned to an API key: agenti.leggi. A scope must name at least one existing permission code and no super_admin.* code.",
"rejected_scopes": ["agenti.leggi"]
}
}

L'elenco dei codici assegnabili, insieme ai prefissi che * non copre, è restituito da GET /api/v2/api-keys/scopes (si veda Endpoint: Utenti, Organizzazione e Quote).

Il ruolo che si può ancora associare a una chiave tramite API non concede permessi: una chiave può fare soltanto ciò che i suoi scope coprono, e una chiave senza scope non può eseguire operazioni protette. Per integrazioni con esigenze diverse si consiglia di creare chiavi separate, ciascuna con gli scope minimi necessari; per un'applicazione che si limita a conversare con un agente, per esempio, sono sufficienti gli scope di consultazione degli agenti e di avvio delle conversazioni.

Avviso per gli integratori

Fino alla versione 2.1 lo scope * copriva anche la gestione di utenti, ruoli e chiavi API. Dalla versione 2.2 non è più così: un'integrazione che crea utenti, assegna ruoli o gestisce chiavi con una chiave * riceve 403. Per ripristinare queste operazioni occorre aggiungere alla chiave gli scope espliciti corrispondenti (per esempio admin.users.create, admin.roles.update, admin.api_keys.read).

Una chiave API non riceve mai le fonti nascoste delle basi di conoscenza: le risposte della chat e i messaggi letti tramite API contengono soltanto le fonti visibili, indipendentemente dagli scope.

Organizzazione​

L'intestazione X-Tenant-ID non è richiesta: l'organizzazione è determinata dalla chiave, che le appartiene dal momento della generazione.

Errori di autenticazione e autorizzazione​

Codice HTTPCausa tipica
401 UnauthorizedIntestazione X-Api-Key assente, valore incompleto o senza prefisso amai_, chiave revocata o scaduta
403 Forbidden con code: PERMISSION_DENIEDGli scope della chiave non coprono il permesso indicato nel campo permission
403 Forbidden con code: FEATURE_FLAG_DISABLEDLa funzionalità indicata nel campo flag non è attiva per l'organizzazione
429 Too Many Requests con Retry-AfterLimite di frequenza della chiave superato
429 Too Many Requests senza Retry-AfterQuota del piano esaurita

Il testo del messaggio di un 401 può variare tra i servizi (per esempio Missing authentication token oppure Invalid API key): conviene basare la gestione degli errori sul codice HTTP. Esempio di 403:

{
"detail": {
"code": "PERMISSION_DENIED",
"permission": "knowledge_bases.delete"
}
}

Limiti di frequenza​

Ogni chiave può avere limiti dedicati:

  • rate_limit_rpm: richieste al minuto;
  • rate_limit_rpd: richieste al giorno.

Un limite non impostato non limita la chiave. I limiti valgono per la singola chiave in tutti i servizi che accettano chiavi API. Quando un limite è raggiunto il servizio risponde 429 con l'intestazione Retry-After, che indica i secondi da attendere prima di ripetere la richiesta.

Rotazione e revoca​

  • Rotazione: operazione atomica che revoca la chiave esistente e ne crea una sostitutiva con le stesse impostazioni (nome, scope, limiti; la scadenza, se presente, riparte dalla rotazione con la stessa durata). Il nuovo valore viene mostrato una sola volta. Una chiave revocata o scaduta non si può ruotare: la richiesta risponde 409.
  • Revoca: disattiva immediatamente la chiave. È un'operazione irreversibile.

Nome, scope, limiti di frequenza e scadenza di una chiave attiva si possono modificare senza rigenerarla.

Buone pratiche​

  • Usare una chiave distinta per ogni integrazione e per ogni ambiente.
  • Assegnare a ogni chiave i soli scope necessari, invece di *.
  • Impostare una scadenza realistica (per esempio 90 o 180 giorni) e pianificare la rotazione.
  • Inviare lo stesso X-Source-App per tutta l'integrazione, così che i consumi siano riconoscibili nella sezione Monitoraggio della console.
  • In caso di sospetta compromissione, revocare subito la chiave e verificare gli accessi nel Registro attività della console.