VoiceBooker

Acceso a la API

VoiceBooker ofrece acceso programático a la API para integrar otras aplicaciones y automatizar flujos, como la recuperación de uso, el despliegue de bots y la integración con pipelines de CI/CD.

URL base

https://voicebooker.de/app/api/v1

Autenticación

Envíe un token API en cada solicitud mediante este header:

X-API-TOKEN: <su-token-api>

El token determina el contexto de empresa de la solicitud. Manténgalo seguro.

Exportar un bot

GET /exportBots/{botId} exporta un bot de la empresa asociada al token API. Use pretty=true para obtener HJSON legible.

curl --get 'https://voicebooker.de/app/api/v1/exportBots/<bot-id>' \
  --header 'X-API-TOKEN: <su-token-api>' \
  --data-urlencode 'pretty=true'

Ejemplo de respuesta:

{
  "name": "Asistente de recepción",
  "id": "kqrmxaveli",
  "stages": [
    {
      "name": "Welcome",
      "id": "mavotirenu",
      "linkId": "qeluzanopi",
      "template": false,
      "prompt": "Saluda a la persona que llama.",
      "tools": [],
      "functions": [],
      "settings": {},
      "stageConfig": [],
      "x": 0,
      "y": 0,
      "order": 0,
      "instanceSettings": {}
    }
  ],
  "settings": {},
  "wizard": {}
}

Importar un bot

POST /importBots importa una definición de bot en la empresa asociada al token. Envíe la definición exportada en contents. Para HJSON, filename debe terminar en .hjson. overwriteBotStages, overwriteTemplates y replaceBotStages son parámetros booleanos opcionales.

curl --request POST \
  --url https://voicebooker.de/app/api/v1/importBots \
  --header 'X-API-TOKEN: <su-token-api>' \
  --header 'Content-Type: application/json' \
  --data '{"filename":"bot.json","contents":{"name":"Asistente de recepción","settings":{},"stages":[]},"overwriteBotStages":false,"overwriteTemplates":false,"replaceBotStages":false}'

Ejemplo de respuesta:

{
  "id": "vexorimaku",
  "name": "Asistente de recepción",
  "settings": {},
  "invisible": false
}

Realizar llamadas salientes

Para realizar una llamada saliente, envíe una solicitud POST a:

https://voicebooker.de/app/api/v1/makeCall
Content-Type: application/json
X-API-TOKEN: <su-token-api>

Ejemplo de solicitud:

{
  "dest": "+49-351-123456789",
  "botId": "kqrmxaveli",
  "sipAccountId": "lupenakori",
  "ringTimeout": 25,
  "startTimeout": 10,
  "state": {
    "customerId": "zpjwletodo"
  }
}
ParámetroDescripción
destNúmero de destino en formato E.164.
botIdBot utilizado para la llamada.
sipAccountIdCuenta SIP utilizada; su número aparece al destinatario.
ringTimeoutSegundos que sonará antes de cancelar si nadie responde. Por defecto: 30 segundos.
startTimeoutSegundos que espera el bot antes de empezar a hablar.
stateDatos para webhooks o llamadas API durante la llamada, como un ID de cliente.

La API devuelve un callId:

{
  "callId": "xavurimeto"
}

Gestionar pruebas de bots

Las pruebas de bots comparan un bot de origen/llamada con un bot de destino/respuesta. Las solicitudes con clave API están limitadas a la empresa asociada al token; ambos bots deben pertenecer a esa empresa.

MétodoEndpointFunción
GET/bot_test_setupsListar pruebas.
POST/bot_test_setupsCrear una prueba.
PUT/bot_test_setups/{id}Actualizar una prueba.
DELETE/bot_test_setups/{id}Eliminar una prueba.

La respuesta pública contiene únicamente id, name, settings, srcBotId y destBotId. settings puede incluir convInitBot, maxConvTurns, asCall, startTimeout y stateUpdate. Al actualizar, los campos omitidos se conservan.

