API Documentation

Send transactional emails with a simple REST API. Get started in minutes.

Quickstart

  1. Create an account at devsmtp.com/login
  2. Generate an API key from your Dashboard
  3. Add your domain and configure the DNS records
  4. Send your first email using the API

Authentication

All API requests require authentication using a Bearer token in the Authorization header.

Authorization: Bearer YOUR_API_KEY

Keep your API key secret. Never expose it in client-side code or public repositories.

Domain Setup

Add your domain and configure DNS records to start sending emails.

Adding a Domain
  1. Go to Domains in the dashboard
  2. Click Add Domain
  3. Enter your domain name (e.g., mail.yourdomain.com)
  4. We'll register your domain with AWS SES and generate DNS records
Best Practice: Use a Subdomain

We recommend sending transactional emails from a subdomain like mail.yourdomain.com or send.yourdomain.com instead of your root domain.

Why use a subdomain?

  • Reputation isolation: If issues occur, your main domain's reputation stays protected
  • Easier recovery: A subdomain can be replaced if it gets blacklisted
  • Separation of concerns: Keep transactional emails separate from marketing

Example: Instead of hello@yourdomain.com, send from hello@mail.yourdomain.com

DNS Configuration
Add CNAME records to verify your domain

After adding a domain, click View DNS to see the required records. Add these CNAME records to your domain registrar:

Cloudflare

  1. Go to your domain → DNS
  2. Click Add record
  3. Type: CNAME
  4. Copy Name and Target from DevSMTP
  5. Important: Turn OFF the proxy (grey cloud)

GoDaddy

  1. Go to My Products → Your domain → DNS
  2. Scroll to Records and click Add
  3. Type: CNAME
  4. Enter Host and Points to values from DevSMTP

Fasthosts

  1. Log into your control panel
  2. Select your domain → DNS Settings
  3. Click Add RecordCNAME
  4. Copy Name and Value from DevSMTP
  5. Repeat for all 3 DKIM records

DNS changes can take up to 48 hours to propagate, but usually complete within 1-2 hours. Click the refresh button on your domain to check verification status.

SPF & DMARC Records
Required for optimal email deliverability

In addition to DKIM (the 3 CNAME records), you should also configure SPF and DMARC records to maximize deliverability.

SPF Record (TXT)

SPF tells receiving servers which mail servers are authorized to send email for your domain.

v=spf1 include:amazonses.com ~all

If you already have an SPF record, add include:amazonses.com before the ~all

DMARC Record (TXT)

DMARC builds trust with mailbox providers by telling them what to do with emails that fail authentication.

Host: _dmarc
Value: v=DMARC1; p=none;

Start with p=none for monitoring. Once verified, consider p=quarantine or p=reject for stronger protection.

⚠️ Important: Without SPF, some email providers may mark your emails as spam. Click View DNS on your domain to see all required records with copy buttons.

Warm-up & Sending Limits

New domains start with low sending limits that automatically increase over time to build sender reputation.

Warm-up Schedule
Daily limits increase automatically as your domain ages
Time PeriodDaily Limit
Week 1 (Days 1-7)50 emails/day
Week 2 (Days 8-14)100 emails/day
Week 3 (Days 15-21)200 emails/day
Week 4 (Days 22-30)500 emails/day
Month 2 (Days 31-60)1,000 emails/day
After 60 days5,000 emails/day

Limits reset at midnight UTC each day. Check the remaining field in API responses to track usage.

Notification Emails
Receive copies of sent emails without changing your code

DevSMTP is designed for single-recipient transactional emails. To receive copies of sent emails:

  • Global: Set one email in Settings to receive a copy of every email sent from any domain.
  • Per-Domain: Set up to 3 emails per domain to receive copies only for that project.

Copies are sent via BCC — no code changes required.

Send Email

POST/api/send

Request Body

