Twilio Call API Incurs No Charges for Unanswered Calls: Verified Through Usage Records API Testing
This page has been translated by machine translation. View original
Introduction
I verified whether outbound calls via the Twilio Call API incur charges based on ring time when the recipient doesn't answer by checking the Usage Records API. In conclusion, I confirmed that there are no charges during unanswered ring time. If a voicemail answers, charges will apply, but you can automatically disconnect from the application side using Twilio's Answering Machine Detection (AMD).
What is Twilio
Twilio is a cloud platform that provides communication features like phone and SMS through APIs. Using the Call API, you can make outbound calls programmatically.
Target Audience
- Those wanting to understand the Twilio Call API charging structure accurately
- Those wanting to verify charges for unanswered calls based on test data
- Those needing to understand how voicemail affects charging
Test Environment
The test environment was as follows:
| Item | Value |
|---|---|
| Source number | US number (+1) |
| Destination number | Japanese mobile number (+81) |
| Twilio SDK | twilio 5.11.2 (Node.js) |
| Test date | 2026-02-02 (UTC) |
References
- Twilio Voice API - Making Calls
- Twilio Usage Records API
- Twilio Answering Machine Detection (AMD)
- Twilio Voice Pricing
Test Overview
The verification was conducted as follows. I took snapshots of Usage Records API before and after making calls, and determined whether charges occurred by comparing the differences.
APIs Used for Verification
I used the Twilio Usage Records API to determine charges. This API returns aggregated usage values for the entire account. I retrieved the following 2 categories before and after calls, and compared the differences in count (number of calls), usage (billable minutes), and price (amount charged).
| Category | Description |
|---|---|
calls-outbound |
Outbound call count, minutes, and charges |
totalprice |
Total charges across the entire account |
Code for Retrieving Usage Records
The following code gets today's Usage Records using the Twilio SDK:
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(),
};
}
Code for Making Calls with the Call API
I used client.calls.create() for outbound calls:
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;
}
The timeout parameter is the maximum number of seconds Twilio waits for an answer. If no answer is received within this time, Twilio ends the call with no-answer. However, as mentioned later, the recipient's carrier may terminate the call earlier.
Test Results
I conducted three test cases.
Test 1: Ringing for 60 seconds with voicemail OFF
In this case, voicemail was disabled on the recipient device, and it rang for 60 seconds with no answer.
| Item | Value |
|---|---|
| timeout setting | 60 seconds |
| Call status | no-answer |
| Call duration | 0 seconds |
| Call price | null |
Usage Records differences were as follows:
| Category | Increase in call count | Increase in billable minutes | Increase in charges |
|---|---|---|---|
calls-outbound |
0 | 0 min | 0 JPY |
totalprice |
- | - | 0 JPY |
After ringing for 60 seconds, Twilio reached the timeout and ended with no-answer. There was no increase in Usage Records, indicating no charges were incurred.
Test 2: Ringing for 300 seconds (5 minutes) with voicemail OFF
Same conditions but with timeout extended to 300 seconds.
| Item | Value |
|---|---|
| timeout setting | 300 seconds |
| Call status | busy |
| Call duration | 0 seconds |
| Call price | null |
Usage Records differences were as follows:
| Category | Increase in call count | Increase in billable minutes | Increase in charges |
|---|---|---|---|
calls-outbound |
0 | 0 min | 0 JPY |
totalprice |
- | - | 0 JPY |
Regarding charges, like Test 1, no charges were incurred.
Test 3: Ringing for 60 seconds with voicemail ON
In this case, voicemail was enabled on the recipient device and the voicemail answered. Machine Detection (AMD) was not used.
| Item | Value |
|---|---|
| timeout setting | 60 seconds |
| Call status | completed |
| Call duration | 69 seconds |
| Call price | -67.35 JPY |
Usage Records differences were as follows:
| Category | Increase in call count | Increase in billable minutes | Increase in charges |
|---|---|---|---|
calls-outbound |
+1 | +2 min | +57.56 JPY |
totalprice |
- | - | +59.58 JPY |
When the voicemail answered, Twilio transitioned the call status to in-progress. From Twilio's perspective, it can't distinguish from a human answer, so the call was treated as established.
The +2 minutes usage is the result of the actual call time of 69 seconds being rounded up to minutes. Charges are incurred when voicemail answers.
Findings and Countermeasures
No charges during ring time
Twilio call charges start when the call is answered. During ring time (ringing state), the duration is 0, price is null, and nothing is recorded in Usage Records. From both Tests 1 and 2, where all Usage Records differences were 0, we can conclude that unanswered ring time does not incur charges.
AMD can address voicemail issues
When voicemail answers a call, Twilio processes it as completed. As confirmed in Test 3, without AMD, Twilio can't distinguish between voicemail and human responses, resulting in charges.
However, Twilio provides standard Answering Machine Detection (AMD). By specifying the machineDetection parameter when making a call via the Call API, Twilio automatically determines the responder and returns values like human or machine_start in the answeredBy field. Applications can control this by immediately disconnecting if answeredBy is not human.
const call = await client.calls.create({
to,
from,
url: twimlUrl,
timeout: timeoutSec,
machineDetection: "Enable", // Enable AMD
});
With AMD enabled, calls identified as voicemail can be disconnected quickly, minimizing charges.
Carrier ring time limits make long ringing difficult
Even if a long time is specified in Twilio's timeout parameter, the recipient's carrier may terminate the call earlier. In Test 2, we specified 300 seconds, but the carrier returned busy after about 90 seconds.
For applications requiring long ringing periods, you may need to implement application-side handling such as redial when a call ends with no-answer or busy.
Charges are rounded up to the minute
In Test 3, the call time was 69 seconds, but the Usage Records usage was 2 minutes. Twilio charges in full minute increments (billed minutes), so even short calls incur at least 1 minute of charges.
In Test 3, there was a difference between the Call Resource price (-67.35 JPY) and the calls-outbound price in Usage Records (57.56 JPY). The Call Resource price includes connection fees in addition to call charges for individual calls. Usage Records, on the other hand, are aggregated values by category with different calculation methods. To understand the overall charging picture, referring to the totalprice category in Usage Records (+59.58 JPY) is appropriate.
Conclusion
For outbound calls using the Twilio Call API, I confirmed with actual Usage Records API data that no call charges are incurred during ring time when the recipient doesn't answer. If voicemail answers, charges apply, but by utilizing Twilio's AMD, you can detect voicemail responses and disconnect automatically, preventing unintended charges.