Obtener una grabación de llamada

GET /getRecording/{id} devuelve la grabación MP3 de una sesión de llamada. Usa como id el ID de sesión de llamada devuelto por /usage. La grabación debe haberse activado para la llamada.

La respuesta se transmite como audio/mpeg y puede guardarse directamente como archivo .mp3:

curl --request GET \
  --url https://voicebooker.de/app/api/v1/getRecording/<id-de-sesion> \
  --header 'X-API-TOKEN: <su-token-api>' \
  --output grabacion.mp3

El endpoint devuelve 404 Not Found cuando la sesión o su grabación no están disponibles para el token de API. Devuelve 401 Unauthorized si el token de API falta o no es válido.

Obtener uso

GET /usage devuelve sesiones telefónicas y de chat de la empresa autenticada y de sus empresas asociadas disponibles.

Sin businessId se incluyen todas las empresas disponibles. Use businessId para seleccionar una empresa y start y end para filtrar por la fecha de creación de la sesión.

curl --get https://voicebooker.de/app/api/v1/usage \
  --header 'X-API-TOKEN: <su-token-api>' \
  --data-urlencode 'businessId=zpjwletodo' \
  --data-urlencode 'start=2026-01-01T00:00:00Z' \
  --data-urlencode 'end=2026-02-01T00:00:00Z'

start y end son inclusivos. Use fechas ISO 8601 que puedan analizarse. Una empresa fuera del alcance del token produce 403 Forbidden.

Ejemplo de respuesta:

[
  {
    "id": "xavurimeto", "businessId": "zpjwletodo", "botId": "kqrmxaveli",
    "isCall": true, "direction": "inbound", "phoneNumberCaller": "+341701234567",
    "phoneNumberCallee": "+34911234567", "duration": 184, "costs": 0.46,
    "start": "2026-01-15T10:30:00.000Z"
  }
]

Listar empresas asociadas

Para integraciones de socios y revendedores, GET /partnerClients devuelve las empresas visibles conectadas con la empresa autenticada. Sus IDs pueden utilizarse como filtro businessId en el endpoint de uso.

curl --request GET \
  --url https://voicebooker.de/app/api/v1/partnerClients \
  --header 'X-API-TOKEN: <su-token-api>'

Ejemplo de respuesta:

[
  {
    "id": "zpjwletodo",
    "name": "Empresa de ejemplo",
    "city": "Madrid",
    "country": "ES"
  }
]

Gestionar archivos de la base de conocimientos y archivos multimedia

Las claves API pueden listar, cargar y eliminar archivos de la empresa asociada al token. Los ID de archivo están ofuscados, pero los nombres de los atributos de respuesta no lo están.

Listar archivos de la base de conocimientos

GET /knowledgeBase devuelve id, name, fileSize y tokens.

curl --request GET \
  --url https://voicebooker.de/app/api/v1/knowledgeBase \
  --header 'X-API-TOKEN: <su-token-api>'

Cargar un archivo de la base de conocimientos

POST /knowledgeBase acepta una carga multipart con los campos file y name.

curl --request POST \
  --url https://voicebooker.de/app/api/v1/knowledgeBase \
  --header 'X-API-TOKEN: <su-token-api>' \
  --form 'name=manual.pdf' \
  --form 'file=@manual.pdf'

Eliminar un archivo de la base de conocimientos

curl --request DELETE \
  --url https://voicebooker.de/app/api/v1/knowledgeBase/<id-archivo> \
  --header 'X-API-TOKEN: <su-token-api>'

Listar y cargar archivos multimedia

GET /mediaFiles devuelve id, name y fileSize. POST /mediaFiles utiliza los mismos campos multipart.

curl --request GET \
  --url https://voicebooker.de/app/api/v1/mediaFiles \
  --header 'X-API-TOKEN: <su-token-api>'

