Api

Introducción


Los servicios web de vpbx están desarrollados usando el estándar REST, usando JSON como formato de intercambio de datos.

URL base para servicios web

La URL base sobre la que están los servicios web es:

  • https://vpbx.me/api
Firma de peticiones

Todas las peticiones que se envien a los servicios web, deben ir firmadas mediante la cabecera:

X-Api-Key

Para saber que valores se pueden utilizar para firmar las peticiones deberá consultar en la sección de configuración "Claves API".

Claves API


Las claves API son necesarias para el desarrollo del apartado de "servicios web", en este apartado las daremos de alta para poder registrar los diferentes servicios que estemos implementando.

Click2Call


Atención

Para hacer un click2call a una extensión interna y que al descolgar se marque a un destino exterior, se usará el método Generar llamada a extensión.

Si lo que se quiere hacer es sonar en un número exterior y enviar a un destino interno (tal como una cola, grupo de ring, extensión, menú vocal, etc), se tendrá que usar el método Generar llamada a un número exterior

Generar llamada a extensión

GET /originatecall/FROM/TO

Descripción

Genera una llamada desde FROM (extensión) hacía TO

Hay que tener en cuenta que el FROM sólo puede ser una extensión de la PBX. Se deberán de usar destinos externos para usar el FROM con números tradicionales.

Permisos

Generar llamadas (click2call) en la centralita asignada a la Api Key utilizada.

Petición

La petición se realizará pasando en la URL todos los parámetros necesarios

Parámetros URL
Nombre Tipo Valor por defecto Opcional Descripción
FROM numérico - No Extensión dónde sonará primero
TO numérico - No Destino donde se llamará una vez descolgada la llamada en FROM
timeout numérico 30 Tiempo en segundos que sonará en FROM antes de descartar la llamada
autoAnswer booleano false Desculegue automático en FROM (sólo para terminales soportados)
outboundId uuid null Una vez descolgado en FROM, la llamada al TO se cursará por las Reglas de salida con el indentificador indicado
  • URL de ejemplo completa
https://vpbx.me/api/originatecall/120/966261122?timeout=20&autoAnswer=true&outboundId=afb77f08177247fabe8fadf4a7307af0
Generar llamada a un número exterior

GET /c2cexternal/FROM/TO

Descripción

Genera una llamada desde FROM hacía TO (destino interno)

Hay que tener en cuenta que el TO sólo puede ser un destino interno de la PBX.

Permisos

Generar llamadas (click2call) en la centralita asignada a la Api Key utilizada.

Petición

La petición se realizará pasando en la URL todos los parámetros necesarios

Parámetros URL
Nombre Tipo Valor por defecto Opcional Descripción
FROM númerico - No Número externo dónde sonará primero
TO númerico - No Destino interno donde se llamará una vez descolgada la llamada en FROM, será un Número Dp o una extensión
timeout númerico 30 Tiempo en segundos que sonará en FROM antes de descartar la llamada
outboundId uuid null Una vez descolgado en FROM, la llamada al TO se cursará por las Reglas de salida con el indentificador indicado
  • URL de ejemplo completa
https://vpbx.me/api/c2cexternal/966261122/*601?timeout=20&outboundId=afb77f08177247fabe8fadf4a7307af0
Respuesta

El servicio web devolverá un mensaje JSON con los siguiente parámetros:

  • success: true|false en función de si se ha procesado correctamente el click2call
  • message: mensaje descriptivo
  • variables: variables usadas en el request
Ejemplo de respuesta al request de ejemplo
{
 "success":true,
 “message":"Call originated",
 "method":"originatecall",
 "variables":
        {
         "from":"120",
         "to":"966261122",
         "timeout":"20",
         "autoAnswer":"true",
         "outboundId":"afb77f08177247fabe8fadf4a7307af0",
         "callId":"8e09b9c9-42e6-46ef-9b83-4187b0c2312c"
        }
}
Obtener el ID de la llamada generada por un clic2call

GET /cdrc2c/<call id>

Descripción

Devuelve el callId del cdr de una llamada generada por el click2call, para ello se pasa el callId devuelto por servicio de click2call.

