On April 28, 2026, seven Twilio API domains stop working:
api.ie1.twilio.comapi.au1.twilio.comapi.br1.twilio.comapi.de1.twilio.comapi.jp1.twilio.comapi.sg1.twilio.comapi.us2.twilio.com
If your code, SDK config, firewall allowlist, or security group references any of those hostnames, the calls will start failing. There is no SDK version bump that masks this — the DNS records go away.
Here's the awkward part, straight from Twilio's API Domain Migration Guide:
these domains process all requests in US1 regardless of the region code
Everyone who set region: 'de1' thinking they were keeping data in Germany for residency reasons — they weren't. The request hit a domain that routed everything to US1 anyway. The region code in the hostname was cosmetic.
This is incident #5 in our silent-breakage series (GitHub PushEvent, Stripe Basil, Shopify 2025-01, OpenAI Responses input_text). The pattern keeps repeating and the fix keeps looking the same.
What actually breaks
If you call Twilio like this today:
from twilio.rest import Client
client = Client(account_sid, auth_token, region='de1')
# SDK resolves to api.de1.twilio.com
client.messages.create(to='+49...', from_='+49...', body='hello')
On April 28, that api.de1.twilio.com DNS name stops resolving. The SDK bubbles up a connection error — ConnectionError in Python, ECONNREFUSED / ENOTFOUND in Node, depending on how the resolver fails. Your retry logic retries. Your logs fill up. Nothing recovers on its own.
Same thing for raw HTTP clients:
# This stops working on April 28, 2026
curl -u "$SID:$TOKEN" https://api.de1.twilio.com/2010-04-01/Accounts/$SID/Messages.json
The nastier failure mode isn't the SDK — it's your infrastructure:
- Firewall rules that allow outbound
443only toapi.de1.twilio.com - Security groups that whitelist the regional domain
- Load balancers with the domain hardcoded in health checks
- Proxies that route Twilio traffic through a specific egress
- Secret store entries that embed the full URL
SDK configs are easy to grep for. Terraform modules and Helm charts referencing api.de1.twilio.com in a cidr_blocks or allowed_hosts block — those are the ones that bite on April 28.
The two fix paths
Twilio gives you two options, and you need to pick based on what you were actually doing, not what you thought you were doing.
Path 1: You don't actually need regional processing
This is the majority case, because — again — the regional domains weren't processing regionally anyway.
Code change:
# Before
client = Client(account_sid, auth_token, region='de1')
# After
client = Client(account_sid, auth_token)
# Resolves to api.twilio.com
Raw HTTP:
# Before
curl https://api.de1.twilio.com/...
# After
curl https://api.twilio.com/...
Firewall / security group:
Add api.twilio.com (resolves to the US1 edge). Remove the regional hostname entries. If your infra does IP-based rules, you need Twilio's US1 IP list — do not attempt to resolve the domain and pin the IPs, Twilio's edge IPs rotate.
Path 2: You actually need regional processing
If you have a real regional processing requirement (data residency, latency, compliance), you need the new localized domains plus the edge parameter plus region-scoped credentials:
client = Client(
regional_account_sid,
regional_auth_token,
edge='dublin',
region='ie1',
)
# Resolves to api.dublin.ie1.twilio.com
Three things had to change, not one:
-
Hostname:
api.dublin.ie1.twilio.com(new localized pattern) -
SDK params: both
edgeandregion, together - Credentials: regional SID and token, not your global ones
If you only add the edge parameter and keep the old global credentials, you'll get auth errors. If you keep only region and drop edge, the SDK may still resolve to the deprecated domain depending on your SDK version.
Twilio's migration guide includes a warning: "Older SDK versions may not properly support the edge parameter or may have bugs related to regional routing." Update the SDK first. This is a second source of drift — you think you're migrated, but an old SDK silently rewrites your request back to the deprecated hostname.
Why your tests didn't catch it
You have integration tests. They hit a Twilio sandbox. They pass. The April 28 deprecation still ships a broken prod.
The reason is the same reason every other silent drift story ships a broken prod:
Your tests exercise the API's response shape. They don't exercise the infrastructure around the API.
A test that checks response.status == 'queued' will continue passing after April 28 — because your test environment probably uses api.twilio.com already, or it mocks Twilio entirely. The failure mode is DNS resolution against a specific hostname buried in your prod firewall rule. No unit test hits that path.
The same story played out with the OpenAI input_text removal: tests used output_text, the change was in the assistant role message format, and it only failed on request construction, not response parsing.
The pattern across APIs
Five incidents, same shape:
| # | API | What changed | Where tests missed it |
|---|---|---|---|
| 1 | GitHub PushEvent |
commits field silently dropped |
Tests didn't assert field presence |
| 2 | Stripe Basil |
current_period_end moved to items
|
Tests used Checkout fixtures |
| 3 | Shopify 2025-01 |
fulfillmentHold type change |
Tests mocked the response |
| 4 | OpenAI Responses |
input_text removed for assistants |
Tests covered request role=user |
| 5 | Twilio regional | Regional domains stop resolving | Tests don't hit prod DNS paths |
The consistent pattern: the breaking change lives in a layer your test suite isn't watching. Request construction, infrastructure config, DNS, header shape, optional field presence. Response-shape assertions catch ~20% of drift cases at best.
How to not be surprised by the next one
Three things actually help:
Subscribe to every vendor's changelog. Not just the ones you think you use — the ones the SDKs in your
package.jsonuse. Most companies announce breaking changes. You have to be reading.Monitor the raw response, not just
status == 'queued'. If Twilio's response drops a field next year, you want an alert, not a silent parse failure downstream.Watch the infrastructure layer. Firewall rules, security groups, and Terraform modules should reference hostnames, not cached IP addresses — and those hostnames need to survive vendor deprecation windows.
We built FlareCanary to do #2 — hit third-party APIs on a schedule, watch the response, page you when the shape changes. It's not magic; it's the poll-and-diff loop you would write yourself if you had the time. The APIs break whether you're watching or not.
We track API drift incidents in real time. If your stack touches Twilio and you haven't audited your hostname config yet, April 28 is a hard date.
Top comments (0)