Ir al contenido
API para telefonía con agentes

API de llamadas telefónicas con IA: haz y contesta llamadas reales con un agente de IA

Wixzel Voice es una API de IA de voz para crear agentes de IA que hacen y contestan llamadas telefónicas reales a través de tu propia troncal SIP, o que hablan con personas en tus apps web y móviles. Una clave de API y un saldo prepagado cubren todos los motores de voz, con cobro por segundo de uso real.

Última actualización:

¿Qué es la API de Wixzel Voice para llamadas telefónicas con IA?

Con la API de Wixzel Voice, un agente de IA que tú defines hace y contesta llamadas telefónicas reales por tu propia troncal SIP: POST /v1/calls con un número y el id de un agente, facturado por segundo de uso real.

En una línea, Wixzel Voice es la API de IA de voz para crear agentes telefónicos con IA: una API de llamadas con IA en la que tú defines el agente y Wixzel Voice ejecuta la llamada. En las salientes, POST /v1/calls marca un número y conecta tu agente. En las entrantes, un número de teléfono con un inbound_agent_id contesta todas las llamadas que recibe. El mismo agente también puede hablar con personas en una página web o una app mediante la API realtime, sin línea telefónica, o lo puede manejar un asistente de IA mediante el servidor MCP.

Wixzel Voice es una clave de API, un saldo, todos los motores de voz: las cuentas de los proveedores de voz, lenguaje y habla son de la plataforma, así que no hay que aportar claves de Deepgram, ElevenLabs ni OpenRouter. La línea telefónica es lo único que aportas: trae tu propia troncal SIP, de Twilio, Telnyx, Plivo o cualquier proveedor SIP.

¿Cómo haces una llamada telefónica con IA con Wixzel Voice?

Cuatro solicitudes, una vez que tienes una clave de API y algo de crédito. Cada respuesta incluye el id que necesita la siguiente solicitud; los fragmentos lo leen de variables del shell.

  1. 01

    Conecta tu troncal SIP

    El host y las credenciales de tu operador. La contraseña se cifra en reposo y nunca se vuelve a devolver. La respuesta incluye platform_ip (hoy 187.126.120.231), que tu operador debe incluir en su lista de permitidos, y origination_uri (hoy sip:187.126.120.231:5090), adonde tu operador envía las llamadas entrantes.

    cURL
    curl https://api.voice.wixzel.com/v1/sip-trunks \
      -H "Authorization: Bearer $WIXZEL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "My carrier",
        "host": "sip.carrier.example",
        "username": "acct123",
        "password": "..."
      }'
  2. 02

    Registra un número de teléfono en ella

    Un número que ya tienes con ese operador, en formato E.164. Wixzel Voice no vende ni porta números. Si la troncal está conectada a tu cuenta de Twilio, Telnyx, Plivo, Vobiz o Vonage, puedes comprar un número nuevo en esa cuenta con POST /v1/phone-numbers/purchase. Tu operador te lo factura a su precio.

    cURL
    curl https://api.voice.wixzel.com/v1/phone-numbers \
      -H "Authorization: Bearer $WIXZEL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "phone_number": "+14155550100",
        "sip_trunk_id": "'"$TRUNK_ID"'"
      }'
  3. 03

    Crea un agente

    Unas instrucciones breves en estilo hablado, las primeras palabras que dice y una voz: tres modelos, o un modelo en tiempo real. opening_message es obligatorio, porque un agente sin él contesta en silencio. outbound_phone_number_id convierte el número del paso 2 en su identificador de llamada.

    cURL
    curl https://api.voice.wixzel.com/v1/agents \
      -H "Authorization: Bearer $WIXZEL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Support",
        "system_prompt": "You are a concise support agent.",
        "opening_message": "Hi, how can I help?",
        "voice": {
          "stt": { "model": "deepgram/nova-3" },
          "llm": { "model": "openrouter/gpt-4o-mini" },
          "tts": { "model": "elevenlabs/eleven_flash_v2_5" }
        },
        "outbound_phone_number_id": "'"$NUMBER_ID"'"
      }'
  4. 04

    Haz la llamada

    Un destino y un agente. Idempotency-Key es obligatorio, porque un tiempo de espera agotado en la red no dice nada sobre si la llamada se hizo: reintentar con la misma clave devuelve la llamada original en lugar de marcar dos veces. La respuesta es 201 con la llamada, status: "queued".

    cURL
    curl https://api.voice.wixzel.com/v1/calls \
      -H "Authorization: Bearer $WIXZEL_API_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{
        "to": "+14155551234",
        "agent_id": "'"$AGENT_ID"'"
      }'