Permisos

Obtener IDs de click2call en la centralita asignada a la Api Key utilizada.

Petición
https://vpbx.me/api/cdrc2c/a992ba30-8233-11e5-8d44-6f9b49995edf
Respuesta

El servicio web devolverá un mensaje JSON con los siguientes parámetros:

  • uuid: identificador real de la llamada generada en el click2call
Ejemplo de respuesta al request de ejemplo
{
"uuid":"ebebaf72-8233-11e5-bc95-53cfef9baeb1"
}

Puede consultar la sección Código de ejemplo para más información


Consultar el registro de llamadas de la centralita


  • URL relativa: /cdr
Datos de una llamada

GET /cdr/<call id>

Permisos

Acceso a los registros de la centralita asignada a la Api Key utilizada.

Respuesta

La respuesta es un JSON con los siguientes campos

Nombre Descripción Tipo Comentarios
callId id de llamada String
created Fecha de la llamada long timestamp en milisegundos desde el 1/1/1970 (GMT)
duration Duración total int en segundos
billsec Duración descolgado int en segundos
hangupCause Causa de cuelgue String
dst Destino String
src Origen String
dstStarts Destino empieza por String
srcStarts Origen empieza por String
srcName Nombre de origen String
did Número externo por el que entró la llamada String
c2c Originada en c2c Boolean
c2cRequestIp IP que originó el c2c String
c2cFrom Origen del c2c String
c2cTo Destino del c2c String
recording Si hay grabación disponible Boolean
queueId ID de la cola String Si la llamada ha pasado por una cola
queueWaitTime Tiempo de espera en la cola int Si la llamada ha pasado por una cola
queueAgent Agente que ha atendido la llamada String Si la llamada ha pasado por una cola
queueCause Causa de colgado en la cola String Si la llamada ha pasado por una cola
queueReason Razón de colgado en la cola String Si la llamada ha pasado por una cola
# Respuesta de ejemplo
{
  "callId":"7bb5b023-c67e-471e-9145-7afa3b13faad",
  "created":1401805669000,
  "duration":5,
  "billsec":0,
  "hangupCause":"ORIGINATOR_CANCEL",
  "dst":"966261122",
  "src":"2023",
  "did":null,
  "srcName":"2023",
  "c2c":false,
  "c2cRequestIp":null,
  "c2cFrom":null,
  "c2cTo":null,
  "recording":false,
  "queueId": null,
  "queueWaitTime": null,
  "queueAgent": null,
  "queueCause": null,
  "queueReason": null
}
Valores posibles de queueCause
Nombre Descripción
cancel No ha sido atendido el llamante
answered Se ha atendido al llamante

Si se ha cancelado la llamada, se rellena el campo "queueReason", que puede tener los siguientes valores:

Nombre Descripción
NONE Sin razón específica
TIMEOUT El llamante ha superado el tiempo máximo de espera en cola
NO_AGENT_TIMEOUT El llamante ha superado el tiempo máximo para esperar a un agente
BREAK_OUT El llamante ha abandonado
Lista de llamadas

POST /cdr

Permisos

Acceso a los registros de la centralita asignada a la Api Key utilizada.

Petición

El servicio espera un petición en formato JSON ("Content-Type: application/json)") a modo de filtro, de no ser así, devolverá un 400 (Bad Request).

Parámetros de la petición
Nombre Descripción Tipo Obligatorio Comentario
from Desde la fecha long no en milisegundos desde el 1/1/1970
to Hasta la fecha long no en milisegundos desde el 1/1/1970
src Número de origen String no
dst Número de destino String no
did Número por el que entró String no
queueId ID interno de la cola String no Para obtener sólo las llamadas de una cola en particular
orderingField Campo por el que ordenar String no Por defecto se ordena por fecha. Valores posibles: [CREATED, SRC, DST, HANGUP_CAUSE, DID_NUMBER, DST_STARTS, SRC_STARTS]
ascending Ordenación ascendente Boolean no Por defecto se ordena de manera descendente
start Número de registro inicial int no
stop Número de registro final int no
Ejemplo de petición
{
 "src": "2023",
 "start": 0,
 "stop": 2
}
Respuesta

