Passa al contenuto principale

Endpoint: Knowledge Base

Riferimento degli endpoint per la gestione delle basi di conoscenza, dei documenti, delle FAQ, delle sorgenti web e database, della ricerca e dei webhook di notifica.

Tutte le richieste usano l'URL base https://ai.askme.it/api/v2 e le intestazioni descritte in Autenticazione. Gli elenchi seguono la paginazione offset/limit descritta nella Panoramica. Gli endpoint delle basi di conoscenza richiedono che la funzionalità knowledge_bases sia attiva per l'organizzazione; accanto a ogni endpoint è indicato, dove rilevante, il permesso che gli scope della chiave devono coprire.

1. Basi di conoscenza​

POST /knowledge-bases​

Crea una base di conoscenza. Permesso: knowledge_bases.create.

Attributi della richiesta

CampoInTipoObbligatorioPredefinitoDescrizione
namebodystring (1–255)Sì—Nome della base di conoscenza.
descriptionbodystringNo—Descrizione libera.
typebodystringNomanualOrigine prevalente dei contenuti: manual (documenti e FAQ caricati), web (pagine di siti web), database (sorgente database), api (contenuti inviati da un'integrazione).
embedding_modelbodystringNotext-embedding-3-smallModello usato per indicizzare e cercare i contenuti. Non si può cambiare dopo la creazione.
chunk_strategybodystringNorecursiveStrategia di suddivisione dei documenti in frammenti.
chunk_sizebodyint (100–4000)No512Dimensione dei frammenti.
chunk_overlapbodyint (0–1000)No50Sovrapposizione tra frammenti consecutivi; deve essere minore di chunk_size.
languagesbodystring[]No["it"]Lingue dei contenuti (codici ISO 639-1). Le domande in lingue diverse vengono tradotte nella prima lingua dell'elenco prima della ricerca.
parent_idbodyintNo—Base di conoscenza genitore.
is_temporarybodyboolNofalseSe true, la base non compare negli elenchi standard.
configbodyobjectNo—Impostazioni di lettura dei documenti. Si consiglia di lasciarlo vuoto: il recupero delle informazioni è regolato dalla piattaforma e non legge questo campo.

Esempio di richiesta

curl -X POST "https://ai.askme.it/api/v2/knowledge-bases" \
-H "X-Api-Key: amai_xxxxxxxxxxxxxxxx" \
-H "X-Source-App: api_direct" \
-H "Content-Type: application/json" \
-d '{
"name": "Documentazione interna",
"description": "Listino, onboarding e procedure interne",
"type": "manual",
"languages": ["it"]
}'

Esempio di risposta (201 Created)

{
"id": 12,
"tenant_id": "5b0e2f7a-2c41-4d0e-9a6b-1c9e8f3d4a21",
"name": "Documentazione interna",
"description": "Listino, onboarding e procedure interne",
"type": "manual",
"embedding_model": "text-embedding-3-small",
"chunk_strategy": "recursive",
"chunk_size": 512,
"chunk_overlap": 50,
"config": {},
"vector_store_config": null,
"status": "active",
"document_count": 0,
"total_chunks": 0,
"website_count": 0,
"faq_count": 0,
"pending_documents": 0,
"error_documents": 0,
"storage_bytes": 0,
"created_by": "apikey:28",
"created_at": "2026-09-24T16:39:00.667513Z",
"updated_at": "2026-09-24T16:39:00.667513Z",
"parent_id": null,
"languages": ["it"],
"is_temporary": false,
"tenant_wide_editable": true
}

Errori specifici

CodiceSignificato
422Validazione non superata, per esempio chunk_overlap non minore di chunk_size o type fuori elenco.
429Quota knowledge_bases del piano esaurita.

GET /knowledge-bases​

Elenca le basi di conoscenza dell'organizzazione. Permesso: knowledge_bases.read.