curl --request POST \
  --url https://voicebooker.de/app/api/v1/mediaFiles \
  --header 'X-API-TOKEN: <su-token-api>' \
  --form 'name=musica.mp3' \
  --form 'file=@musica.mp3'

Eliminar un archivo multimedia

curl --request DELETE \
  --url https://voicebooker.de/app/api/v1/mediaFiles/<id-archivo> \
  --header 'X-API-TOKEN: <su-token-api>'

Especificación OpenAPI

openapi: 3.1.0
info:
  title: VoiceBooker Partner API
  version: 1.0.0
  description: API para consultar empresas asociadas y datos de uso.
servers: [{url: https://voicebooker.de/app/api/v1}]
paths:
  /exportBots/{botId}:
    get:
      summary: Exportar 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: Definición del bot exportado., 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: El bot no pertenece a la empresa del token.}
  /importBots:
    post:
      summary: Importar 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 importado., content: {application/json: {schema: {type: object, properties: {id: {type: string}, name: {type: string}}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
  /makeCall:
    post:
      summary: Realizar una llamada saliente
      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: Llamada saliente iniciada., content: {application/json: {schema: {type: object, properties: {callId: {type: string}}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
  /getRecording/{id}:
    get:
      summary: Obtener una grabación de llamada
      operationId: getCallRecording
      security: [{apiToken: []}]
      parameters:
        - {name: id, in: path, required: true, schema: {type: string}, description: ID de la sesión de llamada.}
      responses:
        '200': {description: Grabación de llamada., content: {audio/mpeg: {schema: {type: string, format: binary}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
        '404': {description: La sesión o grabación no está disponible para este token de API.}
  /usage:
    get:
      summary: Obtener uso
      operationId: listUsage
      security: [{apiToken: []}]
      parameters:
        - {name: businessId, in: query, schema: {type: string}, description: Empresa que se desea consultar.}
        - {name: start, in: query, schema: {type: string, format: date-time}, description: Inicio inclusivo.}
        - {name: end, in: query, schema: {type: string, format: date-time}, description: Fin inclusivo.}
      responses:
        '200': {description: Registros de uso., content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/UsageRecord'}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
        '403': {description: La empresa no está disponible para este token.}
  /partnerClients:
    get:
      summary: Listar empresas asociadas
      operationId: listPartnerClients
      security: [{apiToken: []}]
      responses:
        '200': {description: Lista de empresas., 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: Archivos de la base de conocimientos., 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 archivo cargado., 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: Archivo eliminado.}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Archivo fuera del alcance del token.}}
  /mediaFiles:
    get:
      operationId: listMediaFiles
      security: [{apiToken: []}]
      responses: {'200': {description: Archivos multimedia., 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 archivo cargado., 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: Archivo eliminado.}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Archivo fuera del alcance del token.}}
  /bot_test_setups:
    get:
      operationId: listBotTests
      security: [{apiToken: []}]
      responses: {'200': {description: Pruebas de bots., 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: Prueba creada., content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetup'}}}}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Bot fuera del alcance o bots idénticos.}}
  /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: Prueba actualizada., content: {application/json: {schema: {$ref: '#/components/schemas/BotTestSetup'}}}}, '401': {$ref: '#/components/responses/Unauthorized'}, '403': {description: Bot fuera del alcance o bots idénticos.}, '404': {description: Prueba no encontrada.}}
    delete:
      operationId: deleteBotTest
      security: [{apiToken: []}]
      parameters: [{name: id, in: path, required: true, schema: {type: string}}]
      responses: {'200': {description: Prueba eliminada.}, '401': {$ref: '#/components/responses/Unauthorized'}, '404': {description: Prueba no encontrada.}}
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: El token falta o no es válido.}

Errores HTTP

  • 401 Unauthorized: falta el token API o no es válido.
  • 403 Forbidden: la empresa solicitada no está disponible para el token.

On this page