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.

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
}

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

Code Examples

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...
});