El servicio web devolverá un JSON consistente en un array de objectos JSON cdr (como el ejemplo para un cdr en particular) conforme a los filtros especeficados.

  • Si no se especifica start y stop, devuelve los últimos 50 resultados
  • Si no se especifica orderingField, se devuelve por orden de creación descendente
Respuesta de ejemplo
[
  {
    "callId":"7bb5b023-c67e-471e-9145-7afa3b13faad",
    "created":1401805669000,"duration":5,
    "billsec":0,
    "hangupCause":"ORIGINATOR_CANCEL",
    "dst":"966261122",
    "src":"2023",
    "did":null,
    "srcName":"2023",
    "c2c":false,
    "c2cRequestIp":null,
    "c2cFrom":null,
    "c2cTo":null,"recording":false,
    "queueId": null,
    "queueWaitTime": null,
    "queueAgent": null,
    "queueCause": null,
    "queueReason": null
  },
  {
    "callId":"e07cd6c6-c820-41ca-b548-92fba290bf4c",
    "created":1401805600000,
    "duration":30,
    "billsec":29,
    "hangupCause":"NORMAL_CLEARING",
    "dst":"2021",
    "src":"2023",
    "did":null,
    "srcName":"2023",
    "c2c":false,
    "c2cRequestIp":null,
    "c2cFrom":null,
    "c2cTo":null,
    "recording":false,
    "queueId": null,
    "queueWaitTime": null,
    "queueAgent": null,
    "queueCause": null,
    "queueReason": null
  }
]
Número de llamadas

POST /cdrcount

  • Este servicio se puede utilizar para la paginación de llamadas.
Permisos

Acceso a los registros de la centralita asignada a la Api Key utilizada.

Petición

El servicio espera una petición en formato JSON ("Content-Type: application/json") a modo de filtro, e no se así, devolverá un 400 (Bad Request).

Parámetros de la petición
Nombre Descripción Tipo Obligatorio Comentario
from Desde la fecha long no en milisegundos desde el 1/1/1970
to Hasta la fecha long no en milisegundos desde el 1/1/1970
src Número de origen String no Empieza por
dst Número de destino String no Empieza por
did Número por el que entró String no Empieza por
orderingField Campo por el que ordenar String no Por defecto se ordena por fecha
ascending Ordenación ascendente Boolean no Por defecto se ordena de manera descendente
start Número de registro inicial int no
stop Número de registro final int no
# Ejemplo de petición
{
 "src": "2023"
}
Respuesta

El servicio web devolverá un JSON con la variable "count" y el número de registros para el filtro especificado.

Ejemplo de respuesta para el filtro anterior
  {
    "count":1420
  }

Grabaciones


Recuperar llamada grabada

GET /recording/<call id>

Descripción

Devuelve el fichero MP3 con la grabación de la llamada si existe, si no existe, devolverá un 404 (Not Found)

Permisos

Obtener las grabaciones en la centralita asignada a la Api Key utilizada.

Extensiones


Gestión de extensiones

Mediante los servicios web aquí descritos, se podrá realizar cambios en las extensiones de centralita.

Obtener todas las extensiones

GET /extension

Obtener datos de una extensión

GET /extension/<id de extensión>

Buscar id de extensión por nombre de usuario (username)

GET /extension/findbyusername/<username>

Permisos

Acceso a la búsqueda de extensiones en la centralita asignada a la Api Key utilizada.

Respuesta

La respuesta es un json con los siguientes campos

Nombre Descripción Tipo Comentarios
extensionId id de extensión String
username username utilizado en la consulta String
Ejemplo
  • Petición
GET https://vpbx.me/api/extension/findbyusername/100
  • Respuesta
{
  "extensionId":"ff8081814a53b218014a53b2206c00ff",
  "username":"100"
}
Actualizar información de una extensión

POST /extension/<id de extensión>

Permisos

Acceso a las extensiones en la centralita asignada a la Api Key utilizada.

Petición

El servicio espera una petición en formato JSON ("Content-Type: application/json") a modo de filtro, de no ser así, devolverá un 400 (Bad Request).

