Appearance
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_hereGet Sandbox Status
Returns SMTP credentials and usage information.
GET /pro/api/sandboxResponse
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
}| Field | Description |
|---|---|
enabled | true if sandbox account exists (created on first SMTP connection) |
quota | Storage limit in bytes (100 MB) |
used | Current usage in bytes |
List Captured Emails
Returns emails in the sandbox inbox, newest first.
GET /pro/api/sandbox/messages?page=1Parameters
| Name | Type | Description |
|---|---|---|
page | query, optional | Page 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/:idResponse
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"
}
]
}| Field | Description |
|---|---|
text_body | Plain text version of the email |
html_body | HTML version (may be empty if text-only) |
attachments | List of attachments with index for download |
Download Raw Source
Downloads the original .eml file.
GET /pro/api/sandbox/messages/:id/sourceResponse: 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/:indexResponse: Binary file with appropriate Content-Type and Content-Disposition headers.
Delete a Single Email
DELETE /pro/api/sandbox/messages/:idResponse
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/messagesResponse
json
{
"deleted": 42
}Errors
| Status | Error Code | Description |
|---|---|---|
| 401 | invalid_or_expired_token | Missing or invalid API token |
| 402 | subscription_expired | Pro subscription is not active |
| 404 | sandbox_not_found | No sandbox account exists yet (send an email first) |
| 404 | email_not_found | Email ID does not exist or has expired |
| 404 | attachment_not_found | Invalid attachment index |
| 410 | email_expired | Email 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!");