Accesso API
VoiceBooker offre accesso programmatico all’API per integrare altre applicazioni e automatizzare i flussi, ad esempio il recupero dell’utilizzo, il deployment dei bot e l’integrazione di pipeline CI/CD.
URL di base
https://voicebooker.de/app/api/v1Autenticazione
Inviare un token API in ogni richiesta usando questo header:
X-API-TOKEN: <il-tuo-token-api>Il token determina l’azienda associata alla richiesta. Conservarlo in modo sicuro.
Esportare un bot
GET /exportBots/{botId} esporta un bot dell’azienda associata al token API. Usare pretty=true per ottenere HJSON leggibile.
curl --get 'https://voicebooker.de/app/api/v1/exportBots/<bot-id>' \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--data-urlencode 'pretty=true'Esempio di risposta:
{
"name": "Assistente reception",
"id": "kqrmxaveli",
"stages": [
{
"name": "Welcome",
"id": "mavotirenu",
"linkId": "qeluzanopi",
"template": false,
"prompt": "Saluta il chiamante.",
"tools": [],
"functions": [],
"settings": {},
"stageConfig": [],
"x": 0,
"y": 0,
"order": 0,
"instanceSettings": {}
}
],
"settings": {},
"wizard": {}
}Importare un bot
POST /importBots importa una definizione di bot nell’azienda associata al token. Inviare la definizione in contents. Per HJSON, filename deve terminare con .hjson. overwriteBotStages, overwriteTemplates e replaceBotStages sono parametri booleani opzionali.
curl --request POST \
--url https://voicebooker.de/app/api/v1/importBots \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--header 'Content-Type: application/json' \
--data '{"filename":"bot.json","contents":{"name":"Assistente reception","settings":{},"stages":[]},"overwriteBotStages":false,"overwriteTemplates":false,"replaceBotStages":false}'Esempio di risposta:
{
"id": "vexorimaku",
"name": "Assistente reception",
"settings": {},
"invisible": false
}Effettuare chiamate in uscita
Per effettuare una chiamata in uscita, inviare una richiesta POST a:
https://voicebooker.de/app/api/v1/makeCallContent-Type: application/json
X-API-TOKEN: <il-tuo-token-api>Esempio di richiesta:
{
"dest": "+49-351-123456789",
"botId": "kqrmxaveli",
"sipAccountId": "lupenakori",
"ringTimeout": 25,
"startTimeout": 10,
"state": {
"customerId": "zpjwletodo"
}
}| Parametro | Descrizione |
|---|---|
dest | Numero da chiamare in formato E.164. |
botId | Bot usato per la chiamata. |
sipAccountId | Account SIP usato; il suo numero viene mostrato al destinatario. |
ringTimeout | Secondi di squillo prima dell’annullamento senza risposta. Predefinito: 30 secondi. |
startTimeout | Secondi di attesa prima che il bot inizi a parlare. |
state | Dati utilizzabili da webhook o chiamate API durante la chiamata, ad esempio un ID cliente. |
L’API restituisce un callId:
{
"callId": "xavurimeto"
}Gestire i test dei bot
I test dei bot confrontano un bot sorgente/chiamante con un bot di destinazione/rispondente. Le richieste con chiave API sono limitate all’azienda associata al token; entrambi i bot devono appartenere a quell’azienda.
| Metodo | Endpoint | Funzione |
|---|---|---|
GET | /bot_test_setups | Elenca i test dei bot. |
POST | /bot_test_setups | Crea un test. |
PUT | /bot_test_setups/{id} | Aggiorna un test. |
DELETE | /bot_test_setups/{id} | Elimina un test. |
La risposta pubblica contiene solo id, name, settings, srcBotId e destBotId. settings può includere
convInitBot, maxConvTurns, asCall, startTimeout e stateUpdate. Durante l’aggiornamento, i campi omessi vengono mantenuti.
Recuperare una registrazione della chiamata
GET /getRecording/{id} restituisce la registrazione MP3 di una sessione di chiamata. Usare come id l’ID della sessione restituito da /usage. La registrazione deve essere stata abilitata per la chiamata.
La risposta viene trasmessa come audio/mpeg e può essere salvata direttamente in un file .mp3:
curl --request GET \
--url https://voicebooker.de/app/api/v1/getRecording/<id-sessione> \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--output registrazione.mp3L’endpoint restituisce 404 Not Found quando la sessione o la relativa registrazione non sono disponibili per il token API. Restituisce 401 Unauthorized se il token API manca o non è valido.
Recuperare l’utilizzo
GET /usage restituisce le sessioni telefoniche e chat dell’azienda autenticata e delle aziende partner disponibili.
Senza businessId vengono incluse tutte le aziende disponibili. Usare businessId per selezionare un’azienda e start e end per filtrare in base alla creazione della sessione.
curl --get https://voicebooker.de/app/api/v1/usage \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--data-urlencode 'businessId=zpjwletodo' \
--data-urlencode 'start=2026-01-01T00:00:00Z' \
--data-urlencode 'end=2026-02-01T00:00:00Z'start e end sono inclusivi. Usare date ISO 8601 valide. Un’azienda fuori dall’ambito del token restituisce 403 Forbidden.
Esempio di risposta:
[
{
"id": "xavurimeto", "businessId": "zpjwletodo", "botId": "kqrmxaveli",
"isCall": true, "direction": "inbound", "phoneNumberCaller": "+391701234567",
"phoneNumberCallee": "+39061234567", "duration": 184, "costs": 0.46,
"start": "2026-01-15T10:30:00.000Z"
}
]Elencare le aziende partner
Per le integrazioni di partner e rivenditori, GET /partnerClients restituisce le aziende visibili collegate all’azienda autenticata. I relativi ID possono essere usati con il filtro businessId dell’endpoint di utilizzo.
curl --request GET \
--url https://voicebooker.de/app/api/v1/partnerClients \
--header 'X-API-TOKEN: <il-tuo-token-api>'Esempio di risposta:
[
{
"id": "zpjwletodo",
"name": "Azienda partner di esempio",
"city": "Roma",
"country": "IT"
}
]Gestire i file della base di conoscenza e i file multimediali
Le chiavi API possono elencare, caricare ed eliminare i file dell’azienda associata al token. Gli ID dei file sono offuscati, mentre i nomi degli attributi della risposta non lo sono.
Elencare i file della base di conoscenza
GET /knowledgeBase restituisce id, name, fileSize e tokens.
curl --request GET \
--url https://voicebooker.de/app/api/v1/knowledgeBase \
--header 'X-API-TOKEN: <il-tuo-token-api>'Caricare un file della base di conoscenza
POST /knowledgeBase accetta un upload multipart con i campi file e name.
curl --request POST \
--url https://voicebooker.de/app/api/v1/knowledgeBase \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--form 'name=manuale.pdf' \
--form 'file=@manuale.pdf'Eliminare un file della base di conoscenza
curl --request DELETE \
--url https://voicebooker.de/app/api/v1/knowledgeBase/<id-file> \
--header 'X-API-TOKEN: <il-tuo-token-api>'Elencare e caricare file multimediali
GET /mediaFiles restituisce id, name e fileSize. POST /mediaFiles usa gli stessi campi multipart.
curl --request GET \
--url https://voicebooker.de/app/api/v1/mediaFiles \
--header 'X-API-TOKEN: <il-tuo-token-api>'
curl --request POST \
--url https://voicebooker.de/app/api/v1/mediaFiles \
--header 'X-API-TOKEN: <il-tuo-token-api>' \
--form 'name=musica.mp3' \
--form 'file=@musica.mp3'Eliminare un file multimediale
curl --request DELETE \
--url https://voicebooker.de/app/api/v1/mediaFiles/<id-file> \
--header 'X-API-TOKEN: <il-tuo-token-api>'Specifica OpenAPI
openapi: 3.1.0
info:
title: VoiceBooker Partner API
version: 1.0.0
description: API per consultare aziende partner e dati di utilizzo.
servers: [{url: https://voicebooker.de/app/api/v1}]
paths:
/exportBots/{botId}:
get:
summary: Esportare un bot
operationId: exportBot
security: [{apiToken: []}]
parameters:
- {name: botId, in: path, required: true, schema: {type: string}}
- {name: pretty, in: query, schema: {type: boolean, default: false}}
responses:
'200': {description: Definizione del bot esportato., content: {application/json: {schema: {type: object, properties: {id: {type: string}, name: {type: string}, stages: {type: array, items: {type: object}}, settings: {type: object}, wizard: {type: object}}}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {description: Il bot non appartiene all’azienda del token.}
/importBots:
post:
summary: Importare un bot
operationId: importBot
security: [{apiToken: []}]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [contents]
properties:
filename: {type: string}
contents: {oneOf: [{type: object}, {type: string}]}
overwriteBotStages: {type: boolean, default: false}
overwriteTemplates: {type: boolean, default: false}
replaceBotStages: {type: boolean, default: false}
responses:
'200': {description: Bot importato., content: {application/json: {schema: {type: object, properties: {id: {type: string}, name: {type: string}}}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/makeCall:
post:
summary: Effettuare una chiamata in uscita
operationId: makeOutboundCall
security: [{apiToken: []}]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [dest, botId, sipAccountId]
properties:
dest: {type: string}
botId: {type: string}
sipAccountId: {type: string}
ringTimeout: {type: integer, default: 30}
startTimeout: {type: integer, default: 0}
state: {type: object, additionalProperties: true}
responses:
'200': {description: Chiamata in uscita avviata., content: {application/json: {schema: {type: object, properties: {callId: {type: string}}}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/getRecording/{id}:
get:
summary: Recuperare una registrazione della chiamata
operationId: getCallRecording
security: [{apiToken: []}]
parameters:
- {name: id, in: path, required: true, schema: {type: string}, description: ID della sessione di chiamata.}
responses:
'200': {description: Registrazione della chiamata., content: {audio/mpeg: {schema: {type: string, format: binary}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
'404': {description: La sessione o la registrazione non è disponibile per questo token API.}
/usage:
get:
summary: Recuperare l’utilizzo
operationId: listUsage
security: [{apiToken: []}]
parameters:
- {name: businessId, in: query, schema: {type: string}, description: Azienda da consultare.}
- {name: start, in: query, schema: {type: string, format: date-time}, description: Inizio incluso.}
- {name: end, in: query, schema: {type: string, format: date-time}, description: Fine inclusiva.}
responses:
'200': {description: Dati di utilizzo., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/UsageRecord'}}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {description: L’azienda non è disponibile per questo token.}
/partnerClients:
get:
summary: Elencare le aziende partner
operationId: listPartnerClients
security: [{apiToken: []}]
responses:
'200': {description: Elenco delle aziende., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/PartnerBusiness'}}}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/knowledgeBase:
get:
operationId: listKnowledgeBaseFiles
security: [{apiToken: []}]
responses: {'200': {description: File della base di conoscenza., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/KnowledgeBaseFile'}}}}}, '401': {$ref: '#/components/responses/Unauthorized'}}
post:
operationId: uploadKnowledgeBaseFile
security: [{apiToken: []}]
requestBody: {required: true, content: {multipart/form-data: {schema: {type: object, required: [file, name], properties: {file: {type: string, format: binary}, name: {type: string}}}}}}
responses: {'200': {description: ID del file caricato., content: {application/json: {schema: {type: object, properties: {id: {type: string}}}}}}, '401': {$ref: '#/components/responses/Unauthorized'}}
/knowledgeBase/{fileId}:
delete:
operationId: deleteKnowledgeBaseFile
security: [{apiToken: []}]
parameters: [{name: fileId, in: path, required: true, schema: {type: string}}]
responses: {'200': {description: File eliminato.}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: File fuori dall’ambito del token.}}
/mediaFiles:
get:
operationId: listMediaFiles
security: [{apiToken: []}]
responses: {'200': {description: File multimediali., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/MediaFile'}}}}}, '401': {$ref: '#/components/responses/Unauthorized'}}
post:
operationId: uploadMediaFile
security: [{apiToken: []}]
requestBody: {required: true, content: {multipart/form-data: {schema: {type: object, required: [file, name], properties: {file: {type: string, format: binary}, name: {type: string}}}}}}
responses: {'200': {description: ID del file caricato., content: {application/json: {schema: {type: object, properties: {id: {type: string}}}}}}, '401': {$ref: '#/components/responses/Unauthorized'}}
/mediaFiles/{fileId}:
delete:
operationId: deleteMediaFile
security: [{apiToken: []}]
parameters: [{name: fileId, in: path, required: true, schema: {type: string}}]
responses: {'200': {description: File eliminato.}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: File fuori dall’ambito del token.}}
/bot_test_setups:
get:
operationId: listBotTests
security: [{apiToken: []}]
responses: {'200': {description: Test dei bot., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/BotTestSetup'}}}}}, '401': {$ref: '#/components/responses/Unauthorized'}}
post:
operationId: createBotTest
security: [{apiToken: []}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetupInput'}}}}
responses: {'200': {description: Test creato., content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetup'}}}}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Bot fuori ambito o bot identici.}}
/bot_test_setups/{id}:
put:
operationId: updateBotTest
security: [{apiToken: []}]
parameters: [{name: id, in: path, required: true, schema: {type: string}}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetupUpdate'}}}}
responses: {'200': {description: Test aggiornato., content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetup'}}}}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Bot fuori ambito o bot identici.}, '404': {description: Test non trovato.}}
delete:
operationId: deleteBotTest
security: [{apiToken: []}]
parameters: [{name: id, in: path, required: true, schema: {type: string}}]
responses: {'200': {description: Test eliminato.}, '401': {$ref: '#/components/responses/Unauthorized'}, '404': {description: Test non trovato.}}
components:
securitySchemes:
apiToken: {type: apiKey, in: header, name: X-API-TOKEN}
schemas:
PartnerBusiness: {type: object, properties: {id: {type: string}, name: {type: string}}}
UsageRecord:
type: object
properties:
id: {type: string}
businessId: {type: string}
botId: {type: string, nullable: true}
isCall: {type: boolean}
direction: {type: string, enum: [inbound, outbound]}
phoneNumberCaller: {type: string, nullable: true}
phoneNumberCallee: {type: string, nullable: true}
duration: {type: integer}
costs: {type: number}
start: {type: string, format: date-time}
KnowledgeBaseFile:
type: object
properties: {id: {type: string}, name: {type: string}, fileSize: {type: integer}, tokens: {type: integer}}
MediaFile:
type: object
properties: {id: {type: string}, name: {type: string}, fileSize: {type: integer}}
BotTestSetup:
type: object
properties: {id: {type: string}, name: {type: string}, settings: {type: object, additionalProperties: true}, srcBotId: {type: string}, destBotId: {type: string}}
BotTestSetupInput:
type: object
required: [name, srcBotId, destBotId]
properties: {name: {type: string}, settings: {type: object, additionalProperties: true}, srcBotId: {type: string}, destBotId: {type: string}}
BotTestSetupUpdate:
type: object
properties: {name: {type: string}, settings: {type: object, additionalProperties: true}, srcBotId: {type: string}, destBotId: {type: string}}
responses:
Unauthorized: {description: Il token manca o non è valido.}Errori HTTP
401 Unauthorized: il token API manca o non è valido.403 Forbidden: l’azienda richiesta non è disponibile per questo token.