Parámetros de la petición
Nombre Descripción Tipo Obligatorio Comentario
outboundId Id del outbound a asignar String
Respuesta

La respuesta en un JSON con los siguientes campos

Nombre Descripción Tipo Comentario
extensionId Id de extensión String
Ejemplo
  • Petición
POST https://vpbx.me/api/extension/ff8081814a53b218014a53b2206c00ff
{
  "outboundId": "ff8081814a53b218014a53b220840107"
}
  • Respuesta

El sistema responde con un 200 si se ha actualizado con éxito la extensión.

Eventos


Notificación de eventos

El sistema vpbx.me puede enviar notificaciones de eventos de llamadas (en formato JSON) en tiempo real a un sistema remoto, para ello, realiza peticiones web tipo POST a una URL configurada en el sistema (consulte con su integrador).

RINGING
  • Evento generado al empezar a sonar una extensión.
Variables facilitadas
Nombre Descripción
callId refencia de la llamada
callerNumber número del llamante
callerName nombre del llamante
calleeNumber número de destino (la extensión)
did número públic de entrada (opcional)
  • Ejemplo de mensaje RINGING
{
"eventType":"RINGING",
"variables":
  {
   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",
   "callerNumber":"915631789",
   "callerName":"Cliente 1",
   "calleeNumber":"115",
   "did":"965428888"
  }
}
Ejemplo de notificacion

Puedes probar tu desarrollo con este comando CURL de ejemplo

curl -vvv -XPOST [URL DEL SERVICIO] -d '{"eventType":"RINGING", "variables":  {   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",   "callerNumber":"915631789",   "callerName":"Cliente 1",   "calleeNumber":"115",   "did":"965428888"  }}'
ANSWERED
  • Evento generado al descolgar una extensión
Variables facilitadas
Nombre Descripción
callId refencia de la llamada
callerNumber número del llamante
callerName nombre del llamante
calleeNumber número de destino (la extensión)
did número públic de entrada (opcional)
  • Ejemplo de mensaje ANSWERED
{
"eventType":"ANSWERED",
"variables":
  {
   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",
   "callerNumber":"915631789",
   "callerName":"Cliente 1",
   "calleeNumber":"115",
   "did":"965428888"
  }
}
Consideraciones
  • El evento de answered se envía cuando una extensión descuelga. Por ejemplo, en un IVR, el evento de answered no se notificaría cuando se reproduce la locución.
Ejemplo de notificacion

Puedes probar tu desarrollo con este comando CURL de ejemplo

curl -vvv -XPOST [URL DEL SERVICIO] -d '{"eventType":"ANSWERED","variables":  {   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",   "callerNumber":"915631789",   "callerName":"Cliente 1",   "calleeNumber":"115",   "did":"965428888"  }}'
HANGUP

  • Evento generado al colgar una extensión
Variables facilitadas
Nombre Descripción
callId refencia de la llamada
callerNumber número del llamante
callerName nombre del llamante
calleeNumber número de destino (la extensión)
did número públic de entrada (opcional)
  • Ejemplo de mensaje HANGUP
{
"eventType":"HANGUP",
"variables":
  {
   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",
   "callerNumber":"915631789",
   "callerName":"Cliente 1",
   "calleeNumber":"115",
   "did":"965428888"
  }
}
Ejemplo de notificacion

Puedes probar tu desarrollo con este comando CURL de ejemplo

curl -vvv -XPOST [URL DEL SERVICIO] -d '{"eventType":"HANGUP","variables":  {   "callId":"62397e2e-7cfc-4c64-ade1-0b833ee3f10a",   "callerNumber":"915631789",   "callerName":"Cliente 1",   "calleeNumber":"115",   "did":"965428888"  }}'

Agentes


Los métodos aquí indicados irán siempre firmados con la cabecera "X-Api-Key" al igual que el resto de métodos.

Obtener los agentes disponibles

GET /agent

Con éste método se obtendrá un array JSON con los agentes dados de alta en el sistema, la respuesta sería así:

[
  {
    "extension":"100",
    "name":"a100",
    "status":"AVAILABLE",
    "breakType":null
  },
  {
    "extension":"200",
    "name":"a200",
    "status":"AVAILABLE",
    "breakType":null
  }
]
Obtener los cambios de estado de una serie de agentes

