From twilio-developer-kit
Sends transactional and bulk email via SendGrid v3 Mail Send API. Covers single sends, personalized batch sends with dynamic templates, scheduled sends, attachments, and sandbox mode.
How this skill is triggered — by the user, by Claude, or both
Slash command
/twilio-developer-kit:twilio-sendgrid-email-sendThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **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.
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.
All email sending goes through POST /v3/mail/send. This endpoint returns 202 Accepted (queued) — NOT 200 OK (delivered). Delivery confirmation comes asynchronously via Event Webhook. See twilio-sendgrid-webhooks.
Python
import os, sendgrid
from sendgrid.helpers.mail import Mail
sg = sendgrid.SendGridAPIClient(os.environ["SENDGRID_API_KEY"])
message = Mail(
from_email="[email protected]",
to_emails="[email protected]",
subject="Order Confirmation",
html_content="<p>Your order #1234 is confirmed.</p>"
)
response = sg.send(message)
print(f"Status: {response.status_code}") # 202 = queued
Node.js
const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const [response] = await sgMail.send({
to: "[email protected]",
from: "[email protected]",
subject: "Order Confirmation",
html: "<p>Your order #1234 is confirmed.</p>",
});
console.log(`Status: ${response.statusCode}`); // 202 = queued
Dynamic templates use Handlebars syntax. Template IDs start with d-. Create templates in SendGrid Console > Email API > Dynamic Templates.
Python
from sendgrid.helpers.mail import Mail, To
message = Mail(
from_email="[email protected]",
to_emails=[
To("[email protected]", dynamic_template_data={"name": "Alice", "order_id": "123"}),
To("[email protected]", dynamic_template_data={"name": "Bob", "order_id": "456"}),
],
)
message.template_id = "d-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
sg.send(message)
Node.js
await sgMail.send({
from: { email: "[email protected]" },
template_id: "d-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
personalizations: [
{ to: [{ email: "[email protected]" }], dynamic_template_data: { name: "Alice", order_id: "123" } },
{ to: [{ email: "[email protected]" }], dynamic_template_data: { name: "Bob", order_id: "456" } },
],
});
Recipients in the same to array within a single personalization can see each other. For private sends, use separate personalizations (one per recipient).
Schedule up to 72 hours in advance. Cancellation requires a batch ID assigned before sending.
Python
import time, requests
headers = {"Authorization": f"Bearer {os.environ['SENDGRID_API_KEY']}", "Content-Type": "application/json"}
# Get batch ID first
batch = requests.post("https://api.sendgrid.com/v3/mail/batch", headers=headers).json()
# Include batch_id and send_at in the message
send_at = int(time.time()) + 3600 # Unix SECONDS, not ms
# Cancel if needed (before send_at)
requests.post("https://api.sendgrid.com/v3/user/scheduled_sends",
headers=headers,
json={"batch_id": batch["batch_id"], "status": "cancel"})
Base64-encode files in the attachments array. Total limit: 30MB per request (~22MB before encoding overhead).
import base64
from sendgrid.helpers.mail import Mail, Attachment, FileContent, FileName, FileType, Disposition
with open("invoice.pdf", "rb") as f:
encoded = base64.b64encode(f.read()).decode()
message = Mail(from_email="[email protected]", to_emails="[email protected]",
subject="Your Invoice", html_content="<p>Invoice attached.</p>")
message.attachment = Attachment(FileContent(encoded), FileName("invoice.pdf"),
FileType("application/pdf"), Disposition("attachment"))
sg.send(message)
Categories tag sends for analytics segmentation (up to 10 per message):
message.category = ["transactional", "order-confirmation"]
Custom Args pass metadata through to Event Webhooks (key-value strings only):
message.custom_args = {"order_id": "1234", "env": "production"}
These appear in webhook event payloads, enabling you to correlate delivery events back to your application data.
Validates the request without delivering. Returns 200 OK (not 202).
message.mail_settings = {"sandbox_mode": {"enable": True}}
response = sg.send(message) # 200 = validated, not sent
send_at rejects timestamps beyond 72h.send_at with milliseconds — JS Date.now() returns ms. Divide by 1000 or the timestamp is silently rejected (>72h).subject field in personalizations is a plain string override — To use dynamic subjects, set Handlebars variables (e.g., {{{subject}}}) in the Dynamic Template's subject field and pass values via dynamic_template_data. The personalizations subject key bypasses the template subject entirely.dynamic_template_data keys. Silent failures.413 Payload Too Large returns nginx HTML, not JSON — Exceeding 30MB returns HTML error page. Check Content-Type before parsing.content when using template_id — Omit the content field. If you include both, template_id takes precedence and content is ignored.Agent usage: When sending email on behalf of a user, always report back what was sent — recipients, subject, and the API response status code. Maintain an application-level audit log for all sends.
twilio-sendgrid-account-setuptwilio-sendgrid-email-settingstwilio-sendgrid-webhookstwilio-sendgrid-suppressionsnpx claudepluginhub twilio/ai --plugin twilio-developer-kitGuides on using the Resend email API for sending transactional emails, managing webhooks, templates, domains, contacts, broadcasts, and tracking delivery events. Includes essential gotchas for idempotency keys and webhook verification.
Sends email via Twilio's native Email API (comms.twilio.com/v1/Emails) with support for batch sends up to 10,000 recipients, Liquid personalization, and operation tracking.
Guides effective email strategy covering transactional vs marketing separation, deliverability infrastructure (SPF/DKIM/DMARC), permission practices, and automation patterns with queuing and event tracking.