Antes de que se conecte la primera llamada, tu operador tiene que incluir platform_ip en su lista de permitidos. Las guías de operadores muestran dónde está ese ajuste en Twilio, Telnyx, Plivo, Vonage, Bandwidth, Exotel, Vobiz, Mobily.

¿Cómo haces una llamada telefónica con IA desde TypeScript o Dart?

Los SDK oficiales son wixzel-voice en npm, para TypeScript y JavaScript en Node, navegadores y entornos edge, y wixzel_voice en pub.dev, para Dart y Flutter. Ambos cubren todos los endpoints, reintentan cuando hay límite de tasa y generan el Idempotency-Key en las rutas que gastan dinero. Los demás lenguajes usan la API HTTP directamente y el documento OpenAPI.

TypeScript
import { WixzelVoice } from 'wixzel-voice';

const client = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY! });

// 1. Connect your SIP trunk.
const trunk = await client.sipTrunks.create({
  name: 'My carrier',
  host: 'sip.carrier.example',
  username: 'acct123',
  password: process.env.CARRIER_PASSWORD!,
});
console.log('Allowlist', trunk.platform_ip, 'and send inbound calls to', trunk.origination_uri);

// 2. Register a number you own on it.
const number = await client.phoneNumbers.create({
  phone_number: '+14155550100',
  sip_trunk_id: trunk.id,
});

// 3. Create the agent, with that number as its caller ID.
const agent = await client.agents.create({
  name: 'Support',
  system_prompt: 'You are a concise support agent.',
  opening_message: 'Hi, how can I help?',
  voice: {
    stt: { model: 'deepgram/nova-3' },
    llm: { model: 'openrouter/gpt-4o-mini' },
    tts: { model: 'elevenlabs/eleven_flash_v2_5' },
  },
  outbound_phone_number_id: number.id,
});

// 4. Place the call. The SDK sends the Idempotency-Key for you.
const call = await client.calls.create({ to: '+14155551234', agent_id: agent.id });

// Inbound: calls to the number are answered by the same agent.
await client.phoneNumbers.update(number.id, { inbound_agent_id: agent.id });

// Later: what happened, what it cost, what was said.
const detail = await client.calls.retrieve(call.id);
console.log(detail.status, detail.cost_micros, detail.failure_code, detail.failure_reason);
for (const line of detail.transcript) console.log(line.role, line.content);
Dart
import 'dart:io';

import 'package:wixzel_voice/wixzel_voice.dart';

Future<void> main() async {
  final client = WixzelVoice(apiKey: Platform.environment['WIXZEL_API_KEY']!);

  // 1. Connect your SIP trunk.
  final trunk = await client.sipTrunks.create(CreateSipTrunk(
    name: 'My carrier',
    host: 'sip.carrier.example',
    username: 'acct123',
    password: Platform.environment['CARRIER_PASSWORD']!,
  ));
  print('Allowlist ${trunk.platformIp}; send inbound calls to ${trunk.originationUri}');

  // 2. Register a number you own on it.
  final number = await client.phoneNumbers.create(CreatePhoneNumber(
    phoneNumber: '+14155550100',
    sipTrunkId: trunk.id,
  ));

  // 3. Create the agent, with that number as its caller ID.
  final agent = await client.agents.create(CreateAgent(
    name: 'Support',
    systemPrompt: 'You are a concise support agent.',
    openingMessage: 'Hi, how can I help?',
    voice: VoiceConfig.composed(
      stt: const SttConfig(model: 'deepgram/nova-3'),
      llm: const LlmConfig(model: 'openrouter/gpt-4o-mini'),
      tts: const TtsConfig(model: 'elevenlabs/eleven_flash_v2_5'),
    ),
    outboundPhoneNumberId: number.id,
  ));

  // 4. Place the call. The SDK sends the Idempotency-Key for you.
  final call = await client.calls.create(CreateCall(
    to: '+14155551234',
    agentId: agent.id,
  ));

  // Inbound: calls to the number are answered by the same agent.
  await client.phoneNumbers.update(
      number.id, UpdatePhoneNumber(inboundAgentId: agent.id));

  // Later: what happened, what it cost, what was said.
  final detail = await client.calls.retrieve(call.id);
  print('${detail.status} ${detail.costMicros} ${detail.failureCode}');
  for (final line in detail.transcript) {
    print('${line.role}: ${line.content}');
  }
  client.close();
}

¿Cómo contesta llamadas entrantes un agente de IA en Wixzel Voice?

