From twilio-developer-kit
SMS and MMS deep-dive reference. Covers SMS-specific error codes, message filtering troubleshooting ("Messages Being Filtered or Blocked?" diagnostic checklist), MMS media support (US/CA/AU only), and SMS pumping indicators. For sending SMS, use twilio-send-message instead. Use this skill only when debugging SMS delivery issues or needing SMS-specific details not in the consolidated send skill.
npx claudepluginhub twilio/ai --plugin twilio-developer-kitThis skill uses the workspace's default tool permissions.
**SMS is one channel in Twilio's Messaging platform.** All channels — SMS, WhatsApp, RCS, Facebook Messenger — share the same `messages.create()` API. See `twilio-messaging-overview` for the full channel comparison and onboarding sequence.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
SMS is one channel in Twilio's Messaging platform. All channels — SMS, WhatsApp, RCS, Facebook Messenger — share the same messages.create() API. See twilio-messaging-overview for the full channel comparison and onboarding sequence.
| When to use SMS | When to consider alternatives |
|---|---|
| Reach any phone number globally | Need rich media outside US/CA/AU → WhatsApp |
| No app install required | Opted-in audience prefers chat apps → WhatsApp |
| Time-sensitive alerts (OTP, outage) | Marketing campaigns → twilio-marketing-promotions-advisor |
| Regulatory/compliance requires SMS | Cost-sensitive high-volume → WhatsApp (lower per-msg cost in many markets) |
For production SMS: Use a Messaging Service (messagingServiceSid) instead of a raw from number. It enables sender pool management, compliance toolkit, SMS pumping protection, link shortening, and message scheduling. See twilio-messaging-services.
Every outbound SMS requires a from Twilio number (or messagingServiceSid) and a to recipient — both in E.164 format.
twilio-account-setup for signup, getting a number, and trial limitationsTWILIO_ACCOUNT_SIDTWILIO_AUTH_TOKEN
— See twilio-iam-auth-setup for credential setup and best practicespip install twilio / npm install twilioPython
import os
from twilio.rest import Client
client = Client(os.environ["TWILIO_ACCOUNT_SID"], os.environ["TWILIO_AUTH_TOKEN"])
message = client.messages.create(
from_="+15017122661", # Your Twilio number (E.164)
to="+15558675310", # Recipient (E.164)
body="Your appointment is confirmed for tomorrow at 2pm."
)
print(message.sid) # SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
print(message.status) # queued | sent | delivered | failed
Node.js
const twilio = require("twilio");
const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const message = await client.messages.create({
from: "+15017122661",
to: "+15558675310",
body: "Your appointment is confirmed for tomorrow at 2pm.",
});
console.log(message.sid);
console.log(message.status);
Python
message = client.messages.create(
from_="+15017122661",
to="+15558675310",
body="Here is your invoice.",
media_url=["https://example.com/invoice.pdf"]
)
Node.js
const message = await client.messages.create({
from: "+15017122661",
to: "+15558675310",
body: "Here is your invoice.",
mediaUrl: ["https://example.com/invoice.pdf"],
});
Supported media types: images (JPEG, PNG, GIF), PDF, audio, video. Max 5 MB per message.
Use messagingServiceSid instead of from — Twilio picks the best sender automatically from your pool.
Python
message = client.messages.create(
messaging_service_sid="MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
to="+15558675310",
body="Your order has shipped."
)
Node.js
const message = await client.messages.create({
messagingServiceSid: "MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
to: "+15558675310",
body: "Your order has shipped.",
});
Python
message = client.messages.create(
from_="+15017122661",
to="+15558675310",
body="Hello!",
status_callback="https://yourapp.com/sms-status"
)
Node.js
const message = await client.messages.create({
from: "+15017122661",
to: "+15558675310",
body: "Hello!",
statusCallback: "https://yourapp.com/sms-status",
});
Twilio POSTs to your URL at each transition: queued → sent → delivered (or failed/undelivered).
| Field | Description |
|---|---|
sid | Message identifier (SM...) |
status | queued, sent, delivered, undelivered, failed |
error_code | Populated on failure |
error_message | Human-readable description |
price | Cost (populated after delivery) |
date_sent | UTC timestamp |
| Code | Meaning | Fix |
|---|---|---|
| 21211 | Invalid to number | Validate E.164 format |
| 21408 | Permission to send to region not enabled | Enable geo-permissions in Console |
| 21610 | Number is on blocklist (opted out) | Do not retry; respect opt-out |
| 30003 | Unreachable destination | Carrier cannot deliver; try later |
| 30007 | Message filtered as spam | Review content and sender reputation |
| 30034 | Message from unregistered number | Complete A2P 10DLC registration — see twilio-compliance-onboarding |
| 30450 | SMS pumping detected | Message blocked by SMS pumping protection — see twilio-messaging-services |
If your messages aren't being delivered, check these causes in order:
twilio-compliance-onboardingtwilio-compliance-traffictwilio-security-hardeningtwilio-messaging-servicestwilio-account-setupFor delivery event tracking, set up StatusCallbacks or use twilio-debugging-observability.
from and to must be + followed by country code and numbertwilio-messaging-servicestwilio-messaging-overviewtwilio-messaging-webhookstwilio-messaging-servicestwilio-compliance-onboardingtwilio-whatsapp-send-message