API access
VoiceBooker provides programmatic API access for integrating with other applications and automating workflows such as usage retrieval, bot deployment, and CI/CD pipeline integration.
Base URL
For the VoiceBooker production instance, use:
https://voicebooker.de/app/api/v1Authentication
Create an API token for the business in VoiceBooker and send it with every request using this header:
X-API-TOKEN: <your-api-token>Keep the token private. It determines the business context for the request; the endpoints do not accept an arbitrary business ID to establish access.
Export a bot
GET /exportBots/{botId} exports a bot that belongs to the business associated with the API token. The response contains the bot definition and its stages and can be used as input for /importBots.
Optional query parameters:
pretty=truereturns a human-readable HJSON document.
curl --get 'https://voicebooker.de/app/api/v1/exportBots/<bot-id>' \
--header 'X-API-TOKEN: <your-api-token>' \
--data-urlencode 'pretty=true'Example response:
{
"name": "Reception assistant",
"id": "kqrmxaveli",
"stages": [
{
"name": "Welcome",
"id": "mavotirenu",
"linkId": "qeluzanopi",
"template": false,
"prompt": "Welcome the caller.",
"tools": [],
"functions": [],
"settings": {},
"stageConfig": [],
"x": 0,
"y": 0,
"order": 0,
"instanceSettings": {}
}
],
"settings": {},
"wizard": {}
}Import a bot
POST /importBots imports a bot definition into the business associated with the API token. Send the exported object as the contents parameter. JSON objects can be sent directly; HJSON content can be sent by setting filename to a name ending in .hjson.
The optional flags are:
overwriteBotStages=truereplaces the existing bot with the same name.overwriteTemplates=trueimports template stages instead of reusing existing templates.replaceBotStages=trueupdates the bot identified by the exportedidrather than creating a new bot.
curl --request POST \
--url https://voicebooker.de/app/api/v1/importBots \
--header 'X-API-TOKEN: <your-api-token>' \
--header 'Content-Type: application/json' \
--data '{
"filename": "reception-assistant.json",
"contents": {"name": "Reception assistant", "settings": {}, "stages": []},
"overwriteBotStages": false,
"overwriteTemplates": false,
"replaceBotStages": false
}'Example response:
{
"id": "vexorimaku",
"name": "Reception assistant",
"settings": {},
"invisible": false
}Place outbound calls
You can place an outbound call by sending a POST request to:
https://voicebooker.de/app/api/v1/makeCallUse the following headers:
Content-Type: application/json
X-API-TOKEN: <your-api-token>Example request:
{
"dest": "+49-351-123456789",
"botId": "kqrmxaveli",
"sipAccountId": "lupenakori",
"ringTimeout": 25,
"startTimeout": 10,
"state": {
"customerId": "zpjwletodo"
}
}| Parameter | Description |
|---|---|
dest | Number to call in E.164 format. |
botId | Bot used for the call. |
sipAccountId | SIP account used to place the call. Its number is shown to the callee. |
ringTimeout | Seconds to ring before cancelling when nobody answers. Default: 30 seconds. |
startTimeout | Seconds to wait before the bot starts speaking, allowing the callee to speak first. |
state | Data that can be passed to webhooks or API calls during the call, such as a customer ID. |
The REST API returns a callId, which can be used with webhooks triggered when the call succeeds or fails:
{
"callId": "xavurimeto"
}Retrieve usage
GET /usage returns call and chat session usage for the authenticated business and its available partner businesses.
Without a businessId, the response contains usage for all businesses in that scope. Use businessId to retrieve usage for one business, and use start and end to filter by the session creation time.
curl --get https://voicebooker.de/app/api/v1/usage \
--header 'X-API-TOKEN: <your-api-token>' \
--data-urlencode 'businessId=zpjwletodo' \
--data-urlencode 'start=2026-01-01T00:00:00Z' \
--data-urlencode 'end=2026-02-01T00:00:00Z'start is inclusive and end is inclusive. Date-time values should be parseable ISO 8601 values. The businessId must be returned by /partnerClients or belong to the authenticated business; using a business outside the token's scope returns 403 Forbidden.
Each usage item contains:
| Field | Type | Description |
|---|---|---|
id | string | Call-session ID. |
businessId | string | Business ID. |
botId | string | Bot ID. |
isCall | boolean | true for a phone call, false for another session type. |
direction | string | inbound or outbound. |
phoneNumberCaller | string | Caller number, when available. |
phoneNumberCallee | string | Called number, when available. |
duration | integer | Session duration in seconds. Returns 0 when no call detail duration is available. |
costs | number | Recorded session cost. |
start | string | Session creation timestamp, returned as a JSON date-time value. |
Example response:
[
{
"id": "xavurimeto",
"businessId": "zpjwletodo",
"botId": "kqrmxaveli",
"isCall": true,
"direction": "inbound",
"phoneNumberCaller": "+491701234567",
"phoneNumberCallee": "+49301234567",
"duration": 184,
"costs": 0.46,
"start": "2026-01-15T10:30:00.000Z"
}
]List partner businesses
For reseller and partner integrations, GET /partnerClients returns the visible businesses connected to the authenticated partner business. The returned business IDs can be passed to the businessId filter on the usage endpoint.
curl --request GET \
--url https://voicebooker.de/app/api/v1/partnerClients \
--header 'X-API-TOKEN: <your-api-token>'The response is an array of business objects.
Example response:
[
{
"id": "zpjwletodo",
"name": "Example Partner Business",
"city": "Berlin",
"country": "DE"
}
]Manage knowledge-base and media files
API-key requests can list, upload, and delete files for the business associated with the token. File IDs in these responses are obfuscated IDs, while the response attribute names are not obfuscated.
List knowledge-base files
GET /knowledgeBase returns the knowledge-base files for the business. Each item contains only id, name, fileSize, and tokens.
curl --request GET \
--url https://voicebooker.de/app/api/v1/knowledgeBase \
--header 'X-API-TOKEN: <your-api-token>'Upload a knowledge-base file
POST /knowledgeBase accepts a multipart upload using the file and name fields.
curl --request POST \
--url https://voicebooker.de/app/api/v1/knowledgeBase \
--header 'X-API-TOKEN: <your-api-token>' \
--form 'name=handbook.pdf' \
--form 'file=@handbook.pdf'The response contains the obfuscated file ID:
{"id": "kqrmxaveli"}Delete a knowledge-base file
curl --request DELETE \
--url https://voicebooker.de/app/api/v1/knowledgeBase/<file-id> \
--header 'X-API-TOKEN: <your-api-token>'List media files
GET /mediaFiles returns media files with only id, name, and fileSize.
curl --request GET \
--url https://voicebooker.de/app/api/v1/mediaFiles \
--header 'X-API-TOKEN: <your-api-token>'Upload a media file
POST /mediaFiles accepts a multipart upload using the file and name fields.
curl --request POST \
--url https://voicebooker.de/app/api/v1/mediaFiles \
--header 'X-API-TOKEN: <your-api-token>' \
--form 'name=hold-music.mp3' \
--form 'file=@hold-music.mp3'Delete a media file
curl --request DELETE \
--url https://voicebooker.de/app/api/v1/mediaFiles/<file-id> \
--header 'X-API-TOKEN: <your-api-token>'OpenAPI specification
The following OpenAPI 3.1 document describes these APIs. All endpoints use the X-API-TOKEN header.
openapi: 3.1.0
info:
title: VoiceBooker Partner API
version: 1.0.0
description: Retrieve partner businesses and usage for the business associated with an API token.
servers:
- url: https://voicebooker.de/app/api/v1
description: VoiceBooker production API
tags:
- name: Partner access
description: APIs for partner and reseller integrations.
paths:
/exportBots/{botId}:
get:
tags: [Partner access]
operationId: exportBot
summary: Export a bot
description: Exports a bot belonging to the business associated with the API token.
security:
- apiToken: []
parameters:
- name: botId
in: path
required: true
description: Bot ID to export.
schema: {type: string}
- name: pretty
in: query
schema: {type: boolean, default: false}
responses:
'200':
description: Exported bot definition.
content:
application/json:
schema: {$ref: '#/components/schemas/BotExport'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {description: The bot does not belong to the business associated with the token.}
/importBots:
post:
tags: [Partner access]
operationId: importBot
summary: Import a bot
description: Imports a bot definition into the business associated with the API token.
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: Imported bot.
content:
application/json:
schema: {type: object, properties: {id: {type: string}, name: {type: string}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/makeCall:
post:
tags: [Partner access]
operationId: makeOutboundCall
summary: Place an outbound call
description: Starts an outbound call using the selected bot and SIP account.
security:
- apiToken: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [dest, botId, sipAccountId]
properties:
dest: {type: string, description: Destination number in E.164 format.}
botId: {type: string}
sipAccountId: {type: string}
ringTimeout: {type: integer, default: 30}
startTimeout: {type: integer, default: 0}
state: {type: object, additionalProperties: true}
responses:
'200':
description: Outbound call started.
content:
application/json:
schema: {type: object, properties: {callId: {type: string}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/usage:
get:
tags: [Partner access]
operationId: listUsage
summary: Retrieve usage
description: Returns usage for the authenticated business and its available partner businesses, optionally filtered to one business and a date range.
security:
- apiToken: []
parameters:
- name: businessId
in: query
required: false
description: Business ID. It must be the authenticated business or an available partner business.
schema:
type: string
- name: start
in: query
required: false
description: Inclusive lower bound for the session creation timestamp.
schema:
type: string
format: date-time
- name: end
in: query
required: false
description: Inclusive upper bound for the session creation timestamp.
schema:
type: string
format: date-time
responses:
'200':
description: Usage records.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UsageRecord'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
description: The requested business is outside the token's scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/partnerClients:
get:
tags: [Partner access]
operationId: listPartnerClients
summary: List partner businesses
description: Returns visible businesses connected to the business associated with the API token.
security:
- apiToken: []
responses:
'200':
description: A list of partner businesses.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PartnerBusiness'
'401':
$ref: '#/components/responses/Unauthorized'
/knowledgeBase:
get:
tags: [Partner access]
operationId: listKnowledgeBaseFiles
summary: List knowledge-base files
description: Returns knowledge-base files for the business associated with the API token.
security:
- apiToken: []
responses:
'200':
description: Knowledge-base files with non-obfuscated attribute names.
content:
application/json:
schema:
type: array
items: {$ref: '#/components/schemas/KnowledgeBaseFile'}
'401': {$ref: '#/components/responses/Unauthorized'}
post:
tags: [Partner access]
operationId: uploadKnowledgeBaseFile
summary: Upload a knowledge-base file
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: Uploaded file ID.
content:
application/json:
schema: {type: object, properties: {id: {type: string}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/knowledgeBase/{fileId}:
delete:
tags: [Partner access]
operationId: deleteKnowledgeBaseFile
summary: Delete a knowledge-base file
security:
- apiToken: []
parameters:
- name: fileId
in: path
required: true
schema: {type: string}
responses:
'200': {description: File deleted.}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {description: The file does not belong to the business associated with the token.}
/mediaFiles:
get:
tags: [Partner access]
operationId: listMediaFiles
summary: List media files
description: Returns media files for the business associated with the API token.
security:
- apiToken: []
responses:
'200':
description: Media files with non-obfuscated attribute names.
content:
application/json:
schema:
type: array
items: {$ref: '#/components/schemas/MediaFile'}
'401': {$ref: '#/components/responses/Unauthorized'}
post:
tags: [Partner access]
operationId: uploadMediaFile
summary: Upload a media file
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: Uploaded file ID.
content:
application/json:
schema: {type: object, properties: {id: {type: string}}}
'401': {$ref: '#/components/responses/Unauthorized'}
/mediaFiles/{fileId}:
delete:
tags: [Partner access]
operationId: deleteMediaFile
summary: Delete a media file
security:
- apiToken: []
parameters:
- name: fileId
in: path
required: true
schema: {type: string}
responses:
'200': {description: File deleted.}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {description: The file does not belong to the business associated with the token.}
components:
securitySchemes:
apiToken:
type: apiKey
in: header
name: X-API-TOKEN
description: Send the API token in `X-API-TOKEN: <token>`.
schemas:
BotExport:
type: object
properties:
name: {type: string}
id: {type: string}
stages: {type: array, items: {type: object}}
settings: {type: object}
wizard: {type: object}
PartnerBusiness:
type: object
description: Business data returned by the partner-business endpoint. Additional fields may be returned as the business model evolves.
additionalProperties: true
properties:
id:
type: string
description: Business ID.
name:
type: string
UsageRecord:
type: object
required: [id, businessId, botId, isCall, direction, duration, costs, start]
properties:
id: {type: string, description: Call-session ID.}
businessId: {type: string, description: Business ID.}
botId: {type: string, nullable: true, description: Bot ID.}
isCall: {type: boolean}
direction: {type: string, enum: [inbound, outbound]}
phoneNumberCaller: {type: string, nullable: true}
phoneNumberCallee: {type: string, nullable: true}
duration: {type: integer, minimum: 0, description: Duration in seconds.}
costs: {type: number, format: double}
start: {type: string, format: date-time}
KnowledgeBaseFile:
type: object
required: [id, name, fileSize, tokens]
properties:
id: {type: string, description: Obfuscated knowledge-base file ID.}
name: {type: string, description: Original filename.}
fileSize: {type: integer, description: File size in bytes.}
tokens: {type: integer, description: Number of processed tokens.}
MediaFile:
type: object
required: [id, name, fileSize]
properties:
id: {type: string, description: Obfuscated media file ID.}
name: {type: string, description: Original filename.}
fileSize: {type: integer, description: File size in bytes.}
Error:
type: object
properties:
error:
type: string
example: Invalid businessId
responses:
Unauthorized:
description: The API token is missing or invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'HTTP errors
401 Unauthorized: the API token is missing or does not match an API key.403 Forbidden: the requestedbusinessIdis not the authenticated business or an available partner business.