CampoInTipoPredefinitoDescrizione
offsetqueryint0Paginazione.
limitqueryint (1–100)50Dimensione della pagina.
searchquerystring—Ricerca su nome e descrizione.
statusquerystring—active, inactive, building, error.
sort_by, orderquerystring—Ordinamento; order vale asc o desc.
include_temporaryqueryboolfalseInclude le basi temporanee (per esempio quelle create dall'analisi PDF per conversare con un documento).

GET /knowledge-bases/{kb_id}​

Dettaglio della base di conoscenza, nello stesso formato di POST /knowledge-bases.

PATCH /knowledge-bases/{kb_id}​

Aggiorna la base di conoscenza. Permesso: knowledge_bases.update. Campi facoltativi: name, description, status, chunk_strategy, chunk_size, chunk_overlap, config, parent_id, languages. vector_store_config ed embedding_model non sono modificabili dopo la creazione: una richiesta di cambio del modello viene rifiutata. Le nuove impostazioni di suddivisione valgono per i documenti elaborati dopo la modifica.

DELETE /knowledge-bases/{kb_id}​

Elimina la base di conoscenza con i suoi documenti e libera la quota knowledge_bases. Permesso: knowledge_bases.delete. Risposta 204 No Content.

Se uno o più agenti usano la base, la richiesta viene rifiutata con 409 e il corpo elenca gli agenti coinvolti:

{
"detail": {
"code": "KB_HAS_LINKED_AGENTS",
"agents": [
{ "id": 54, "name": "Assistente sito", "status": "active" }
]
}
}

Per procedere si ripete la richiesta con il parametro agents:

ValoreEffetto
?agents=detachToglie la base di conoscenza dalla configurazione degli agenti, che restano attivi.
?agents=pausePorta in stato paused gli agenti attivi che la usano, senza modificarne la configurazione.
curl -X DELETE "https://ai.askme.it/api/v2/knowledge-bases/12?agents=detach" \
-H "X-Api-Key: amai_xxxxxxxxxxxxxxxx"

Se non tutti gli agenti possono essere aggiornati, la base non viene eliminata e la risposta 502 (code: AGENT_RELEASE_PARTIAL_FAILURE) riporta in released_agent_ids e failed_agent_ids gli agenti aggiornati e quelli non aggiornati. La richiesta può essere ripetuta senza effetti sugli agenti già aggiornati.


GET /knowledge-bases/{kb_id}/agents​

Agenti che consultano la base di conoscenza. Permesso: knowledge_bases.read. Risposta { "items": [...], "total": n }.

POST /knowledge-bases/{kb_id}/reindex​

Ricalcola in background i contatori della base di conoscenza a partire dai documenti presenti. Permesso: knowledge_bases.reindex. Risponde 202 con { "id": 12, "status": "building" }; al termine lo stato torna active (oppure error). Se una reindicizzazione è già in corso la risposta è 409. L'operazione non rielabora i contenuti: per rigenerare i frammenti di un documento si usa POST .../documents/{document_id}/process, per una sorgente web si rilancia il job di scraping.

GET /knowledge-bases/{kb_id}/quality-metrics​

Metriche strutturali della base di conoscenza, calcolate senza chiamate ai modelli.

{
"total_documents": 6,
"indexed_documents": 5,
"pending_documents": 0,
"error_documents": 1,
"doc_status_breakdown": { "error": 1, "indexed": 5 },
"source_type_breakdown": { "file": 6 },
"total_chunks": 5,
"avg_chunk_tokens": 157.4,
"min_chunk_tokens": 90,
"max_chunk_tokens": 236,
"docs_with_empty_chunks": 0,
"total_scraped_pages": 0,
"scraped_pages_done": 0,
"scraped_pages_pending": 0,
"scraped_pages_excluded": 0,
"avg_unique_content_ratio": 0.0,
"scraping_jobs_count": 0
}

GET /knowledge-bases/{kb_id}/export​

Esporta la base di conoscenza come archivio ZIP (application/zip).

GET /knowledge-bases/{kb_id}/change-log​

Cronologia delle modifiche della base di conoscenza (documenti aggiunti, sostituiti, eliminati): action, actor_id, actor_type, details, created_at. Paginazione offset/limit (predefinito 20, massimo 100).


2. Documenti​

Endpoint sotto /knowledge-bases/{kb_id}/documents.

Un documento caricato o creato da testo è in stato pending finché non viene elaborato, cioè suddiviso in frammenti e indicizzato con POST .../documents/{document_id}/process. Solo i documenti in stato indexed vengono consultati dagli agenti. Gli stati possibili sono pending, processing, processed, indexed ed error.

POST /knowledge-bases/{kb_id}/documents/upload​

Carica un file (multipart). Permesso: knowledge_bases.upload. Formati gestiti: PDF, DOCX, TXT, MD, HTML, CSV, XLSX, JSON.

CampoInTipoObbligatorioPredefinitoDescrizione
fileform-datafileSì—File da caricare.
priorityform-dataintNo2Priorità della fonte (1 = più alta).
categoryform-datastringNo—Categoria libera, salvata nei metadati.
languageform-datastringNo—Lingua del documento.

Esempio di richiesta (cURL)

curl -X POST "https://ai.askme.it/api/v2/knowledge-bases/12/documents/upload" \
-H "X-Api-Key: amai_xxxxxxxxxxxxxxxx" \
-H "X-Source-App: api_direct" \
-F "[email protected]" \
-F "category=Listino" \
-F "language=it"

Esempio di richiesta (Python, httpx), con elaborazione

import os

import httpx

client = httpx.Client(
base_url=os.environ["ASKMEAI_HOST"] + "/api/v2",
headers={"X-Api-Key": os.environ["ASKMEAI_API_KEY"], "X-Source-App": "api_direct"},
timeout=120.0,
)

with open("listino-servizi.pdf", "rb") as fh:
resp = client.post(
"/knowledge-bases/12/documents/upload",
files={"file": ("listino-servizi.pdf", fh, "application/pdf")},
data={"category": "Listino", "language": "it"},
)
resp.raise_for_status()
document = resp.json()

resp = client.post(f"/knowledge-bases/12/documents/{document['id']}/process")
resp.raise_for_status()
print(resp.json()["status"], resp.json()["chunk_count"])

Esempio di risposta (201 Created)

{
"id": 137,
"knowledge_base_id": 12,
"title": "listino-servizi.pdf",
"source_type": "file",
"source_url": null,
"file_path": "5b0e2f7a-2c41-4d0e-9a6b-1c9e8f3d4a21/12/listino-servizi.pdf",
"mime_type": "application/pdf",
"status": "pending",
"file_size": 18342,
"chunk_count": 0,
"metadata": { "category": "Listino", "language": "it" },
"error_message": null,
"created_at": "2026-09-24T16:41:12.114807Z",
"updated_at": "2026-09-24T16:41:12.114807Z",
"priority": 2,
"is_visible": true
}

Errori specifici

CodiceSignificato
413File oltre il limite di dimensione del piano.
429Quota dei documenti o dello spazio di archiviazione esaurita.

POST /knowledge-bases/{kb_id}/documents/text​

Crea un documento da testo. Permesso: knowledge_bases.upload. Come per i file, il documento va poi elaborato.

CampoInTipoObbligatorioDescrizione
titlebodystring (1–500)SìTitolo del documento.
contentbodystringSìTesto del documento.
metadatabodyobjectNoMetadati liberi.

POST /knowledge-bases/{kb_id}/documents/{document_id}/process​

Elabora il documento: estrae il testo, lo suddivide in frammenti e lo indicizza. Permesso: knowledge_bases.update. Per impostazione predefinita l'elaborazione è sincrona e la risposta (200) riporta il documento con lo stato finale (indexed, oppure error con error_message). Con ?background=true la risposta è immediata (202, stato processing) e l'esito si legge con GET .../documents/{document_id}. La stessa chiamata rielabora un documento già indicizzato.

POST /knowledge-bases/{kb_id}/documents/{document_id}/replace​

Sostituisce il file di un documento mantenendone l'identificativo, così che le citazioni e i collegamenti esistenti restino validi. Permesso: knowledge_bases.upload.

CampoInTipoObbligatorioDescrizione
fileform-datafileSìNuovo file.
titleform-datastringNoNuovo titolo.
backgroundqueryboolNoSe true, la rielaborazione avviene in background (202).

Il nuovo contenuto viene elaborato subito: la risposta riporta il documento aggiornato.

Altri endpoint dei documenti​

EndpointMetodoDescrizione
/knowledge-bases/{kb_id}/documentsGETElenco dei documenti, con paginazione.
/knowledge-bases/{kb_id}/documents/{document_id}GETDettaglio del documento, con stato ed eventuale error_message.
/knowledge-bases/{kb_id}/documents/{document_id}/previewGETAnteprima del testo estratto.
/knowledge-bases/{kb_id}/documents/{document_id}/downloadGETScarica il file originale.
/knowledge-bases/{kb_id}/documents/{document_id}DELETEElimina il documento e i suoi frammenti (204).
/knowledge-bases/{kb_id}/documents/bulkDELETEEliminazione multipla, corpo { "document_ids": [137, 138] }.
/knowledge-bases/{kb_id}/documents/{document_id}/visibilityPATCHCorpo { "is_visible": false }: il documento resta usato per costruire le risposte, ma non compare tra le fonti mostrate agli utenti finali (fonte nascosta).

3. FAQ​

Endpoint sotto /knowledge-bases/{kb_id}/faqs. Solo le FAQ in stato editoriale verified vengono usate dagli agenti.

POST /knowledge-bases/{kb_id}/faqs​

CampoInTipoObbligatorioPredefinitoDescrizione
questionbodystring (max 500)Sì—Domanda.
answerbodystring (max 5000)Sì—Risposta.
categorybodystring (max 255)No—Categoria.
prioritybodyintNo2Priorità della FAQ come fonte.
variantsbodystring[]No[]Formulazioni alternative della domanda.
editorial_statusbodystringNodraftdraft, verified, obsolete.

Esempio di risposta (201 Created)

{
"id": 401,
"knowledge_base_id": 11,
"question": "Che cos'è Askme AI?",
"answer": "Askme AI è la piattaforma per creare agenti conversazionali che rispondono usando le basi di conoscenza dell'organizzazione.",
"category": "Prodotto",
"created_at": "2026-09-24T17:12:04.215771Z",
"updated_at": "2026-09-24T17:12:04.215771Z",
"priority": 2,
"variants": ["A cosa serve Askme AI?"],
"editorial_status": "verified",
"is_visible": true
}

Altri endpoint delle FAQ​

EndpointMetodoDescrizione
/knowledge-bases/{kb_id}/faqsGETElenco paginato.
/knowledge-bases/{kb_id}/faqs/{faq_id}PUTAggiornamento: question e answer obbligatori, gli altri campi (compreso is_visible) facoltativi.
/knowledge-bases/{kb_id}/faqs/{faq_id}DELETEEliminazione (204).
/knowledge-bases/{kb_id}/faqsDELETEElimina tutte le FAQ della base di conoscenza.
/knowledge-bases/{kb_id}/faqs/{faq_id}/visibilityPATCHCorpo { "is_visible": false }, con lo stesso significato della visibilità dei documenti.
/knowledge-bases/{kb_id}/faqs/visibilityPATCHStessa operazione su tutte le FAQ della base di conoscenza.
/knowledge-bases/{kb_id}/faqs/importPOSTImportazione da file CSV o JSON (multipart [email protected]). Risposta { "imported": 12 }.
/knowledge-bases/{kb_id}/faqs/template/{formato}GETFile modello per l'importazione, in formato csv o json.

4. Scraping web​

Endpoint sotto /knowledge-bases/{kb_id}/scraping-jobs. Il servizio riconosce automaticamente sitemap XML e feed RSS/Atom.

POST /knowledge-bases/{kb_id}/scraping-jobs​

Crea un job di scraping.

CampoInTipoObbligatorioPredefinitoDescrizione
urlbodystringSì—Indirizzo di partenza: una pagina, una sitemap o un feed.
depthbodyint (1–5)No1Profondità di esplorazione dei collegamenti.
schedule_cronbodystringNo—Espressione cron per l'esecuzione periodica.
exclude_urlsbodystring[]No—Indirizzi da escludere, confrontati come prefisso di host e percorso (per esempio www.esempio.it/area-riservata).
exclude_pathsbodystring[]No—Percorsi da escludere su qualunque host (per esempio /team/, /privacy-policy).
exclude_patternsbodystring[]No—Espressioni regolari confrontate con l'indirizzo completo.
configbodyobjectNo—Opzioni avanzate.

Esempio di risposta (201 Created)

{
"id": 6,
"knowledge_base_id": 10,
"url": "https://www.lascaux.it",
"status": "pending",
"depth": 3,
"pages_scraped": 0,
"pages_discovered": 0,
"pages_failed": 0,
"last_run_at": null,
"schedule_cron": null,
"trigger": "manual",
"config": { "exclude_paths": ["/team", "/privacy-policy"] },
"error_message": null,
"created_at": "2026-09-24T14:44:50.289701Z",
"updated_at": "2026-09-24T14:44:50.289701Z"
}

Altri endpoint dello scraping​

EndpointMetodoDescrizione
/knowledge-bases/{kb_id}/scraping-jobsGETElenco dei job.
/knowledge-bases/{kb_id}/scraping-jobs/detect-sitemapPOSTCerca la sitemap di un sito: corpo { "url": "https://www.esempio.it" }, risposta { "sitemap_url", "pages" }.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}GET, PATCH, DELETEDettaglio, modifica (stessi campi della creazione, facoltativi), eliminazione (204).
/knowledge-bases/{kb_id}/scraping-jobs/bulkDELETEEliminazione multipla, corpo { "ids": [6, 7] }.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discoverPOSTIndividua le pagine (sitemap ed esplorazione dei collegamenti) senza scaricarle.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discovered-pagesGETPagine individuate, con selected e status (pending, scraped, skipped, error).
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discovered-pages/selectionPATCHSeleziona o deseleziona pagine: page_ids, selected, oppure select_all con il filtro facoltativo filter_source (sitemap o crawl).
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discovered-pages/{page_id}DELETERimuove una pagina individuata e il contenuto importato.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discovered-pages/{page_id}/visibilityPATCHNasconde o mostra la pagina come fonte, come per i documenti.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/discovered-pages/{page_id}/previewGETTesto importato per la pagina: document_id, title, url, preview_text, total_chars. Una pagina non ancora importata restituisce un'anteprima vuota.
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/triggerPOSTAvvia l'importazione delle pagine selezionate (202).
/knowledge-bases/{kb_id}/scraping-jobs/{job_id}/progressGETAvanzamento del job in tempo reale (stream SSE).