Asigna al número de teléfono un inbound_agent_id y ese agente contestará todas las llamadas que reciba. Sin él, las llamadas entrantes a ese número se rechazan.

cURL
curl -X PATCH https://api.voice.wixzel.com/v1/phone-numbers/$NUMBER_ID \
  -H "Authorization: Bearer $WIXZEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "inbound_agent_id": "'"$AGENT_ID"'" }'

La otra mitad está en tu operador: las llamadas entrantes tienen que entregarse en el origination_uri de la troncal (hoy sip:187.126.120.231:5090). Es una configuración aparte, en otra parte de la consola del operador distinta de la lista de permitidos, y si falta, el número simplemente nunca suena: el operador no tiene adónde enviar la llamada, así que no aparece nada en ningún registro. Cada llamada entrante se registra con direction: "inbound" y ambos números, y dispara un webhook inboundCall.

¿Qué devuelve un registro de llamada de Wixzel Voice?

POST /v1/calls responde de inmediato con la llamada, status: "queued". GET /v1/calls/{id} devuelve el registro completo mientras la llamada está en curso y después de que termina, y un webhook callCompleted, firmado con X-Wixzel-Signature, avisa a tu servidor cuando termina para que no tengas que consultarlo una y otra vez.

CampoQué contiene
statusqueued, ringing, in-progress, completed, failed, busy, no-answer o canceled.
direction / channeloutbound o inbound; phone para una llamada por tu troncal, web para una sesión en tiempo real desde un navegador o una app.
duration_secondsCuánto duró la llamada, una vez terminada.
engineEl motor de voz con el que funcionó el agente.
cost_microsLo que costó la llamada, en microdólares (1,000,000 = $1.00), escrito cuando se liquida la llamada. null en una llamada que nunca se conectó, que no cuesta nada.
transcriptCada turno, con role (user, assistant o system), content y una marca de tiempo UTC. También en GET /v1/calls/{id}/transcript.
summary / recording_urlLa grabación, si la llamada se grabó. summary está vacío en las llamadas hechas mediante la API; lee la transcripción.
failure_code / failure_reasonEn una llamada que no se conectó: la causa Q.850 del operador, el dato estable sobre el que ramificar, y qué hacer al respecto en lenguaje claro.
transfersUna entrada por cada intento de pasar a quien llama con una persona, con su estado, el tiempo de timbrado y la causa SIP.
metadataEl mapa plano de cadenas que adjuntaste a POST /v1/calls, devuelto tal cual. Nunca se envía al modelo.

Cada microdólar de cost_micros se explica con una fila de uso en GET /v1/usage/events: segundos de voz reconocida, tokens de entrada y de salida del modelo, caracteres sintetizados y la cuota de orquestación por minuto.

¿Qué pasa cuando una llamada telefónica con IA no se conecta?

Una llamada que el operador rechazó tiene status: "failed" (o busy, o no-answer), un failure_code y un failure_reason, y cost_micros: null: no costó nada, y el crédito reservado para ella se liberó. failure_code es la causa Q.850 del operador, el dato estable sobre el que ramificar; failure_reason dice qué hacer al respecto en lenguaje claro.

Algunas solicitudes se rechazan antes de marcar nada, y no cuestan nada: un saldo que no alcanza para los primeros 15 segundos da 402 insufficient_credits, una solicitud directa sin Idempotency-Key da 400 missing_idempotency_key, y una llamada que supera el límite de llamadas simultáneas se rechaza con 503. Todos los códigos de error y todos los rechazos, con qué hacer en cada caso, están en la página de operadores.

¿Cuánto cuesta una llamada telefónica con IA en Wixzel Voice?

Costo del motor para una llamada, a velocidades de habla habituales, calculado a partir de la tarifa con la que factura el medidor. Cada precio incluye la cuota de orquestación de $0.012 por minuto. Las llamadas se facturan por segundo de uso real, así que una llamada de 90 segundos cuesta más o menos la mitad que una de tres minutos. La telefonía es tu propia troncal a la tarifa de tu operador y no está incluida.

MotorPipelineLlamada de 1 minutosLlamada de 3 minutosLlamada de 5 minutos
classicDeepgram + GPT-4o-mini + ElevenLabs$0.0867$0.2601$0.4335
sarvamSarvam, idiomas de la India de principio a fin$0.0617$0.1851$0.3085
gemini-liveGemini Live, audio nativo$0.0491$0.1473$0.2455
deepgram-agentDeepgram Voice Agent$0.1851$0.5553$0.9255

Prepago: agrega crédito desde $5, sin suscripción ni plan gratuito. El motor más barato hoy es gemini-live, a $0.0491 por minuto. Calcula tu propia combinación.

