plugins/twilio-developer-kit/skills/twilio/twilio-email-send/SKILL.md
Use when the caller has Twilio credentials (Account SID + Auth Token or API Key SID + Secret) and needs to send email via comms.twilio.com/v1/Emails. This is Twilio-native email — NOT SendGrid. Do NOT use if the caller has a SendGrid API key (SG.-prefix) — use twilio-sendgrid-email-send instead. Covers single sends, batch sends up to 10,000 recipients, Liquid personalization, operation tracking, and error handling.
npx skillsauth add openai/plugins twilio-email-sendInstall 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.
Agent safety: Always confirm recipients, subject, and content with the user before sending. Email is irreversible once delivered. Never send email autonomously without explicit user approval — especially for batch sends to multiple recipients.
Twilio Email is a separate product from SendGrid. Both send email, but they use different APIs, credentials, templating languages, and endpoints. If you have a SendGrid API key (SG.-prefix), use twilio-sendgrid-email-send instead.
| | Twilio Email (this skill) | SendGrid |
|---|---|---|
| Base URL | https://comms.twilio.com/v1/emails | https://api.sendgrid.com/v3/mail/send |
| Auth | Twilio Account SID + Auth Token (or API Key SID + Secret) | SendGrid API key (SG.-prefix) |
| Templating | Liquid ({{variable}}) | Handlebars ({{variable}}) |
| Max recipients/request | 10,000 | 1,000 |
| Max message size | 10MB (including attachments) | 30MB |
| Status tracking | Operation resource (poll operationLocation) | Event Webhooks (async POST) |
| Console | console.twilio.com | app.sendgrid.com |
twilio-account-setup for signup and credentialsfrom address domainFor a complete setup guide, see the Email Onboarding guide in the Twilio console.
The API uses Basic Authentication with either:
These are standard Twilio credentials — the same ones used for SMS, Voice, and other Twilio APIs.
POST https://comms.twilio.com/v1/Emails
The endpoint is asynchronous — it returns 202 Accepted with an operationId, not a delivery confirmation.
curl -X POST "https://comms.twilio.com/v1/Emails" \
--header "Content-Type: application/json" \
--data '{
"from": {
"address": "[email protected]",
"name": "Support Team"
},
"to": [
{
"address": "[email protected]",
"name": "John Doe"
}
],
"content": {
"subject": "Your subject line",
"html": "<p>Your message content in HTML format.</p>",
"text": "Your message content in plain text."
}
}' \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
Response (202 Accepted):
{
"operationId": "...",
"operationLocation": "https://comms.twilio.com/v1/Emails/Operations/..."
}
Poll operationLocation to track delivery status.
Send the same message to multiple recipients in a single request by adding entries to the to array. Maximum 10,000 recipients per request.
{
"from": {
"address": "[email protected]",
"name": "Support Team"
},
"to": [
{
"address": "[email protected]",
"name": "John Doe"
},
{
"address": "[email protected]",
"name": "Jane Smith"
}
],
"content": {
"subject": "Your subject line",
"html": "<p>Your message content in HTML format.</p>",
"text": "Your message content in plain text."
}
}
Use Liquid templating in the content.subject, content.html, and content.text fields. For each variable referenced (e.g. {{firstName}}), provide a matching key in the variables object for every recipient in the to array.
{
"from": {
"address": "[email protected]",
"name": "Support Team"
},
"to": [
{
"address": "[email protected]",
"name": "Alice",
"variables": {"firstName": "Alice", "orderId": "123"}
},
{
"address": "[email protected]",
"name": "Bob",
"variables": {"firstName": "Bob", "orderId": "456"}
}
],
"content": {
"subject": "Hi {{firstName}}, your order update",
"html": "<p>Hi {{firstName}}, order #{{orderId}} has shipped.</p>",
"text": "Hi {{firstName}}, order #{{orderId}} has shipped."
}
}
Ensure every recipient has all referenced variables defined.
After submitting a send, use the Operation resource to monitor batch status.
POST /v1/emails — response includes operationId and operationLocationGET to the operationLocation URIThis is especially important for large recipient lists where processing is not instantaneous.
| Status Code | Description | Action |
|-------------|-------------|--------|
| 202 | Accepted | Request accepted, Operation created. Poll operationLocation for status. |
| 400 | Bad Request | Malformed or ambiguous request content. Check JSON payload. |
| 401 | Unauthorized | Verify Account SID and Auth Token / API Key are correct. |
| 429 | Too Many Requests | Rate limited. Back off and retry. |
| 500 | Internal Server Error | Twilio server-side issue. Retry with backoff. |
| 503 | Service Unavailable | Temporarily unavailable. Retry after a short delay. |
Validation errors return as many issues as possible in a single response to help debug quickly.
SG.-prefix keys do not work. Use twilio-sendgrid-email-send for SendGrid.from field — Unicode encoding is not supported for sender addresses.{{#if}} or {{#each}}, that's Handlebars/SendGrid syntax.202 Accepted means queued, not delivered. Poll the Operation resource for status.twilio-account-setuptwilio-sendgrid-email-sendtwilio-sms-send-messagedevelopment
Use when the user wants to spin up / create / launch / provision a DigitalOcean droplet (or "a remote dev box on DO") and connect to it from Codex as a remote SSH workspace.
data-ai
Search through Microsoft Teams chats or channels, triage unread or recent activity, draft follow-ups, and manage Planner tasks through connected Teams data.
tools
Motion / animation context for the `use_figma` MCP tool — animating Figma nodes via manual keyframes, animation styles, easing, and timeline duration. Load alongside figma-use whenever a task involves adding, editing, or inspecting animation on a node.
development
SwiftUI ↔ Figma translation. Use whenever the user mentions Swift, SwiftUI, iOS, iPhone, or iPad — in EITHER direction — translating a Figma design into SwiftUI (design → code), or pushing SwiftUI views / screens / tokens back into a Figma file (code → design). Triggers on phrases like 'implement this Figma design in SwiftUI', 'build this screen in Swift', 'push this SwiftUI view to Figma', 'mirror my Swift code in a Figma file', or whenever a Figma URL appears alongside `.swift` files / an `.xcodeproj`. Routes to a direction-specific reference doc; loads alongside `figma-use` for the code → design path.