5. Sorgenti database​

Endpoint sotto /knowledge-bases/{kb_id}/db-source. Una sorgente database importa periodicamente righe di una tabella o di una query come documenti. Nella versione attuale è gestito il tipo di connessione postgresql.

PUT /knowledge-bases/{kb_id}/db-source​

Crea o aggiorna la sorgente database della base di conoscenza.

CampoInTipoObbligatorioDescrizione
connection_typebodystringSìpostgresql.
namebodystringNoNome della sorgente.
hostbodystringSìHost del database.
portbodyint (1–65535)SìPorta.
databasebodystringSìNome del database.
usernamebodystringSìUtente, preferibilmente con sola lettura.
passwordbodystringNoPassword, conservata cifrata.
schemabodystringNoSchema.
tablebodystringNoTabella da importare (in alternativa a query).
querybodystringNoQuery SQL di lettura (in alternativa a table).
sync_interval_minutesbodyint (≥1)NoIntervallo di sincronizzazione in minuti.

Altri endpoint delle sorgenti database​

EndpointMetodoDescrizione
/knowledge-bases/{kb_id}/db-sourceGETConfigurazione corrente (la password non viene restituita).
/knowledge-bases/{kb_id}/db-source/testPOSTVerifica la connessione senza salvarla (stessi campi di PUT): { "success": bool, "message": string }.
/knowledge-bases/{kb_id}/db-source/previewGETAnteprima di alcune righe: { "rows": [...], "columns": [...] }.
/knowledge-bases/{kb_id}/db-source/runPOSTAvvia un'importazione manuale: { "documents_created", "rows_processed", "message" }.
/knowledge-bases/{kb_id}/db-source/{connector_id}/runsGET, DELETEStorico delle esecuzioni (started_at, completed_at, rows_extracted, chunks_created, error_message) e sua cancellazione.
/knowledge-bases/{kb_id}/db-source/{connector_id}DELETEElimina la sorgente (204).

