Send transactional emails through Zyphr's email API, powered by AWS SES with built-in deliverability features. You can send emails via the API and manage email configuration through the Dashboard.
Features
- High Deliverability - Automatic domain verification, DKIM signing, and reputation management
- Rich Content - HTML and plain text support with inline attachments
- Templates - Reusable templates with Handlebars variable interpolation
- Tracking - Open and click tracking with real-time webhooks
- Batch Sending - Send up to 100 emails per request
Quick Start
Send a Simple Email
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"from": "hello@yourapp.com",
"subject": "Welcome!",
"html": "<h1>Welcome to our app!</h1><p>Thanks for signing up.</p>"
}'
Using Node.js SDK
import { Zyphr } from '@zyphr-dev/node-sdk';
const zyphr = new Zyphr({ apiKey: process.env.ZYPHR_API_KEY });
const email = await zyphr.emails.send({
to: 'user@example.com',
from: 'hello@yourapp.com',
subject: 'Welcome!',
html: '<h1>Welcome!</h1>',
text: 'Welcome!', // Plain text fallback
});
console.log(`Email sent: ${email.id}`);
Email Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Recipient email address |
from | string | No | Sender email (defaults to workspace default) |
subject | string | Yes | Email subject line |
html | string | Conditional | HTML body (required if no template_id) |
text | string | No | Plain text fallback |
reply_to | string | No | Reply-to address |
cc | string[] | No | CC recipients |
bcc | string[] | No | BCC recipients |
headers | object | No | Custom email headers |
attachments | object[] | No | File attachments |
tags | string[] | No | Tags for filtering/analytics |
metadata | object | No | Custom metadata |
template_id | string | No | Template to use |
template_data | object | No | Variables for template |
Using Templates
Create reusable templates in the Dashboard or via the API, then reference them when sending:
Via Dashboard
- Navigate to Templates in the sidebar
- Click Create Template, design your email, and save
- Use the template name when sending via the API
Via API
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"template_id": "welcome-email",
"template_data": {
"name": "John",
"action_url": "https://yourapp.com/activate"
}
}'
await zyphr.emails.send({
to: 'user@example.com',
template_id: 'welcome-email',
template_data: {
name: 'John',
action_url: 'https://yourapp.com/activate',
},
});
See Templates for more details.
Viewing Messages
Via Dashboard
- Navigate to Messages in the sidebar
- Browse all sent emails with filters for status, date range, and recipient
- Click on any message to view its full content, delivery timeline, and tracking data
Via API
# List emails with filters
curl "https://api.zyphr.dev/v1/emails?status=delivered&page=1&per_page=25" \
-H "X-API-Key: zy_live_your_key"
# Get a specific email's details
curl https://api.zyphr.dev/v1/emails/EMAIL_ID \
-H "X-API-Key: zy_live_your_key"
# Get delivery events for an email
curl -X POST https://api.zyphr.dev/v1/emails/EMAIL_ID/events \
-H "X-API-Key: zy_live_your_key"
# Get tracking stats (opens, clicks)
curl -X POST https://api.zyphr.dev/v1/emails/EMAIL_ID/tracking \
-H "X-API-Key: zy_live_your_key"
Attachments
Add file attachments to your emails:
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Your Invoice",
"html": "<p>Please find your invoice attached.</p>",
"attachments": [
{
"filename": "invoice.pdf",
"content": "base64_encoded_content_here",
"content_type": "application/pdf"
}
]
}'
await zyphr.emails.send({
to: 'user@example.com',
subject: 'Your Invoice',
html: '<p>Please find your invoice attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: base64EncodedContent,
content_type: 'application/pdf',
},
],
});
- Maximum total attachment size: 10MB
- Supported content types: PDF, images, text files, etc.
Batch Sending
Send to multiple recipients in a single request:
curl -X POST https://api.zyphr.dev/v1/emails/batch \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "to": "user1@example.com", "subject": "Hello", "html": "<p>Hi User 1!</p>" },
{ "to": "user2@example.com", "subject": "Hello", "html": "<p>Hi User 2!</p>" }
]
}'
const result = await zyphr.emails.sendBatch({
messages: [
{ to: 'user1@example.com', subject: 'Hello', html: '<p>Hi User 1!</p>' },
{ to: 'user2@example.com', subject: 'Hello', html: '<p>Hi User 2!</p>' },
// ... up to 100 messages
],
});
console.log(`Sent: ${result.succeeded}, Failed: ${result.failed}`);
Domain Verification
Before sending production emails, verify your domain. You can do this through the Dashboard or API:
Via Dashboard
- Navigate to Domains in the sidebar
- Click Add Domain and enter your sending domain
- Add the displayed DNS records to your DNS provider
- Click Verify once records have propagated
Via API
# Add a domain
curl -X POST https://api.zyphr.dev/v1/domains \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{ "domain": "notifications.yourapp.com" }'
# Trigger verification
curl -X POST https://api.zyphr.dev/v1/domains/DOMAIN_ID/check \
-H "X-API-Key: zy_live_your_key"
See Domain Verification for detailed instructions.
Tracking
Configuring Tracking
Via Dashboard
- Navigate to Settings → Workspace tab
- Toggle Track Opens and Track Clicks on or off
- These settings apply workspace-wide as defaults
Per-Email Override
Override workspace defaults on individual emails:
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Newsletter",
"html": "<p>Content here</p>",
"track_opens": true,
"track_clicks": true
}'
Open Tracking
When enabled, an invisible tracking pixel is inserted into your HTML emails.
Click Tracking
When enabled, links in your email are rewritten to track clicks before redirecting to the original URL.
Email Provider Configuration
Via Dashboard
- Navigate to Providers in the sidebar
- Click Add Provider to configure your email provider (e.g., AWS SES)
- Enter the required credentials
- Configure fallback order if you have multiple providers
- Monitor provider health from the Providers page
Via API
# Set email provider config
curl -X POST https://api.zyphr.dev/v1/providers/email_provider/config \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "ses",
"credentials": { ... }
}'
Email Status
Emails progress through these statuses:
| Status | Description |
|---|---|
queued | Email accepted and queued for sending |
sending | Being processed by the mail server |
sent | Accepted by recipient's mail server |
delivered | Confirmed delivery (when available) |
bounced | Rejected by recipient's mail server |
complained | Marked as spam by recipient |
failed | Permanent failure |
Deliverability Monitoring
Via Dashboard
Navigate to Deliverability in the sidebar to view:
- Overall sending status (Active/Throttled/Frozen)
- Reputation score
- Bounce and complaint rates
- Reputation events timeline
This is a read-only dashboard — deliverability metrics are automatically tracked based on your sending activity.
Webhooks
Receive real-time notifications for email events:
{
"event": "email.delivered",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"message_id": "msg_abc123",
"to": "user@example.com",
"status": "delivered"
}
}
See Webhooks for setup instructions.
Error Handling
Common error responses:
{
"error": {
"code": "domain_not_verified",
"message": "The sending domain is not verified. Please verify your domain first."
}
}
| Error Code | Description | Solution |
|---|---|---|
domain_not_verified | Sending domain not verified | Verify your domain in Dashboard → Domains |
suppressed_recipient | Recipient on suppression list | Remove from suppression list (Dashboard or API) |
invalid_email | Malformed email address | Fix the email format |
rate_limited | Too many requests | Slow down and retry |