Twilio Call APIの未応答架電では呼び出し中の通話料は発生しない: Usage Records API で実測検証した
はじめに
Twilio Call API によるアウトバウンド発信で、相手が電話に出ない場合に呼び出し時間に応じた通話料が発生するかを Usage Records API で検証しました。結論として、未応答の呼び出し中は課金されないことを確認しました。 留守番電話が応答した場合は課金が発生しますが、Twilio が提供する Answering Machine Detection (AMD) を使えばアプリケーション側で自動的に切断できます。
Twilio とは
Twilio は電話や SMS などのコミュニケーション機能を API で提供するクラウドプラットフォームです。Call API を使うと、プログラムからアウトバウンド発信 (外線発信) を行えます。
対象読者
- Twilio Call API を使ったアウトバウンド発信の課金体系を正確に理解したい方
- 未応答時の課金有無を検証データに基づいて確認したい方
- 留守番電話が課金に与える影響を把握しておきたい方
検証環境
検証環境は次の通りです。
| 項目 | 値 |
|---|---|
| 発信元番号 | US 番号 (+1) |
| 着信先番号 | 日本国内 携帯番号 (+81) |
| Twilio SDK | twilio 5.11.2 (Node.js) |
| 検証日 | 2026-02-02 (UTC) |
参考
- Twilio Voice API - Making Calls
- Twilio Usage Records API
- Twilio Answering Machine Detection (AMD)
- Twilio Voice Pricing
検証の全体像
検証は次の流れで行いました。発信の前後で Usage Records API のスナップショットを取得し、その差分から課金の有無を判定します。
判定に使用した API
課金の判定には Twilio Usage Records API を使用しました。この API はアカウント全体の利用実績を集計した値を返します。以下の 2 カテゴリを発信の前後で取得し、count (通話回数)・usage (課金分数)・price (課金金額) の差分を比較しました。
| カテゴリ | 内容 |
|---|---|
calls-outbound |
アウトバウンド通話の回数・分数・金額 |
totalprice |
アカウント全体の合計課金額 |
Usage Records の取得コード
Twilio SDK を使い、今日の Usage Records を取得する処理は次のようになります。
async function fetchUsageToday(
client: Twilio.Twilio,
category: string,
): Promise<UsageSnapshot> {
const records = await client.usage.records.today.list({ category });
const record = records.find((r) => r.category === category);
if (!record) {
return {
category,
count: "0",
usage: "0",
price: "0",
asOf: new Date().toISOString(),
startDate: "",
endDate: "",
raw: null,
};
}
return {
category,
count: record.count ?? "0",
usage: record.usage ?? "0",
price: String(record.price ?? 0),
asOf: record.asOf ?? new Date().toISOString(),
startDate: record.startDate?.toISOString() ?? "",
endDate: record.endDate?.toISOString() ?? "",
raw: record.toJSON(),
};
}
Call API による発信コード
アウトバウンド発信には client.calls.create() を使用しました。
async function makeCall(
client: Twilio.Twilio,
from: string,
to: string,
timeoutSec: number,
twimlUrl?: string,
): Promise<string> {
const call = await client.calls.create({
to,
from,
url: twimlUrl ?? "https://demo.twilio.com/docs/voice.xml",
timeout: timeoutSec,
});
return call.sid;
}
timeout パラメータは Twilio 側が応答を待つ最大秒数です。この秒数を超えても応答がなければ、Twilio は通話を no-answer として終了します。ただし後述するように、着信先キャリアが先に呼び出しを打ち切る場合もあります。
検証結果
3 つのテストケースを実施しました。
テスト 1: 留守電 OFF で 60 秒間呼び出し
着信先端末の留守番電話を無効にし、60 秒間呼び出して誰も応答しないケースです。
| 項目 | 値 |
|---|---|
| timeout 設定 | 60 秒 |
| Call status | no-answer |
| Call duration | 0 秒 |
| Call price | null |
Usage Records の差分は次の通りです。
| カテゴリ | 増加した通話回数 | 増加した課金分数 | 増加した課金額 |
|---|---|---|---|
calls-outbound |
0 | 0 分 | 0 JPY |
totalprice |
- | - | 0 JPY |
60 秒間呼び出しが続いた後、Twilio が timeout に達して no-answer で終了しました。Usage Records に増加はなく、課金は発生していません。
テスト 2: 留守電 OFF で 300 秒 (5 分) 間呼び出し
同じ条件で timeout を 300 秒に延長したケースです。
| 項目 | 値 |
|---|---|
| timeout 設定 | 300 秒 |
| Call status | busy |
| Call duration | 0 秒 |
| Call price | null |
Usage Records の差分は次の通りです。
| カテゴリ | 増加した通話回数 | 増加した課金分数 | 増加した課金額 |
|---|---|---|---|
calls-outbound |
0 | 0 分 | 0 JPY |
totalprice |
- | - | 0 JPY |
課金に関しては、テスト 1 と同様に 課金は発生していません。
テスト 3: 留守電 ON で 60 秒間呼び出し
着信先端末の留守番電話を有効にして、留守電が応答するケースです。Twilio の Machine Detection (AMD) は使用していません。
| 項目 | 値 |
|---|---|
| timeout 設定 | 60 秒 |
| Call status | completed |
| Call duration | 69 秒 |
| Call price | -67.35 JPY |
Usage Records の差分は次の通りです。
| カテゴリ | 増加した通話回数 | 増加した課金分数 | 増加した課金額 |
|---|---|---|---|
calls-outbound |
+1 | +2 分 | +57.56 JPY |
totalprice |
- | - | +59.58 JPY |
留守番電話が応答した時点で Twilio は通話状態を in-progress に遷移させました。Twilio にとっては人間が応答した場合と区別がつかないため、通話が成立した扱いとなりました。
usage の +2 分は、実際の通話時間 69 秒が分単位で切り上げられた結果です。留守電が応答した場合は課金が発生します。
分かったこととその対策
呼び出し中は課金されない
Twilio の通話課金は、通話が応答 (answered) された時点から開始されます。呼び出し中 (ringing 状態) では duration は 0、price は null であり、Usage Records にも計上されませんでした。テスト 1 とテスト 2 の両方で Usage Records の差分がすべて 0 であったことから、未応答の呼び出しだけでは課金が発生しないと判断できます。
留守番電話には AMD で対策できる
留守電がコールに応答すると、Twilio は completed (通話完了) として処理します。テスト 3 で確認したように、AMD を使用しなければ留守電と人間の応答は区別されず、課金が発生します。
しかし Twilio は Answering Machine Detection (AMD) 機能 を標準で提供しています。Call API の発信時に machineDetection パラメータを指定すると、Twilio が応答先を自動判定し、answeredBy フィールドに human または machine_start などの値を返します。アプリケーション側では answeredBy が human でなければ即座に切断する、といった制御が可能です。
const call = await client.calls.create({
to,
from,
url: twimlUrl,
timeout: timeoutSec,
machineDetection: "Enable", // AMD を有効化
});
AMD を有効にした場合、留守電と判定された通話は短時間で切断されるため、課金を最小限に抑えられます。
キャリアの呼び出し制限により長時間の呼び出しは困難
Twilio の timeout パラメータで長い時間を指定しても、着信先キャリアが先に呼び出しを打ち切ることがあります。テスト 2 では 300 秒を指定しましたが、キャリア側が約 90 秒で busy を返しました。
長時間の架電が必要な場合は、no-answer や busy で終了した際にアプリケーション側で再発信するなどの方法をとる必要があります。
課金は分単位で切り上げられる
テスト 3 では通話時間が 69 秒であったのに対し、Usage Records の usage は 2 分でした。Twilio の課金は分単位の切り上げ (billed minutes) であるため、短い通話でも 1 分以上の課金が発生します。
テスト 3 では Call Resource の price が -67.35 JPY、Usage Records の calls-outbound の price が 57.56 JPY と差があります。Call Resource の price は通話料に加えて回線接続料等を含む個別通話の課金額です。一方 Usage Records はカテゴリごとの集計値であり、算出方法が異なります。課金の全体像を把握するには Usage Records の totalprice カテゴリ (+59.58 JPY) を参照するのが適切です。
まとめ
Twilio Call API のアウトバウンド発信において、相手が応答しない呼び出し中は通話料が発生しないことを、Usage Records API の実測データで確認しました。留守番電話が応答すると課金が発生しますが、Twilio が提供する AMD を活用すれば留守電応答を検知して自動切断でき、意図しない課金を防げます。