FieldTypeRequiredDescription
tostringRecipient email address
fromstringSender email (must be verified domain)
subjectstringEmail subject line
htmlstring*HTML email body
textstring*Plain text email body

* At least one of html or text is required

💡 Transactional Only: DevSMTP is designed for single-recipient transactional emails (welcome emails, password resets, notifications). Need to receive copies? Configure notification emails in Settings - no code changes needed.

Example Request

{
  "to": "user@example.com",
  "from": "hello@yourdomain.com",
  "subject": "Welcome to our service!",
  "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
  "text": "Welcome! Thanks for signing up."
}

Example Response

{
  "success": true,
  "messageId": "01234567-89ab-cdef-0123-456789abcdef",
  "remaining": 49
}

Test Mode

Test your email integration without sending real emails. Use special test addresses to simulate different delivery scenarios.

Test Email Addresses
Send to these addresses to simulate different scenarios
AddressSimulates
delivered@devsmtp.devSuccessful delivery
bounced@devsmtp.devBounced email
complained@devsmtp.devSpam complaint

🧪 No real emails sent: Test emails are logged but never actually sent. They don't count against your daily limits.

Example: Testing with cURL
curl -X POST https://devsmtp.com/api/v1/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "delivered@devsmtp.dev",
    "from": "hello@yourdomain.com",
    "subject": "Test Email",
    "html": "<h1>Testing!</h1>"
  }'

Test Mode Response

{
  "success": true,
  "test": true,
  "simulated_status": "sent",
  "message": "Test email simulated with status: sent. No actual email was sent.",
  "eventId": "test_abc123-def456-..."
}
Testing with MCP
Use your AI assistant to test emails
You:"Send a test email to delivered@devsmtp.dev from hello@mydomain.com"
AI:🧪 Test email simulated! Status: sent. No actual email was sent.
You:"Now test a bounce scenario"
AI:🧪 Test email simulated! Status: bounced. No actual email was sent.

Test emails appear in your logs with a "test" indicator so you can distinguish them from real sends.

Best Practices
  • Use test addresses in CI/CD pipelines to validate email integration without sending
  • Test all three scenarios (delivered, bounced, complained) to ensure your app handles each correctly
  • Check the test: true field in responses to detect test mode
  • Your from address must still be from a verified domain

Response Codes

CodeDescription
200Email sent successfully
400Bad request - check your request body
401Unauthorized - invalid or missing API key
403Forbidden - domain not verified or not owned
429Too many requests - daily limit exceeded
500Server error - try again later

SDKs

Official SDKs for Node.js and PHP. Install via your package manager and start sending emails with just a few lines of code.

Installation
npm install @devsmtp/sdk
Quick Start
import DevSMTP from '@devsmtp/sdk';

const devsmtp = new DevSMTP('your-api-key');

// Send an email
const result = await devsmtp.send({
  to: 'user@example.com',
  from: 'hello@mail.yourdomain.com',
  subject: 'Welcome!',
  html: '<h1>Hello World</h1>'
});

console.log(result.eventId);
Available Methods
MethodDescription
send(options)Send a transactional email
validate(email)Validate an email address
getStatus()Get API usage and limits
getDomains()List verified domains
getLogs(options?)Get recent email logs
Error Handling
import DevSMTP, { DevSMTPError } from '@devsmtp/sdk';

try {
  await devsmtp.send({ ... });
} catch (error) {
  if (error instanceof DevSMTPError) {
    console.error(`Error ${error.statusCode}: ${error.message}`);
  }
}

Code Examples

Quick examples for sending emails without using an SDK.

curl -X POST https://devsmtp.com/api/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "user@example.com",
    "from": "hello@yourdomain.com",
    "subject": "Hello!",
    "html": "<h1>Hello World</h1>"
  }'

Webhooks

Receive real-time notifications when emails bounce or recipients mark them as spam. Configure your webhook URL in the Dashboard settings.

