跳到主要內容
代理式電話通訊 API

AI 電話通話 API:用 AI 代理撥打和接聽真實電話

Wixzel Voice 是一個語音 AI API,用於打造 AI 代理,透過您自己的 SIP 中繼撥打和接聽真實的電話,或在您的網頁和行動應用程式中與人對話。一把 API 金鑰和一份預付餘額即可使用所有語音引擎,依實際用量按秒計費。

最後更新於

什麼是 Wixzel Voice 的 AI 電話通話 API?

使用 Wixzel Voice API,由您定義的 AI 代理會透過您自己的 SIP 中繼撥打和接聽真實電話:以號碼和代理 id 呼叫 POST /v1/calls,依實際用量逐秒計費。

簡單來說,Wixzel Voice 是用於打造 AI 電話代理的語音 AI API:一個由您定義代理、由 Wixzel Voice 執行通話的 AI 撥號 API。外撥時,POST /v1/calls 撥打號碼並接上您的代理。來電時,設定了 inbound_agent_id 的電話號碼會接聽每一通打進來的電話。同一個代理也可以透過即時 API,在網頁或應用程式中與人對話,不需要電話線路;或透過 MCP 伺服器由 AI 助理操作。

Wixzel Voice 的做法是一把 API 金鑰、一份餘額、所有語音引擎:語音轉文字、語言和語音供應商的帳號都屬於平台,因此不需要自備 Deepgram、ElevenLabs 或 OpenRouter 金鑰。唯一需要您自備的是電話線路:自帶 SIP 中繼,可來自 Twilio、Telnyx、Plivo 或任何 SIP 供應商。

如何用 Wixzel Voice 撥打 AI 電話?

在您有了 API 金鑰和一些點數之後,只需四個請求。每個回應都帶有下一個請求需要的 id;範例程式碼從 shell 變數讀取這些 id。

  1. 01

    連接您的 SIP 中繼

    您電信業者的主機和憑證。密碼會加密儲存,之後不會再傳回。回應中包含 platform_ip(目前為 187.126.120.231),您的電信業者必須將其加入允許清單;以及 origination_uri(目前為 sip:187.126.120.231:5090),您的電信業者會把來電送到這裡。

    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

    在中繼上登錄電話號碼

    您在該電信業者已擁有的號碼,使用 E.164 格式。Wixzel Voice 不販售號碼,也不辦理號碼移轉。如果中繼連接的是您的 Twilio、Telnyx、Plivo、Vobiz 或 Vonage 帳號,也可以改用 POST /v1/phone-numbers/purchase 在該帳號上購買新號碼,由您的電信業者依其價格計費。

    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

    建立代理

    一段簡短、口語風格的提示詞、開場第一句話,以及語音:三個模型,或一個即時模型。opening_message 為必填,因為沒有開場白的代理接起電話後會一片沉默。outbound_phone_number_id 會讓步驟 2 的號碼成為它的來電顯示號碼。

    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

    撥打電話

    一個目的地號碼和一個代理。Idempotency-Key 為必填,因為網路逾時並不能告訴您通話是否已撥出:用同一個金鑰重試,會傳回原本的通話,而不會重複撥號。回應為 201,內容是該通話,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"'"
      }'

在第一通電話接通之前,您的電信業者必須將 platform_ip 加入允許清單。電信業者指南說明了這項設定在 Twilio, Telnyx, Plivo, Vonage, Bandwidth, Exotel, Vobiz, Mobily 中的位置。

如何用 TypeScript 或 Dart 撥打 AI 電話?

官方 SDK 是 npm 上的 wixzel-voice,適用於 Node、瀏覽器和邊緣執行環境上的 TypeScript 與 JavaScript;以及 pub.dev 上的 wixzel_voice,適用於 Dart 與 Flutter。兩者都涵蓋所有端點、會在遇到速率限制時重試,並在會花費金額的路徑上自動產生 Idempotency-Key。其他語言請使用一般的 HTTP API 和 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();
}

AI 代理如何在 Wixzel Voice 上接聽來電?

