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.

Listar sesiones de llamadas y obtener transcripciones

Usa GET /call_sessions para listar sesiones de llamadas o GET /conversations para listar sesiones con transcripciones visibles. Al listar sesiones, ambos endpoints requieren las fechas start y end y devuelven 30 elementos por página de forma predeterminada. El campo call indica si la sesión es una llamada telefónica.

curl --get https://voicebooker.de/app/api/v1/call_sessions \
  --header 'X-API-TOKEN: <tu-token-api>' \
  --data-urlencode 'start=2026-01-01' \
  --data-urlencode 'end=2026-01-31' \
  --data-urlencode 'page=1'

Usa el ID de sesión de una lista para obtener la transcripción (cs.id en /call_sessions e id en /conversations):

curl --get 'https://voicebooker.de/app/api/v1/conversations/<id-de-sesion>' \
  --header 'X-API-TOKEN: <tu-token-api>' \
  --data-urlencode 'trace=true' \
  --data-urlencode 'page=1'

Con trace=true, cada página incluye hasta 1.000 turnos cronológicos de la transcripción, además de los prompts, el estado, la pila y los detalles fsCalls de funciones/webhooks disponibles. Omite trace para obtener la página estándar de 30 elementos. Usa page para obtener páginas posteriores. El acceso se limita a las empresas disponibles para el token.

Si ya conoces el ID de contexto telefónico, GET /conversations?contextUId=<id-de-contexto> devuelve una transcripción compacta.

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.

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.}
  /call_sessions:
    get:
      tags: [Partner access]
      operationId: listCallSessions
      summary: Listar sesiones de llamadas
      description: Devuelve sesiones de llamadas de las empresas disponibles para el token API.
      security: [{apiToken: []}]
      parameters:
        - {name: start, in: query, required: true, description: Fecha de inicio inclusiva (AAAA-MM-DD)., schema: {type: string, format: date}}
        - {name: end, in: query, required: true, description: Fecha de fin inclusiva (AAAA-MM-DD)., schema: {type: string, format: date}}
        - {name: page, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
      responses:
        '200': {description: Página de sesiones de llamadas (30 elementos por página)., content: {application/json: {schema: {type: array, items: {type: object, additionalProperties: true}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
  /conversations:
    get:
      tags: [Partner access]
      operationId: listTranscribedSessions
      summary: Listar sesiones con transcripción
      description: Devuelve sesiones visibles con transcripciones de las empresas disponibles para el token API. El parámetro contextUId permite obtener en su lugar una transcripción compacta para un contexto telefónico conocido.
      security: [{apiToken: []}]
      parameters:
        - {name: start, in: query, required: false, description: Obligatorio al listar sesiones., schema: {type: string, format: date}}
        - {name: end, in: query, required: false, description: Obligatorio al listar sesiones., schema: {type: string, format: date}}
        - {name: page, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
        - {name: contextUId, in: query, required: false, description: Devuelve una transcripción compacta de este contexto telefónico en lugar de una lista de sesiones., schema: {type: string}}
      responses:
        '200': {description: Página de sesiones con transcripción o transcripción compacta del contexto., content: {application/json: {schema: {type: array, items: {type: object, additionalProperties: true}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
  /conversations/{id}:
    get:
      tags: [Partner access]
      operationId: getCallTranscript
      summary: Obtener una transcripción de llamada
      description: Devuelve turnos cronológicos de la transcripción y datos asociados a la llamada para una sesión disponible. trace=true incluye hasta 1.000 turnos por página, con prompts, estado, pila y llamadas a funciones/webhooks disponibles.
      security: [{apiToken: []}]
      parameters:
        - {name: id, in: path, required: true, description: ID de sesión obtenido de una lista., schema: {type: string}}
        - {name: page, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
        - {name: trace, in: query, required: false, description: Establécelo en true para obtener el seguimiento detallado; omítelo para la respuesta estándar., schema: {type: boolean}}
      responses:
        '200': {description: Turnos de la transcripción de la página solicitada., content: {application/json: {schema: {type: array, items: {type: object, additionalProperties: true}}}}}
        '401': {$ref: '#/components/responses/Unauthorized'}
  /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