Para hacer las peticiones de los cambios de estado de uno o varios agentes se deberá enviar con un POST un objeto JSON con el filtro que necesitemos.

Propiedades disponibles en el filtro
Nombre Tipo Valor por defecto Opcional Descripción
start numérico - No Fecha de inicio, timestamp en milisengundos
end numérico - No Fecha fin, timestamp en milisegundos
statuses array de strings Array con los valores que queremos filtrar
agents array de strings Array con los agentes que queremos filtrar
offset numérico 0 No En el método de count se ignora. De todos los registros existentes, desde dónde se empieza
limit numérico 50 No En el método de count se ignora. A partir del offset, cuántos registros queremos

Los "statuses" posibles son los indicados en Estados de un agente

Contar los registros existentes para un filtro

POST /agent/statuscount

Descripción

Devuelve en JSON la propiedad count indicando cuántos registros existen para el filtro pasado como JSON en el POST para poder paginar los resultados.

Permisos

Obtener los cambios de estado de los agentes de la centralita asignada a la Api Key utilizada.

Ejemplo:

Petición para filtrar el estado "ON_BREAK" en los agentes "201" y "202" el día 19/05/2017 (desde las 00:00 hasta las 23:59 horas)

{
  "start":1495144800000,
  "end":1495231200000,
  "statuses": ["ON_BREAK"],
  "agents": ["201","202"],
}

La respuesta sería:

{
  "count": 2
}
Obtener los registros existentes para un filtro

POST /agent/status

Descripción

Devuelve en JSON con un array de los cambios de estado registrados para el filtro indicado pasado como JSON en el POST.

Permisos

Obtener los cambios de estado de los agentes de la centralita asignada a la Api Key utilizada.

Ejemplo:

Petición para filtrar el estado "ON_BREAK" en los agentes "201" y "202" el día 19/05/2017 (desde las 00:00 hasta las 23:59 horas)

{
  "start":1495144800000,
  "end":1495231200000,
  "statuses": ["ON_BREAK"],
  "agents": ["201","202"],
  "offset": 0,
  "limit": 2
}

La respuesta sería:

[
  {
    "agent":"201",
    "date":1495189860000,
    "status":"ON_BREAK",
    "agentBreakType":"Gestión"
  }
  {
    "agent":"202",
    "date":1495189860000,
    "status":"AVAILABLE",
    "agentBreakType":null
  }
]

Colas


Los métodos aquí indicados irán siempre firmados con la cabecera "X-Api-Key" al igual que el resto de métodos.

Obtener el tiempo de espera medio de las llamadas atendidas

GET /queue/{queueNumber}/waittime

El parámetro de la url queueNumber es el número entero que define el número de cola (se puede consultar en la interfaz web)

Devolverá un JSON con el tiempo de espera medio de las llamadas atentidadas.

Permisos

Obtener los cambios de estado de los agentes de la centralita asignada a la Api Key utilizada.

Ejemplo:

Petición para obtener el tiempo de espera de la cola "1":

GET /queue/1/waittime

Respuesta:

{
  "waitTime":136
}
Obtener las llamadas en cola

GET /queue/{queueNumber}/state

El parámetro de la url queueNumber es el número entero que define el número de cola (se puede consultar en la interfaz web)

Devolverá un JSON con un array de las llamadas en cola

Campos de las llamadas
Nombre del campo Descripción
uuid id de llamada
cidNumber Número del llamante
cidName Nombre del llamante
join Cuándo entro en la cola, timestamp en milisengundos
answer Cuándo le descolgó un agente, timestamp en milisengundos
abandoned Cuándo se consideró abandonada la llamada, timestamp en milisengundos
state Estado de la llamada: Waiting/Answered/Abandoned
score Tiempo en segundos desde que entró en la cola
servingAgent Agente que esta atendiendo la llamada
Permisos

Obtener los cambios de estado de los agentes de la centralita asignada a la Api Key utilizada.

Ejemplo:

Petición para obtener el tiempo de espera de la cola "1":