6. Ricerca​

Endpoint per interrogare direttamente le basi di conoscenza, senza passare da un agente.

POST /search​

Ricerca ibrida (vettoriale e testuale, con fusione dei risultati e FAQ) su una o più basi di conoscenza.

CampoInTipoObbligatorioPredefinitoDescrizione
querybodystring (1–2000)Sì—Testo da cercare.
knowledge_base_idsbodyint[]Sì—Almeno una base di conoscenza.
top_kbodyint (1–100)No10Numero di risultati.
min_scorebodyfloat (0.0–1.0)No0.0Punteggio minimo.
use_rerankingbodyboolNofalseRiordina i risultati con il modello di riordino, se disponibile nell'installazione.
enable_bm25bodyboolNotrueInclude la ricerca testuale nella fusione.

Esempio di richiesta

curl -X POST "https://ai.askme.it/api/v2/search" \
-H "X-Api-Key: amai_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"query": "orari del supporto tecnico",
"knowledge_base_ids": [11, 12],
"top_k": 5
}'

Esempio di risposta (200 OK)

{
"query": "orari del supporto tecnico",
"chunks": [
{
"id": "42",
"document_id": 139,
"knowledge_base_id": 12,
"content": "Il supporto tecnico risponde dal lunedì al venerdì, dalle 9 alle 18 [...]",
"score": 0.031,
"metadata": { "category": "Procedure", "language": "it" }
}
],
"faqs": [
{
"id": 401,
"knowledge_base_id": 11,
"question": "Quali sono gli orari del supporto?",
"answer": "Il supporto è attivo dal lunedì al venerdì, dalle 9 alle 18.",
"score": 0.92,
"is_visible": true
}
],
"total_results": 6,
"search_time_ms": 132.4
}