為電話號碼設定 inbound_agent_id,打到這個號碼的每通電話都會由該代理接聽。沒有設定時,打到這個號碼的來電會被拒絕。

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"'" }'

另一半設定在您的電信業者端:來電必須送到中繼的 origination_uri(目前為 sip:187.126.120.231:5090)。這是與允許清單分開的設定,位於電信業者主控台的不同位置;如果少了這項設定,號碼就永遠不會響:電信業者無處可送這通電話,所以任何記錄中都不會出現。每通來電都會記錄 direction: "inbound" 和雙方號碼,並觸發 inboundCall webhook。

Wixzel Voice 的通話紀錄會傳回什麼?

POST /v1/calls 會立即傳回該通話,status: "queued"。GET /v1/calls/{id} 在通話進行中和結束後都會傳回完整記錄;通話結束時,會有一個以 X-Wixzel-Signature 簽署的 callCompleted webhook 通知您的伺服器,因此您不必輪詢。

欄位內容
statusqueued、ringing、in-progress、completed、failed、busy、no-answer 或 canceled。
direction / channeloutbound 或 inbound;透過您的中繼進行的通話為 phone,從瀏覽器或應用程式發起的即時工作階段為 web。
duration_seconds通話結束後的通話時長。
engine代理所使用的語音引擎。
cost_micros通話費用,以微美元計(1,000,000 = $1.00),於通話結算時寫入。從未接通的通話為 null,不收任何費用。
transcript每一輪對話,包含 role(user、assistant 或 system)、content 和 UTC 時間戳記。也可以從 GET /v1/calls/{id}/transcript 取得。
summary / recording_url錄音,僅限有錄音的通話。透過 API 撥打的通話,summary 為空;請閱讀逐字稿。
failure_code / failure_reason未接通的通話:電信業者提供的 Q.850 原因碼(適合用來做程式分支的穩定依據),以及以白話說明的處理方式。
transfers每次嘗試把來電者轉給真人都有一筆記錄,包含狀態、響鈴時間和 SIP 原因碼。
metadata您附加在 POST /v1/calls 上的扁平字串對應表,原樣傳回。永遠不會傳送給模型。

cost_micros 上的每一微美元,都能在 GET /v1/usage/events 的用量記錄中找到對應:辨識的語音秒數、模型的輸入與輸出 token、合成的字元數,以及每分鐘的協調費。

AI 電話未接通時會怎樣?

被電信業者拒絕的通話會有 status: "failed"(或 busy、no-answer)、failure_code 和 failure_reason,以及 cost_micros: null:不收任何費用,為它預留的點數也會釋放。failure_code 是電信業者提供的 Q.850 原因碼,是做程式分支的穩定依據;failure_reason 以白話說明該如何處理。

有些請求在撥號之前就會被拒絕,且不收費:餘額不足以支付前 15 秒時為 402 insufficient_credits,未帶 Idempotency-Key 的直接請求為 400 missing_idempotency_key,超過同時通話上限的通話則以 503 拒絕。 每個失敗代碼和每種拒絕情況,以及各自的處理方式,都列在電信業者頁面上。

在 Wixzel Voice 上,一通 AI 電話的費用是多少?

以一般語速計算的單通通話引擎費用,由計費系統實際依據的價目表算出。每個價格都已含每分鐘 $0.012 的協調費。通話依實際用量逐秒計費,因此 90 秒的通話費用約為三分鐘通話的一半。電信使用您自己的中繼,以您電信業者的費率計費,不包含在內。

引擎管線1 分鐘通話3 分鐘通話5 分鐘通話
classicDeepgram + GPT-4o-mini + ElevenLabs$0.0867$0.2601$0.4335
sarvamSarvam,全程處理印度語言$0.0617$0.1851$0.3085
gemini-liveGemini Live,原生音訊$0.0491$0.1473$0.2455
deepgram-agentDeepgram Voice Agent$0.1851$0.5553$0.9255

預付制:從 $5 起儲值點數,沒有訂閱,也沒有免費方案。目前最便宜的引擎是 gemini-live,每分鐘 $0.0491。估算您自己的組合。