GET /queue/1/state

Respuesta:

[
  {
    "uuid":"0f5b4a5f-d1bc-41f5-9489-8c1a3dbbecff",
    "cidNumber":"600000000",
    "cidName":"600000000",
    "join":1497856540000,
    "answer":1497857602000,
    "abandoned":null,
    "state":"Answered",
    "score":1562,
    "servingAgent":"a201@demo.vpbx.me"
  },
  {
    "uuid":"e19be2f9-fc8e-45ca-814a-fe7ed0b18b04",
    "cidNumber":"610000001",
    "cidName":"610000001",
    "join":1497856616000,
    "answer":1497858089000,
    "abandoned":null,
    "state":"Answered","score":1486,
    "servingAgent":"a202@demo.vpbx.me"
  },
  {
    "uuid":"baba409e-7a83-405d-ade2-bca9b2c1791b",
    "cidNumber":"911123123",
    "cidName":"911123123",
    "join":1497856649000,
    "answer":null,
    "abandoned":null,
    "state":"Waiting",
    "score":1453,
    "servingAgent":""
  }

Obtener las voces disponibles


GET /voiceengine

Con éste método se obtendrá un array JSON con las voces disponibles en el sistema para Text To Speech (TTS). La voces no suelen variar, por lo que este servicio web no debe ser consultado continuamente, debe guardarse una copia de las voces disponibles en el servicio que este utilizando esta API.

Los voces vienen del servicio Amazon Polly, por lo que para saber qué idioma es cada una se puede consultar en su documentación.

La respuesta sería así:

[
   {
      "gender" : "Female",
      "languageCode" : "fr-BE",
      "voiceAndEngine" : "Isabelle::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Danielle::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Gregory::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "tr-TR",
      "voiceAndEngine" : "Burcu::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "cs-CZ",
      "voiceAndEngine" : "Jitka::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "de-CH",
      "voiceAndEngine" : "Sabrina::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Joanna::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Joanna::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Ruth::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-US",
      "voiceAndEngine" : "Lupe::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-US",
      "voiceAndEngine" : "Lupe::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Kevin::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "tr-TR",
      "voiceAndEngine" : "Filiz::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "sv-SE",
      "voiceAndEngine" : "Elin::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "sv-SE",
      "voiceAndEngine" : "Astrid::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ru-RU",
      "voiceAndEngine" : "Tatyana::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "ru-RU",
      "voiceAndEngine" : "Maxim::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ro-RO",
      "voiceAndEngine" : "Carmen::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-PT",
      "voiceAndEngine" : "Ines::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-PT",
      "voiceAndEngine" : "Ines::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "pt-PT",
      "voiceAndEngine" : "Cristiano::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Vitoria::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Vitoria::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Ricardo::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Camila::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Camila::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pl-PL",
      "voiceAndEngine" : "Maja::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "pl-PL",
      "voiceAndEngine" : "Jan::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "pl-PL",
      "voiceAndEngine" : "Jacek::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pl-PL",
      "voiceAndEngine" : "Ewa::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "pl-PL",
      "voiceAndEngine" : "Ola::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "nl-BE",
      "voiceAndEngine" : "Lisa::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "nl-NL",
      "voiceAndEngine" : "Ruben::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "nl-NL",
      "voiceAndEngine" : "Lotte::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "nl-NL",
      "voiceAndEngine" : "Laura::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "nb-NO",
      "voiceAndEngine" : "Ida::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "nb-NO",
      "voiceAndEngine" : "Liv::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ko-KR",
      "voiceAndEngine" : "Seoyeon::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "ko-KR",
      "voiceAndEngine" : "Seoyeon::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ja-JP",
      "voiceAndEngine" : "Kazuha::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "ja-JP",
      "voiceAndEngine" : "Tomoko::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "ja-JP",
      "voiceAndEngine" : "Takumi::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "ja-JP",
      "voiceAndEngine" : "Takumi::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ja-JP",
      "voiceAndEngine" : "Mizuki::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "it-IT",
      "voiceAndEngine" : "Bianca::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "it-IT",
      "voiceAndEngine" : "Bianca::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "it-IT",
      "voiceAndEngine" : "Giorgio::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "it-IT",
      "voiceAndEngine" : "Carla::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "is-IS",
      "voiceAndEngine" : "Karl::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "is-IS",
      "voiceAndEngine" : "Dora::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "fr-FR",
      "voiceAndEngine" : "Mathieu::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "fr-FR",
      "voiceAndEngine" : "Lea::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "fr-FR",
      "voiceAndEngine" : "Lea::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "fr-FR",
      "voiceAndEngine" : "Celine::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "fr-CA",
      "voiceAndEngine" : "Chantal::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "fr-CA",
      "voiceAndEngine" : "Gabrielle::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-US",
      "voiceAndEngine" : "Penelope::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "es-US",
      "voiceAndEngine" : "Miguel::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-MX",
      "voiceAndEngine" : "Mia::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-MX",
      "voiceAndEngine" : "Mia::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-ES",
      "voiceAndEngine" : "Lucia::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-ES",
      "voiceAndEngine" : "Lucia::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "es-ES",
      "voiceAndEngine" : "Enrique::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "es-ES",
      "voiceAndEngine" : "Conchita::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-GB-WLS",
      "voiceAndEngine" : "Geraint::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Salli::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Salli::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Matthew::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Matthew::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Kimberly::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Kimberly::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Kendra::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Kendra::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Justin::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Justin::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Joey::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Joey::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Ivy::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Ivy::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-NZ",
      "voiceAndEngine" : "Aria::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-ZA",
      "voiceAndEngine" : "Ayanda::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-IN",
      "voiceAndEngine" : "Raveena::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-IN",
      "voiceAndEngine" : "Aditi::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Emma::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Emma::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Brian::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Brian::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Amy::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Amy::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-AU",
      "voiceAndEngine" : "Russell::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-AU",
      "voiceAndEngine" : "Nicole::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-AU",
      "voiceAndEngine" : "Olivia::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "de-DE",
      "voiceAndEngine" : "Vicki::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "de-DE",
      "voiceAndEngine" : "Vicki::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "de-DE",
      "voiceAndEngine" : "Marlene::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "de-DE",
      "voiceAndEngine" : "Hans::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "da-DK",
      "voiceAndEngine" : "Naja::standard"
   },
   {
      "gender" : "Male",
      "languageCode" : "da-DK",
      "voiceAndEngine" : "Mads::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "da-DK",
      "voiceAndEngine" : "Sofie::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "cy-GB",
      "voiceAndEngine" : "Gwyneth::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "cmn-CN",
      "voiceAndEngine" : "Zhiyu::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "cmn-CN",
      "voiceAndEngine" : "Zhiyu::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "arb",
      "voiceAndEngine" : "Zeina::standard"
   },
   {
      "gender" : "Female",
      "languageCode" : "ar-AE",
      "voiceAndEngine" : "Hala::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "ca-ES",
      "voiceAndEngine" : "Arlet::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "de-AT",
      "voiceAndEngine" : "Hannah::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-US",
      "voiceAndEngine" : "Stephen::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-IN",
      "voiceAndEngine" : "Kajal::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "yue-CN",
      "voiceAndEngine" : "Hiujin::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "fi-FI",
      "voiceAndEngine" : "Suvi::neural"
   },
   {
      "gender" : "Female",
      "languageCode" : "en-IE",
      "voiceAndEngine" : "Niamh::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "en-GB",
      "voiceAndEngine" : "Arthur::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "de-DE",
      "voiceAndEngine" : "Daniel::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "fr-CA",
      "voiceAndEngine" : "Liam::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "es-US",
      "voiceAndEngine" : "Pedro::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "es-ES",
      "voiceAndEngine" : "Sergio::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "es-MX",
      "voiceAndEngine" : "Andres::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "fr-FR",
      "voiceAndEngine" : "Remi::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "it-IT",
      "voiceAndEngine" : "Adriano::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "pt-BR",
      "voiceAndEngine" : "Thiago::neural"
   },
   {
      "gender" : "Male",
      "languageCode" : "ar-AE",
      "voiceAndEngine" : "Zayd::neural"
   }
]