API Reference
Send transactional emails programmatically using the AutoSend REST API. This guide covers the email sending endpoint, request/response formats, and best practices.
Base URL
All API requests should be made to:
https://api.autosend.com/v1Authentication
All API requests require authentication using an API key. Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYLearn how to create and manage API keys →
Available Endpoint
| Endpoint | Method | Description | 
|---|---|---|
/mails/send | POST | Send a single email to one recipient | 
Send Email
Send a single transactional email to one recipient.
Endpoint
POST /v1/mails/sendRequest Headers
| Header | Value | Required | 
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes | 
Content-Type | application/json | Yes | 
Idempotency-Key | unique-request-id | No | 
Request Body Parameters
| Parameter | Type | Required | Description | 
|---|---|---|---|
to.email | string | Yes | Recipient email address | 
to.name | string | No | Recipient name | 
from.email | string | Yes | Sender email address (must be from a verified domain) | 
from.name | string | No | Sender name | 
subject | string | Yes* | Email subject line (max 998 characters) | 
html | string | Yes* | HTML content of the email | 
text | string | No | Plain text version of the email | 
templateId | string | Yes* | ID of the email template to use | 
replyTo.email | string | No | Reply-to email address | 
replyTo.name | string | No | Reply-to name | 
unsubscribeGroupId | string | No | ID of the unsubscribe group | 
categories | array | No | Array of category strings for tracking | 
dynamicData | object | No | Key-value pairs for template variable substitution | 
scheduledAt | string | No | ISO 8601 timestamp to schedule email delivery | 
campaignName | string | No | Campaign name for tracking purposes | 
test | boolean | No | Set to true to send a test email (default: false) | 
Note: Either templateId OR html/text must be provided. If using a template, subject is optional.
Example Request
curl -X POST https://api.autosend.com/v1/mails/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": {
      "email": "[email protected]",
      "name": "Jane Smith"
    },
    "from": {
      "email": "[email protected]",
      "name": "Your Company"
    },
    "subject": "Welcome to Our Platform!",
    "html": "<h1>Welcome, {{name}}!</h1><p>Thanks for signing up.</p>",
    "dynamicData": {
      "name": "Jane"
    },
    "categories": ["welcome", "onboarding"],
    "replyTo": {
      "email": "[email protected]"
    }
  }'Example Request with Template
curl -X POST https://api.autosend.com/v1/mails/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": {
    "email": "[email protected]",
      "name": "Jane Smith"
  },
  "from": {
      "email": "[email protected]",
      "name": "Your Company"
    },
    "templateId": "tmpl_abc123",
    "dynamicData": {
      "firstName": "Jane",
      "orderNumber": "ORD-12345",
      "orderTotal": "$99.99"
    }
  }'Success Response (200 OK)
{
  "success": true,
  "message": "Email queued successfully",
  "data": {
    "emailId": "email_xyz789",
    "status": "queued",
    "queuedAt": "2025-09-30T10:30:00.000Z"
  }
}Error Response (400 Bad Request)
{
  "success": false,
  "message": "Validation failed",
  "errors": [
    {
      "field": "to.email",
      "message": "Invalid email format"
    }
  ]
}Error Response (401 Unauthorized)
{
  "success": false,
  "message": "Unauthorized"
}Error Response (429 Too Many Requests)
{
  "success": false,
  "message": "Rate limit exceeded",
  "retryAfter": 30
}HTTP Status Codes
| Code | Meaning | Description | 
|---|---|---|
200 | OK | Request succeeded | 
400 | Bad Request | Invalid request parameters | 
401 | Unauthorized | Missing or invalid API key | 
403 | Forbidden | API key doesn’t have required access | 
404 | Not Found | Resource doesn’t exist | 
429 | Too Many Requests | Rate limit exceeded | 
500 | Internal Server Error | Something went wrong on our end | 
503 | Service Unavailable | Temporary service outage | 
Rate Limits
API keys are subject to the following rate limits:
- 2 requests per second per API key
 - 50 requests per minute per API key
 
