API Documentation

This page explains how to authenticate and send an email using the POST /api/v1/message endpoint.

Getting started

  1. Add and verify your domain in the dashboard.
  2. Create an API key from the dashboard.
  3. Use the API key as a Bearer token to call the API.

Authentication

Include your API key in the Authorization header as a Bearer token.

Authorization: Bearer <YOUR_API_KEY>

Official API packages

Send a message

Endpoint: POST /api/v1/message

Content-Type: application/json

Request body

  • from (string, required): Sender email, e.g. "Sender Name <no-reply@yourdomain.com>".
  • to (string|array, required): Recipient email or array of emails.
  • subject (string, required): Message subject line.
  • html (string, optional): HTML body.
  • text (string, optional): Plain text body.
  • cc (string|array, optional)
  • bcc (string|array, optional)
  • reply_to (string|array, optional)
  • headers (array, optional): Map of header name to value, e.g. {"X-Campaign": "welcome"}.
  • attachments (array, optional): Each item supports:
    • filename (string, required)
    • content (string, required): Base64-encoded or raw text
    • content_type (string, optional)
    • disposition (string, optional): attachment or inline
    • content_id (string, optional): Required for inline images referenced via cid:

Example: cURL

curl -X POST "https://sendwich.dev/api/v1/message" \
  -H "Authorization: Bearer sw_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Sender <no-reply@yourdomain.com>",
    "to": ["user@example.com"],
    "subject": "Hello from Sendwich",
    "html": "<p>Hi there ๐Ÿ‘‹</p>",
    "text": "Hi there",
    "headers": {
      "X-Campaign": "welcome"
    },
    "attachments": [
      {
        "filename": "hello.txt",
        "content": "SGVsbG8gd29ybGQh",
        "content_type": "text/plain",
        "disposition": "attachment"
      }
    ]
  }'

Example: JavaScript (fetch)

await fetch('https://sendwich.dev/api/v1/message', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + process.env.SENDWICH_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    from: 'Sender <no-reply@yourdomain.com>',
    to: ['user@example.com'],
    subject: 'Hello from Sendwich',
    html: '<p>Hi there ๐Ÿ‘‹</p>',
    text: 'Hi there',
    headers: {
      'X-Campaign': 'welcome'
    },
    attachments: [
      {
        filename: 'hello.txt',
        content: 'SGVsbG8gd29ybGQh',
        content_type: 'text/plain',
        disposition: 'attachment'
      }
    ]
  })
});

Example: PHP (Laravel HTTP)

Http::withToken(env('SENDWICH_API_KEY'))
    ->post('https://sendwich.dev/api/v1/message', [
        'from' => 'Sender <no-reply@yourdomain.com>',
        'to' => ['user@example.com'],
        'subject' => 'Hello from Sendwich',
        'html' => '<p>Hi there ๐Ÿ‘‹</p>',
        'text' => 'Hi there',
        'headers' => [
            'X-Campaign' => 'welcome',
        ],
        'attachments' => [
            [
                'filename' => 'hello.txt',
                'content' => 'SGVsbG8gd29ybGQh',
                'content_type' => 'text/plain',
                'disposition' => 'attachment',
            ],
        ],
    ]);

Responses

  • 201 Created on success with an empty body (message is queued for delivery).
  • 401 Unauthorized with body {"reason": "Invalid key"} when the API key is invalid.
  • 400 Bad Request when the from domain is invalid for the key or the domain is not verified.
  • 422 Unprocessable Entity with validation errors when the input is invalid.

Notes

  • Fields like to, cc, bcc, and reply_to accept either a single email string or an array of emails.
  • HTML and text bodies are optional, but at least one should be provided.
  • Ensure your sender domain is verified before sending.
  • Custom headers and attachments are supported. For inline images, set disposition to inline and provide a content_id, then reference it in HTML as <img src="cid:your-content-id">.