plugins/twilio-developer-kit/skills/twilio/twilio-whatsapp-send-message/SKILL.md
WhatsApp messaging deep-dive reference. Covers the 24-hour service window rules (free-form vs template mode), sandbox setup for testing, template approval workflow, production sender requirements, and WhatsApp-specific error handling. For sending WhatsApp messages, use twilio-send-message instead. Use this skill when setting up WhatsApp for the first time or debugging WhatsApp-specific delivery behavior.
npx skillsauth add openai/plugins twilio-whatsapp-send-messageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
WhatsApp is one channel in Twilio's Messaging platform. All channels share the same messages.create() API — see twilio-messaging-overview for the full channel comparison and onboarding sequence.
Twilio routes WhatsApp through the Programmable Messaging API — all numbers use whatsapp:+E.164 prefix. Two sending modes apply: free-form (within 24 hrs of last inbound) and template (anytime). Sending free-form outside the window causes silent delivery failure — always check which mode is required.
| Mode | When allowed | Parameters |
|------|-------------|------------|
| Free-form | Within 24 hrs of last inbound from user | body, optional mediaUrl |
| Template | Anytime | contentSid + contentVariables |
twilio-account-setupTWILIO_ACCOUNT_SIDTWILIO_AUTH_TOKEN
— See twilio-iam-auth-setup for credential setup and best practicespip install twilio / npm install twilioTesting (sandbox): Join by texting join <your-code> to +14155238886. No registration needed — see Console > Messaging > Try it out > Send a WhatsApp message. Sandbox participants must re-join every 3 days.
Production: Register a WhatsApp Business sender first — see twilio-whatsapp-manage-senders.
Python
import os
from twilio.rest import Client
client = Client(os.environ["TWILIO_ACCOUNT_SID"], os.environ["TWILIO_AUTH_TOKEN"])
message = client.messages.create(
from_="whatsapp:+14155238886", # Sandbox sender (or your production number)
to="whatsapp:+15005550006", # Must have joined the sandbox
body="Your order has been confirmed."
)
print(message.sid) # MMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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: "whatsapp:+14155238886",
to: "whatsapp:+15005550006",
body: "Your order has been confirmed.",
});
console.log(message.sid);
console.log(message.status);
Templates are created in Console > Messaging > Content Template Builder and must be approved by Meta. See twilio-content-template-builder for template creation.
Python
message = client.messages.create(
from_="whatsapp:+14155238886",
to="whatsapp:+15005550006",
content_sid="HXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
content_variables='{"1": "March 25", "2": "2:00 PM"}'
)
Node.js
const message = await client.messages.create({
from: "whatsapp:+14155238886",
to: "whatsapp:+15005550006",
contentSid: "HXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
contentVariables: JSON.stringify({ "1": "March 25", "2": "2:00 PM" }),
});
Max file size: 16 MB.
Python
message = client.messages.create(
from_="whatsapp:+14155238886",
to="whatsapp:+15005550006",
body="Here is your invoice.",
media_url=["https://example.com/invoice.pdf"]
)
Node.js
const message = await client.messages.create({
from: "whatsapp:+14155238886",
to: "whatsapp:+15005550006",
body: "Here is your invoice.",
mediaUrl: ["https://example.com/invoice.pdf"],
});
| Field | Description |
|-------|-------------|
| sid | Unique message identifier (MM...) |
| status | queued, sent, delivered, read, failed, undelivered |
| error_code | Populated on failure |
| error_message | Human-readable error description |
| date_sent | UTC timestamp |
| Code | Meaning | Fix | |------|---------|-----| | 63003 | Invalid WhatsApp destination number | Verify number is WhatsApp-enabled and correctly formatted | | 63018 | Rate limit exceeded on sender | Reduce send rate; default is 80 MPS | | 63020 | Business hasn't accepted Twilio's Meta invitation | Accept invite in Meta Business Manager | | N/A | Free-form outside window | Switch to a template message |
twilio-messaging-overviewtwilio-whatsapp-manage-senderstwilio-content-template-buildertwilio-conversations-apitools
Top-level workflow skill for USD performance diagnosis and optimization. Use for slow loading, high memory, low FPS, or 'optimize my scene' requests; delegates auth/runtime setup to Phase 0 owners.
data-ai
Use when the user mentions MagicPath, designs, UI components, themes, canvas selections, or repo-to-canvas UI work; run magicpath-ai to search, inspect, install, or author components.
documentation
Use as the top-level router for Omniverse Realtime Viewer USD app requests and focused viewer reference documents.
tools
Turn Notion specs into implementation plans, tasks, and progress tracking; use when implementing PRDs/feature specs and creating Notion plans + tasks from them.