Varianti​

Le varianti accettano lo stesso corpo e restituiscono lo stesso formato:

  • POST /search/advanced: ricerca con filtri aggiuntivi; accetta ?document_ids=... per limitare i documenti;
  • POST /search/vector: solo ricerca vettoriale;
  • POST /search/fulltext: solo ricerca testuale;
  • POST /search/faq: solo FAQ; i risultati sono nel campo faqs e chunks è vuoto.

7. Webhook​

I webhook inviano una notifica HTTP POST a un indirizzo dell'integrazione quando si verificano eventi nell'organizzazione (documenti caricati o eliminati, scraping completati, agenti creati, analisi concluse, ...). Permessi: admin.integrations.read per la lettura, admin.integrations.manage per le modifiche.

POST /webhooks​

CampoInTipoObbligatorioPredefinitoDescrizione
namebodystringSì—Nome del webhook.
urlbodystringSì—Indirizzo che riceve le notifiche.
eventsbodystring[]No[]Tipi di evento notificati (elenco con GET /webhooks/event-types).
secretbodystringNo—Segreto per la firma delle notifiche. Se ne può generare uno con POST /webhooks/generate-secret.
activebodyboolNotrueWebhook attivo.

Esempio di risposta (201 Created)

{
"id": 3,
"tenant_id": "5b0e2f7a-2c41-4d0e-9a6b-1c9e8f3d4a21",
"name": "Notifiche documenti",
"url": "https://integrazione.example.com/askme/webhook",
"secret": "***",
"events": ["document.uploaded", "document.deleted"],
"active": true,
"created_at": "2026-09-24T15:02:11.402118+00:00",
"updated_at": "2026-09-24T15:02:11.402118+00:00",
"last_delivery_at": null,
"last_delivery_outcome": null
}