When you exceed the rate limit, you’ll receive a 429 Too Many Requests response with a retryAfter field indicating how many seconds to wait.
Rate Limit Headers
Each API response includes rate limit information:
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1696075200Handling Rate Limits
Implement exponential backoff when receiving 429 errors:
async function sendEmailWithRetry(data, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await sendEmail(data);
      return response;
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise((resolve) => setTimeout(resolve, waitTime));
      } else {
        throw error;
      }
    }
  }
}Dynamic Data & Personalization
Use Handlebars syntax for template variables:
<h1>Hello {{firstName}}!</h1>
<p>Your order #{{orderNumber}} has been shipped.</p>
<p>Total: {{orderTotal}}</p>Provide values in the dynamicData object:
{
  "html": "<h1>Hello {{firstName}}!</h1>",
  "dynamicData": {
    "firstName": "Jane",
    "orderNumber": "12345",
    "orderTotal": "$99.99"
  }
}Idempotency
To safely retry requests without duplicate operations, use idempotency keys:
curl -X POST https://api.autosend.com/v1/mails/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-12345" \
  -d '...'If you retry a request with the same idempotency key within 24 hours, you’ll receive the same response without sending a duplicate email.
Testing
Use the test flag to validate your integration without sending actual emails:
{
  "to": { "email": "[email protected]" },
  "from": { "email": "[email protected]" },
  "subject": "Test Email",
  "html": "<p>Testing</p>",
  "test": true
}Test emails are processed but not delivered, allowing you to verify your integration without impacting statistics.
Code Examples
JavaScript (Node.js)
const fetch = require("node-fetch");
 
const API_KEY = process.env.AUTOSEND_API_KEY;
 
async function sendEmail() {
  const response = await fetch("https://api.autosend.com/v1/mails/send", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      to: { email: "[email protected]", name: "John Doe" },
      from: { email: "[email protected]", name: "Your Company" },
      subject: "Welcome!",
      html: "<h1>Hello!</h1><p>Welcome to our platform.</p>",
    }),
  });
 
  const data = await response.json();
  console.log(data);
}
 
sendEmail();Python
import requests
import os
 
API_KEY = os.environ.get('AUTOSEND_API_KEY')
 
def send_email():
    url = 'https://api.autosend.com/v1/mails/send'
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json'
    }
    payload = {
        'to': {
            'email': '[email protected]',
            'name': 'John Doe'
        },
        'from': {
            'email': '[email protected]',
            'name': 'Your Company'
        },
        'subject': 'Welcome!',
        'html': '<h1>Hello!</h1><p>Welcome to our platform.</p>'
    }
 
    response = requests.post(url, json=payload, headers=headers)
    print(response.json())
 
send_email()PHP
<?php
 
$apiKey = getenv('AUTOSEND_API_KEY');
 
$ch = curl_init('https://api.autosend.com/v1/mails/send');
 
$payload = json_encode([
    'to' => [
        'email' => '[email protected]',
        'name' => 'John Doe'
    ],
    'from' => [
        'email' => '[email protected]',
        'name' => 'Your Company'
    ],
    'subject' => 'Welcome!',
    'html' => '<h1>Hello!</h1><p>Welcome to our platform.</p>'
]);
 
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
$response = curl_exec($ch);
curl_close($ch);
 
echo $response;
?>Best Practices
1. Use Environment Variables
Never hardcode API keys in your source code:
const API_KEY = process.env.AUTOSEND_API_KEY;2. Implement Error Handling
Always handle errors appropriately:
try {
  const response = await sendEmail(data);
  console.log("Email sent:", response.data.emailId);
} catch (error) {
  if (error.response?.status === 429) {
    // Rate limit - retry later
  } else if (error.response?.status === 400) {
    // Validation error - fix the data
  } else {
    // Other error - log and alert
  }
}3. Validate Email Addresses
Validate email addresses before sending to reduce bounces:
function isValidEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}4. Use Verified Domains
Always send from verified domains to ensure deliverability. Learn how to verify domains →
5. Include Unsubscribe Links
For marketing emails, always include unsubscribe links to comply with regulations and maintain good sender reputation.
Common Errors
Domain Not Verified
Error:
{
  "success": false,
  "message": "Domain not verified"
}Solution: Verify your sending domain in Settings > Domains. Domain verification guide →
Invalid Email Format
Error:
{
  "success": false,
  "message": "Validation failed",
  "errors": [{ "field": "to.email", "message": "Invalid email format" }]
}Solution: Ensure email addresses follow the correct format: [email protected]
Missing Content
Error:
{
  "success": false,
  "message": "Either templateId or html/text content must be provided"
}Solution: Provide either a templateId or html/text content in your request.
Need Help?
If you’re experiencing issues with the API, please contact support.