Skip to content

Sandbox API

Query, inspect, and manage emails captured by the SMTP Sandbox. All endpoints require a Pro API token in the Authorization header.

Authorization: Bearer tm_pro_your_token_here

Get Sandbox Status

Returns SMTP credentials and usage information.

GET /pro/api/sandbox

Response

json
{
  "enabled": true,
  "account_id": "a1b2c3d4-...",
  "address": "sandbox-a1b2c3d4@sandbox.mail.td",
  "smtp_host": "smtp.mail.td",
  "smtp_port": 25,
  "auth_method": "PLAIN",
  "username": "any",
  "note": "Use any API token as the SMTP password",
  "quota": 104857600,
  "used": 2457600
}
FieldDescription
enabledtrue if sandbox account exists (created on first SMTP connection)
quotaStorage limit in bytes (100 MB)
usedCurrent usage in bytes

List Captured Emails

Returns emails in the sandbox inbox, newest first.

GET /pro/api/sandbox/messages?page=1

Parameters

NameTypeDescription
pagequery, optionalPage number (default: 1, 30 per page)

Response

json
{
  "messages": [
    {
      "id": "e5f6g7h8-...",
      "sender": "noreply@yourapp.com",
      "from": "YourApp <noreply@yourapp.com>",
      "subject": "Welcome to YourApp",
      "preview_text": "Thanks for signing up! Click the link below to...",
      "size": 4521,
      "created_at": "2025-03-15T10:30:00Z"
    }
  ],
  "page": 1
}

Get Email Detail

Returns the full content of a captured email, including HTML body, plain text, and attachments.

GET /pro/api/sandbox/messages/:id

Response

json
{
  "id": "e5f6g7h8-...",
  "sender": "noreply@yourapp.com",
  "from": "YourApp <noreply@yourapp.com>",
  "subject": "Welcome to YourApp",
  "address": "user@example.com",
  "size": 4521,
  "created_at": "2025-03-15T10:30:00Z",
  "text_body": "Thanks for signing up!\n\nClick the link below...",
  "html_body": "<h1>Welcome!</h1><p>Thanks for signing up!</p>...",
  "attachments": [
    {
      "index": 0,
      "filename": "invoice.pdf",
      "size": 12800,
      "content_type": "application/pdf"
    }
  ]
}
FieldDescription
text_bodyPlain text version of the email
html_bodyHTML version (may be empty if text-only)
attachmentsList of attachments with index for download

Download Raw Source

Downloads the original .eml file.

GET /pro/api/sandbox/messages/:id/source

Response: message/rfc822 binary with Content-Disposition: attachment; filename="message.eml"


Download Attachment

Downloads a specific attachment by index.

GET /pro/api/sandbox/messages/:id/attachments/:index

Response: Binary file with appropriate Content-Type and Content-Disposition headers.


Delete a Single Email

DELETE /pro/api/sandbox/messages/:id

Response

json
{
  "deleted": true
}

INFO

Deleting an email reclaims its storage quota immediately.


Purge All Emails

Deletes all emails in the sandbox and resets the usage counter.

DELETE /pro/api/sandbox/messages

Response

json
{
  "deleted": 42
}

Errors

StatusError CodeDescription
401invalid_or_expired_tokenMissing or invalid API token
402subscription_expiredPro subscription is not active
404sandbox_not_foundNo sandbox account exists yet (send an email first)
404email_not_foundEmail ID does not exist or has expired
404attachment_not_foundInvalid attachment index
410email_expiredEmail source file has been cleaned up

Example: Automated Test (Node.js)

javascript
const assert = require("assert");

const API = "https://api.mail.td/pro/api";
const TOKEN = process.env.MAILTD_TOKEN;

async function fetchSandboxMessages() {
  const res = await fetch(`${API}/sandbox/messages`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
  });
  return res.json();
}

// After your app sends an email...
const { messages } = await fetchSandboxMessages();
const latest = messages[0];

assert(latest.subject.includes("Welcome"));
assert(latest.from.includes("yourapp.com"));

// Get full content
const detail = await fetch(`${API}/sandbox/messages/${latest.id}`, {
  headers: { Authorization: `Bearer ${TOKEN}` },
}).then(r => r.json());

assert(detail.html_body.includes("verify your email"));
console.log("Email test passed!");

Mail.td API Documentation