Send Email with SendGrid
Overview
SendGrid provides a single Mail Send endpoint for sending email via the v3 API. The Node SDK (@sendgrid/mail) is the recommended integration for JavaScript/TypeScript.
Use this skill when:
- Sending transactional emails (welcome, password reset, receipts)
- Sending simple notifications
- You need basic text/HTML emails with optional attachments
- Using dynamic templates for personalized content
Quick Start
Test Your Configuration First
# Validate API key and send test email
../scripts/send-test-email.sh recipient@example.com
Then integrate:
- Detect project language (package.json, requirements.txt, go.mod, etc.)
- Install SDK (preferred) or use cURL - See references/installation.md
- Prepare message with
from, to, subject, and text or html
- Send and handle errors (retry on 429/5xx)
Required Parameters
| Parameter |
Type |
Description |
from |
string |
Sender email (must be verified) |
to |
string or string[] |
Recipient email(s) |
subject |
string |
Email subject |
text or html |
string |
Email body content |
Optional Parameters
| Parameter |
Type |
Description |
cc |
string or string[] |
CC recipients |
bcc |
string or string[] |
BCC recipients |
reply_to |
string |
Reply-to address |
attachments |
array |
Base64-encoded attachments |
template_id |
string |
Dynamic template ID (if using templates) |
dynamic_template_data |
object |
Template data (if using templates) |
Minimal Example (Node.js)
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
await sgMail.send({
from: 'Support <support@winkintel.com>',
to: 'vince@winkintel.com',
subject: 'Hello from SendGrid',
text: 'This is a test email.',
html: '<p>This is a test email.</p>',
});
Templates (Dynamic Templates)
If using SendGrid Dynamic Templates, supply template_id and dynamic_template_data instead of html/text.
await sgMail.send({
from: 'Support <support@winkintel.com>',
to: 'vince@winkintel.com',
templateId: 'd-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
dynamicTemplateData: { first_name: 'Vince' },
});
Decision: Plain Send vs Dynamic Templates?
How complex is your email?
├─ Simple, one-off message
│ └─ Plain send (html/text) ✅
├─ Reusable design with variables
│ └─ Dynamic Template ✅
└─ Personalized at scale
└─ Dynamic Template with merge tags ✅
Use plain send when:
- Quick, simple messages
- Content changes every time
- No design reusability needed
Use dynamic templates when:
- Consistent design across emails
- Variable substitution (names, dates, etc.)
- Non-technical teams manage email content
- A/B testing email designs
Troubleshooting
"401 Unauthorized":
- API key invalid or missing
- Check
SENDGRID_API_KEY environment variable
- Verify key has mail send permissions
"403 Forbidden":
- Sender email not verified
- Go to SendGrid Console → Settings → Sender Authentication
- Verify single sender or authenticate domain
"429 Too Many Requests":
- Rate limit exceeded
- Implement exponential backoff (retry after 1s, 2s, 4s...)
- Consider upgrading SendGrid plan
"500/503 Service Errors":
- SendGrid temporary service issue
- Retry with exponential backoff
- Check SendGrid status page
Emails not arriving:
- Check recipient spam folder
- Verify sender domain authentication (SPF/DKIM)
- Use both
text and html for better deliverability
- Avoid spam trigger words in subject/body
Best Practices (Short)
- Always set both
text and html when possible (deliverability + accessibility).
- Retry only on 429 or 5xx errors with exponential backoff.
- Use verified senders; unverified domains will fail.
- Avoid fake addresses at real providers; test with addresses you control.
For deeper details, see:
- references/best-practices.md
- references/single-email-examples.md
Automation Scripts
Quick testing:
scripts/send-test-email.sh - Send plain text test email (API key validation)
scripts/send-html-email.sh - Send HTML email (newsletters, reports, formatted content)
See scripts/README.md for usage examples.
Related Skills
Receiving email responses:
- See
sendgrid-inbound for handling incoming emails via Inbound Parse Webhook
- Common use case: Auto-reply systems, support ticket creation from email
1---2name: send-email-43description: Send transactional emails and notifications via SendGrid v3 Mail Send API. Supports simple emails, HTML/text content, attachments, CC/BCC, dynamic templates, and personalization. Use when sending welcome emails, password resets, receipts, notifications, or any programmatic email. Triggers on send email, transactional email, SendGrid send, email notification, welcome email, password reset email, email template, dynamic template.4---56# Send Email with SendGrid78## Overview910SendGrid provides a single **Mail Send** endpoint for sending email via the v3 API. The Node SDK (`@sendgrid/mail`) is the recommended integration for JavaScript/TypeScript.1112**Use this skill when:**13- Sending transactional emails (welcome, password reset, receipts)14- Sending simple notifications15- You need basic text/HTML emails with optional attachments16- Using dynamic templates for personalized content1718## Quick Start1920### Test Your Configuration First21```bash22# Validate API key and send test email23../scripts/send-test-email.sh recipient@example.com24```2526**Then integrate:**27281. **Detect project language** (package.json, requirements.txt, go.mod, etc.)292. **Install SDK** (preferred) or use cURL - See [references/installation.md](references/installation.md)303. **Prepare message** with `from`, `to`, `subject`, and `text` or `html`314. **Send and handle errors** (retry on 429/5xx)3233## Required Parameters3435| Parameter | Type | Description |36|----------|------|-------------|37| `from` | string | Sender email (must be verified) |38| `to` | string or string[] | Recipient email(s) |39| `subject` | string | Email subject |40| `text` or `html` | string | Email body content |4142## Optional Parameters4344| Parameter | Type | Description |45|----------|------|-------------|46| `cc` | string or string[] | CC recipients |47| `bcc` | string or string[] | BCC recipients |48| `reply_to` | string | Reply-to address |49| `attachments` | array | Base64-encoded attachments |50| `template_id` | string | Dynamic template ID (if using templates) |51| `dynamic_template_data` | object | Template data (if using templates) |5253## Minimal Example (Node.js)5455```ts56import sgMail from '@sendgrid/mail';5758sgMail.setApiKey(process.env.SENDGRID_API_KEY!);5960await sgMail.send({61 from: 'Support <support@winkintel.com>',62 to: 'vince@winkintel.com',63 subject: 'Hello from SendGrid',64 text: 'This is a test email.',65 html: '<p>This is a test email.</p>',66});67```6869## Templates (Dynamic Templates)7071If using SendGrid Dynamic Templates, supply `template_id` and `dynamic_template_data` instead of `html`/`text`.7273```ts74await sgMail.send({75 from: 'Support <support@winkintel.com>',76 to: 'vince@winkintel.com',77 templateId: 'd-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',78 dynamicTemplateData: { first_name: 'Vince' },79});80```8182## Decision: Plain Send vs Dynamic Templates?8384```85How complex is your email?86├─ Simple, one-off message87│ └─ Plain send (html/text) ✅88├─ Reusable design with variables89│ └─ Dynamic Template ✅90└─ Personalized at scale91 └─ Dynamic Template with merge tags ✅92```9394**Use plain send when:**95- Quick, simple messages96- Content changes every time97- No design reusability needed9899**Use dynamic templates when:**100- Consistent design across emails101- Variable substitution (names, dates, etc.)102- Non-technical teams manage email content103- A/B testing email designs104105## Troubleshooting106107**"401 Unauthorized":**108- API key invalid or missing109- Check `SENDGRID_API_KEY` environment variable110- Verify key has mail send permissions111112**"403 Forbidden":**113- Sender email not verified114- Go to SendGrid Console → Settings → Sender Authentication115- Verify single sender or authenticate domain116117**"429 Too Many Requests":**118- Rate limit exceeded119- Implement exponential backoff (retry after 1s, 2s, 4s...)120- Consider upgrading SendGrid plan121122**"500/503 Service Errors":**123- SendGrid temporary service issue124- Retry with exponential backoff125- Check SendGrid status page126127**Emails not arriving:**128- Check recipient spam folder129- Verify sender domain authentication (SPF/DKIM)130- Use both `text` and `html` for better deliverability131- Avoid spam trigger words in subject/body132133## Best Practices (Short)134135- Always set **both** `text` and `html` when possible (deliverability + accessibility).136- Retry **only** on 429 or 5xx errors with exponential backoff.137- Use verified senders; unverified domains will fail.138- Avoid fake addresses at real providers; test with addresses you control.139140For deeper details, see:141- [references/best-practices.md](references/best-practices.md)142- [references/single-email-examples.md](references/single-email-examples.md)143144## Automation Scripts145146**Quick testing:**147- `scripts/send-test-email.sh` - Send plain text test email (API key validation)148- `scripts/send-html-email.sh` - Send HTML email (newsletters, reports, formatted content)149150See [scripts/README.md](../scripts/README.md) for usage examples.151152## Related Skills153154**Receiving email responses:**155- See `sendgrid-inbound` for handling incoming emails via Inbound Parse Webhook156- Common use case: Auto-reply systems, support ticket creation from email