Wixzel Voice 的 AI 電話通話 API 有哪些限制?

  • Wixzel Voice 已上線,正在處理真實通話。行為變更會透過標註日期的 Wixzel-Version 標頭發布,現有的金鑰會保留建立時的行為。
  • 預設每個帳號可同時進行 5 通通話,可依申請提高。網頁與應用程式工作階段計入同一個上限。
  • 轉接真人僅支援盲轉:來電者會直接轉到您列出的號碼。尚未支援指定轉接(先與對方通話再轉),測試通話以及網頁或應用程式工作階段也無法轉接。
  • Wixzel Voice 不販售號碼,也不辦理號碼移轉,電話通話需要您自己的 SIP 中繼。它可以在您自己的 Twilio、Telnyx、Plivo、Vobiz 或 Vonage 帳號上為您購買號碼,由您的電信業者計費。
  • 網頁與應用程式工作階段傳輸 8 kHz 的 G.711 µ-law 音訊,屬於電話音質,而不是寬頻音質。
  • 每把金鑰每秒 10 次 API 請求,突發上限 20 次。遭速率限制的請求一律不收費。
  • API 和儲存的資料位於印度孟買。位於美國和印度的語音與語言供應商會在通話期間處理音訊和文字;sarvam 引擎在印度處理語音。
  • 沒有免費方案,也沒有試用點數。最低儲值金額為 $5。唯一的免費使用,是每個帳號 5 分鐘從主控台與您的代理對話。

常見問題

什麼是 AI 電話通話 API?

一種把 AI 代理接上真實電話通話的 API:您的程式碼指定號碼和代理,API 負責撥號、以語音辨識、語言模型和語音合成進行對話,並傳回通話狀態、逐字稿和費用。Wixzel Voice 就是其中之一:POST /v1/calls 透過您自己的 SIP 中繼撥打電話,而設定了 inbound_agent_id 的電話號碼也以同樣方式接聽來電。

Wixzel Voice 是 AI 撥號 API,還是現成的通話代理?

是 API。代理由您打造:它的提示詞、開場白、語音引擎,以及您的系統如何處理結果。Wixzel Voice 販售的是 API、SDK 和 MCP 伺服器,從不販售現成的代理。

一通 AI 電話的費用是多少?

語音引擎費用為 classic 每接通一分鐘 $0.0867, sarvam 每接通一分鐘 $0.0617, gemini-live 每接通一分鐘 $0.0491, deepgram-agent 每接通一分鐘 $0.1851,每個都已含 $0.012 的協調費,依實際用量逐秒計費。在 classic 上的三分鐘通話約為 $0.2601。電話線路由您的電信業者依您的費率另行計費,不加價。

AI 代理除了外撥,也能接聽來電嗎?

可以。用 PATCH /v1/phone-numbers/{id} 為電話號碼設定 inbound_agent_id,打到該號碼的電話就會由該代理接聽。您的電信業者必須把來電送到中繼傳回的 origination_uri。沒有設定 inbound_agent_id 時,打到該號碼的來電會被拒絕。

AI 代理可以把來電者轉給真人嗎?

可以,採盲轉:當來電者要求找真人時,代理會把進行中的通話轉給您在代理的 human_transfer 中列出的其中一個目的地,透過您的 SIP 中繼撥出。代理先與對方通話再轉接的指定轉接尚未支援,測試通話以及網頁或應用程式工作階段也無法轉接。

可以同時進行多少通 AI 通話?

預設每個帳號可同時進行 5 通通話,可依申請提高。超過上限的通話會在撥號前被拒絕,不收任何費用。網頁與應用程式工作階段計入同一個上限。

有免費試用嗎?

沒有免費方案,也沒有試用點數。API 採預付制,最低儲值 $5,沒有訂閱。每個新帳號有 5 分鐘免費時間,可從主控台與自己的代理對話;電話通話一律使用點數。無法支付前 15 秒費用的通話,會在分配任何資源之前以 402 insufficient_credits 拒絕。

下一步

建立您的第一個語音代理