Docs/API Reference

API Reference

Complete reference for all SendMailOS API endpoints.

Base URL

https://sendmailos.com/api/v1

Endpoints

POST
/api/v1/send

Send Email

Send transactional or marketing emails. Supports raw HTML content or saved templates with Handlebars variable interpolation.

Rate Limits

Transactional: 5/sec (300/min) soft limit, auto-demotes to marketing if exceeded.
Marketing: 500/sec (30,000/min) hard limit.

Request Body

ParameterTypeRequiredDescription
tostringRequiredRecipient email address
subjectstringRequiredEmail subject line
htmlstringOptional*HTML content (required if no templateId)
templateIduuidOptional*Template ID (required if no html)
from_namestringOptionalSender display name (default: "System")
from_emailstringOptionalSender email (must be from verified domain)
variablesobjectOptionalHandlebars template variables
typestringOptional"transactional" or "marketing" (default: transactional)
attachmentsarrayOptionalFile attachments (max 5 files, 7MB total)
external_idstringOptionalYour system's ID for correlation
metadataobjectOptionalCustom key-value data to store with email

Attachments

Attach files using Base64 content or a URL (fetched at send time).

FieldTypeRequiredDescription
filenamestringRequiredFilename shown to recipient
contentstringOptional*Base64-encoded file content (required if no url)
urlstringOptional*URL to fetch file from (required if no content)
contentTypestringRequiredMIME type (e.g., "application/pdf")
cidstringOptionalContent-ID for inline images (use cid:value in HTML)

Attachment Limits

Max 5 attachments per email • Max 5MB per file • Max 7MB total

Example Request

bash
curl -X POST https://sendmailos.com/api/v1/send \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "[email protected]",
    "from_email": "[email protected]",
    "from_name": "Your Company",
    "subject": "Your order has shipped!",
    "html": "<h1>Order Shipped</h1><p>Your order #{{order_id}} is on the way.</p>",
    "variables": {
      "order_id": "12345",
      "tracking_url": "https://track.example.com/12345"
    }
  }'

Response

json
{
  "success": true,
  "message": "Email queued (policy: transactional 5/sec)",
  "id": "550e8400-e29b-41d4-a716-446655440000"
}
POST
/api/v1/campaigns/send

Send Campaign

Queue a bulk email campaign to subscribers. Filter by tags or send to all subscribers.

Request Body

ParameterTypeRequiredDescription
subjectstringRequiredEmail subject line
from_namestringRequiredSender display name
from_emailstringRequiredSender email (must be from verified domain)
htmlstringOptional*HTML content (required if no templateId)
templateIduuidOptional*Template ID to use
namestringOptionalCampaign name (auto-generated if omitted)
tagsstring[]OptionalFilter subscribers by tags
variablesobjectOptionalTemplate variables
external_idstringOptionalYour system's ID for tracking
metadataobjectOptionalCustom key-value data to store with campaign

Example Request

bash
curl -X POST https://sendmailos.com/api/v1/campaigns/send \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "January Newsletter",
    "subject": "What'\''s new this month",
    "from_name": "Your Company",
    "from_email": "[email protected]",
    "html": "<h1>January Updates</h1><p>Check out our latest features...</p>",
    "tags": ["newsletter", "active"]
  }'

Response (202 Accepted)

json
{
  "success": true,
  "message": "Campaign queued with 1,234 subscribers",
  "campaignId": "550e8400-e29b-41d4-a716-446655440000"
}
POST
/api/v1/subscribers

Create Subscriber

Add or update a subscriber. Uses upsert logic to handle existing emails gracefully.

Request Body

ParameterTypeRequiredDescription
emailstringRequiredSubscriber email address
first_namestringOptionalFirst name
last_namestringOptionalLast name
tagsstring[]OptionalCustom tags for segmentation
domain_iduuidOptionalPrimary domain association
external_idstringOptionalYour system's user/contact ID
metadataobjectOptionalCustom key-value data (e.g., source, plan)

Example Request

bash
curl -X POST https://sendmailos.com/api/v1/subscribers \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "John",
    "last_name": "Doe",
    "tags": ["newsletter", "premium"]
  }'

Response (201 Created)

json
{
  "success": true,
  "subscriber": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]",
    "status": "subscribed",
    "created_at": "2024-01-15T10:30:00Z",
    "source": "api"
  }
}
GET
/api/v1/subscribers

List Subscribers

Retrieve all subscribers with pagination support.

Query Parameters

ParameterTypeDefaultDescription
limitnumber20Results per page
offsetnumber0Pagination offset
external_idstring-Filter by your system's ID

Example Request

bash
curl -X GET "https://sendmailos.com/api/v1/subscribers?limit=50&offset=0" \
  -H "Authorization: Bearer sk_live_..."

Response

json
{
  "success": true,
  "subscribers": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe",
      "status": "subscribed",
      "tags": ["newsletter", "premium"],
      "source": "api",
      "created_at": "2024-01-15T10:30:00Z",
      "primary_domain": {
        "id": "...",
        "domain_name": "yourcompany.com"
      }
    }
  ],
  "total": 1234,
  "limit": 50,
  "offset": 0
}
POST
/api/v1/domains

Add Domain

Register a new sending domain. Returns DNS records for DKIM verification.

Request Body

ParameterTypeRequiredDescription
domainstringRequiredDomain name to register
external_idstringOptionalYour system's domain/client ID
metadataobjectOptionalCustom key-value data (e.g., client_name)

Example Request

bash
curl -X POST https://sendmailos.com/api/v1/domains \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "yourcompany.com",
    "external_id": "client_123",
    "metadata": { "client_name": "Acme Corp" }
  }'

Response (201 Created)

json
{
  "success": true,
  "domain": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "domain_name": "yourcompany.com",
    "status": "pending",
    "dkim_tokens": ["abc123...", "def456...", "ghi789..."],
    "created_at": "2024-01-15T10:30:00Z",
    "dns_records": [
      {
        "type": "CNAME",
        "name": "abc123._domainkey.yourcompany.com",
        "value": "abc123.dkim.amazonses.com"
      },
      {
        "type": "CNAME",
        "name": "def456._domainkey.yourcompany.com",
        "value": "def456.dkim.amazonses.com"
      },
      {
        "type": "CNAME",
        "name": "ghi789._domainkey.yourcompany.com",
        "value": "ghi789.dkim.amazonses.com"
      }
    ]
  }
}

Error Responses

The API uses standard HTTP status codes to indicate success or failure.

StatusDescription
200Success
201Created - Resource created successfully
202Accepted - Request queued for processing
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Domain not verified or restricted
409Conflict - Resource already exists
429Rate Limited - Too many requests
500Server Error - Try again later
json
{
  "success": false,
  "error": "Invalid email format",
  "code": "VALIDATION_ERROR"
}

Related Resources