Webhook Events
Events sent to your configured webhook URL
EventDescription
bounceEmail could not be delivered (invalid address, mailbox full, etc.)
complaintRecipient marked the email as spam
Bounce Event Payload
{
  "event": "bounce",
  "email": "user@example.com",
  "bounce_type": "Permanent",
  "bounce_subtype": "General",
  "timestamp": "2026-01-22T11:24:00Z",
  "message_id": "01234567-89ab-cdef-0123-456789abcdef"
}
Bounce TypeDescription
PermanentHard bounce - remove this address from your list
TransientSoft bounce - temporary issue, may succeed later
Complaint Event Payload
{
  "event": "complaint",
  "email": "user@example.com",
  "complaint_type": "abuse",
  "timestamp": "2026-01-22T11:24:00Z",
  "message_id": "01234567-89ab-cdef-0123-456789abcdef"
}

⚠️ Important: When you receive a complaint, immediately stop sending to that address. High complaint rates can affect your sending reputation.

Verifying Webhook Signatures
Ensure webhooks are from DevSMTP

If you configure a webhook secret in your settings, we'll sign each request with an HMAC-SHA256 signature in the X-DevSMTP-Signature header.

// Node.js example
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return signature === expected;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-devsmtp-signature'];
  
  if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook...
});

Blocklist Monitoring

We automatically monitor your verified domains against major email blocklists and alert you if any issues are detected.

Monitored Blocklists
Your domains are checked against these blocklists every 6 hours
BlocklistType
Spamhaus ZENIP
Spamhaus DBLDomain
BarracudaIP
SpamCopIP
SORBSIP
UCEPROTECT L1IP
Dashboard Features
Monitor your blocklist status from the dashboard
  • Shield icons: Each domain shows a shield icon — green if clear, red if listed on any blocklist
  • Last Checked: See when each domain was last scanned
  • Check Now: Click the shield to view details and trigger an immediate scan
  • Alert banner: A warning banner appears on your dashboard if any domain is listed
Email Alerts
Get notified when your domain status changes

We send daily email alerts at 9am UTC if any of your domains have been listed or delisted from a blocklist.

Alert emails are sent to:

  1. Domain-specific emails — if configured in Settings
  2. Global notification email — if no domain-specific emails are set
  3. Your account email — as a fallback

💡 Tip: Configure notification emails in Settings to ensure the right people receive blocklist alerts.

What to Do If Listed
  1. Click the shield icon on the affected domain to see which blocklist(s)
  2. Click the Remove link to visit the blocklist's removal request page
  3. Follow their instructions to request delisting
  4. Most blocklists process removal requests within 24-48 hours
  5. We'll automatically detect when you're delisted and update your status

Being listed on a blocklist can affect email deliverability. Using a subdomain for transactional emails helps isolate any reputation issues.

AI Integration (MCP Server)

Test emails and check logs directly from your AI coding assistant. Works with Windsurf, Cursor, Claude Desktop, and any MCP-compatible tool.

🤖 Developer-first feature: Let your AI assistant test emails while you code. No context switching needed.

Installation
Install the DevSMTP MCP server globally
npm install -g @devsmtp/mcp
Configuration
Add to your IDE's MCP settings

Add to .windsurf/mcp.json:

{
  "mcpServers": {
    "devsmtp": {
      "command": "devsmtp-mcp",
      "env": {
        "DEVSMTP_API_KEY": "your-api-key-here"
      }
    }
  }
}
Available Tools
Commands your AI assistant can use
ToolDescription
send_test_emailSend a test email
check_email_logsView recent logs
validate_emailValidate an address
get_api_statusCheck usage & limits
list_domainsList verified domains
Example Workflow
Testing your signup flow with AI
You:"Test the signup email by sending a welcome message to test@myapp.com"
AI:✅ Email sent successfully! Message ID: abc123. Remaining today: 9
You:"Check if it was delivered"
AI:📧 Recent logs: ✅ test@myapp.com - "Welcome!" (sent) - 2 minutes ago