¿Cuáles son los límites de la API de Wixzel Voice para llamadas telefónicas con IA?

  • Wixzel Voice está en producción y atiende llamadas reales. Los cambios de comportamiento se publican detrás de un encabezado Wixzel-Version con fecha, y una clave existente conserva el comportamiento con el que se creó.
  • Cinco llamadas simultáneas por cuenta de forma predeterminada, ampliables a petición. Las sesiones web y de app cuentan para el mismo límite.
  • La transferencia a una persona solo es ciega: quien llama pasa directamente a un número que indicaste. La transferencia asistida no existe, y la transferencia no está disponible en llamadas de prueba ni en sesiones web o de app.
  • Wixzel Voice no vende ni porta números de teléfono, y las llamadas telefónicas necesitan tu propia troncal SIP. Puede comprarte un número en tu propia cuenta de Twilio, Telnyx, Plivo, Vobiz o Vonage, facturado por tu operador.
  • Las sesiones web y de app transmiten audio G.711 µ-law a 8 kHz, que es calidad telefónica, no de banda ancha.
  • 10 solicitudes a la API por segundo por clave, con ráfagas de 20. Una solicitud limitada por tasa nunca se cobra.
  • La API y los datos almacenados están en Bombay, India. Los proveedores de voz y lenguaje en Estados Unidos y la India procesan el audio y el texto mientras dura la llamada; el motor sarvam procesa la voz en la India.
  • Sin plan gratuito ni crédito de prueba. La recarga mínima es de $5. El único uso gratuito son 5 minutos por cuenta para hablar con tus agentes desde la consola.

Preguntas frecuentes

¿Qué es una API de llamadas telefónicas con IA?

Una API que conecta un agente de IA con una llamada telefónica real: tu código indica un número y un agente, y la API marca, lleva la conversación con reconocimiento de voz, un modelo de lenguaje y síntesis de voz, y devuelve el estado de la llamada, su transcripción y su costo. Wixzel Voice es una de ellas: POST /v1/calls hace una llamada por tu propia troncal SIP, y un número de teléfono con un inbound_agent_id contesta las llamadas de la misma manera.

¿Wixzel Voice es una API de llamadas con IA o un agente de llamadas terminado?

Una API. Tú creas el agente: sus instrucciones, su frase de apertura, su motor de voz y lo que tu sistema hace con el resultado. Wixzel Voice vende las API, los SDK y el servidor MCP, y nunca un agente terminado.

¿Cuánto cuesta una llamada telefónica con IA?

El motor de voz cuesta $0.0867 por minuto conectado con classic, $0.0617 por minuto conectado con sarvam, $0.0491 por minuto conectado con gemini-live, $0.1851 por minuto conectado con deepgram-agent, cada uno con la cuota de orquestación de $0.012 incluida, facturado por segundo de uso real. Una llamada de tres minutos con classic cuesta unos $0.2601. Tu operador te factura la línea telefónica por separado, a tus tarifas, sin recargo.

¿El agente de IA puede contestar llamadas entrantes además de hacer llamadas salientes?

Sí. Configura inbound_agent_id en un número de teléfono con PATCH /v1/phone-numbers/{id} y ese agente contestará las llamadas a ese número. Tu operador tiene que enviar las llamadas entrantes al origination_uri que devuelve la troncal. Sin un inbound_agent_id, las llamadas entrantes a ese número se rechazan.

¿El agente de IA puede transferir a quien llama con una persona?

Sí, como transferencia ciega: cuando quien llama pide hablar con una persona, el agente pasa la llamada en curso a uno de los destinos que indicaste en el agente en human_transfer, marcado por tu troncal SIP. La transferencia asistida, en la que el agente habla primero con la persona, no existe, y la transferencia no está disponible en llamadas de prueba ni en sesiones web o de app.

¿Cuántas llamadas con IA pueden estar en curso a la vez?

Cinco llamadas simultáneas por cuenta de forma predeterminada, ampliables a petición. Una llamada que supera el límite se rechaza antes de marcar nada y no cuesta nada. Las sesiones web y de app cuentan para el mismo límite.

¿Hay una prueba gratuita?

Sin plan gratuito ni crédito de prueba. La API es prepago, con una recarga mínima de $5 y sin suscripción. Cada cuenta nueva tiene 5 minutos gratis para hablar con sus propios agentes desde la consola; las llamadas siempre usan crédito. Una llamada que no puede cubrir sus primeros 15 segundos se rechaza con 402 insufficient_credits antes de reservar nada.

Adónde ir después