Il segreto non viene mai restituito: le letture riportano "***" quando un segreto è impostato. In un aggiornamento, inviando di nuovo "***" il segreto resta invariato; un valore diverso lo sostituisce.

Firma e formato delle notifiche​

Ogni notifica ha questo formato:

{
"event_id": "7f1c1f0e-5c1a-4f47-9d2b-2f5e1b0c9a44",
"event_type": "document.uploaded",
"tenant_id": "5b0e2f7a-2c41-4d0e-9a6b-1c9e8f3d4a21",
"timestamp": "2026-09-24T15:10:02.118Z",
"data": { "kb_id": 12, "document_id": 137, "title": "listino-servizi.pdf" }
}

event_id è univoco per ogni invio e consente di ignorare eventuali duplicati. Se il webhook ha un segreto, la notifica contiene l'intestazione X-Askme-Signature: sha256=<firma>, dove la firma è l'HMAC-SHA256 esadecimale del corpo della richiesta calcolato con il segreto. Esempio di verifica in Python:

import hashlib
import hmac


def signature_is_valid(body: bytes, header_value: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header_value or "")

Una notifica è considerata consegnata quando l'indirizzo risponde con un codice 2xx. In caso di errore 5xx o di mancata risposta l'invio viene ripetuto fino a tre tentativi; un errore 4xx non viene ripetuto.

Altri endpoint dei webhook​

EndpointMetodoDescrizione
/webhooksGETElenco dei webhook, con last_delivery_at e last_delivery_outcome.
/webhooks/{webhook_id}GET, PATCH, DELETEDettaglio, modifica (campi facoltativi), eliminazione (204).
/webhooks/event-typesGETTipi di evento notificabili, con categoria ed esempio di data.
/webhooks/{webhook_id}/deliveriesGETRegistro delle consegne: event_type, outcome (ok o failed), status_code, attempts, error_message, duration_ms, created_at. Filtro outcome, ordinamento sort_by (created_at, event_type, outcome, status_code, attempts, duration_ms) e sort_dir, paginazione.
/webhooks/{webhook_id}/testPOSTInvia una notifica di prova. Risponde 202 ({ "status": "queued" }): l'esito compare nel registro delle consegne.
/webhooks/generate-secretPOSTGenera un segreto casuale: { "secret": "..." }.

Esempio di elemento di GET /webhooks/event-types:

{
"type": "document.uploaded",
"category": "documents",
"i18n_key": "admin.webhooks.events.documentUploaded",
"example_payload": {
"kb_id": "550e8400-e29b-41d4-a716-446655440000",
"document_id": "660e8400-e29b-41d4-a716-446655440001",
"filename": "report.pdf",
"size_bytes": 102400
}
}

Pagine correlate​