Email Testing API
Create disposable test inboxes, send emails to them, and inspect the full content programmatically. Perfect for CI pipelines and automated testing.
Overview
The Email Testing API lets you create temporary inboxes on the mailchk.email domain. Send any email to the generated address — from your app, your ESP, or your CI pipeline — and retrieve the full parsed content via API.
∞
No auto-expiry
5
Active inboxes per user
50
Messages per inbox
1
Credit per inbox created
Paid plans only
Email Testing requires a paid plan or purchased credits. Each inbox creation costs 1 validation credit. Listing, reading, and deleting are free.
Quick Start
# 1. Create a test inbox
curl -X POST "https://api.mailchk.io/v1/test-inboxes" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "CI signup flow"}'
# Response:
# {
# "id": "a1b2c3d4-...",
# "address": "test-k9m2x7p3qr@mailchk.email",
# "label": "CI signup flow",
# "message_count": 0,
# "created_at": "2026-02-15T10:00:00.000Z",
# }
# 2. Send an email to the test address from your app
# (use your own sending logic — SMTP, SendGrid, etc.)
# 3. Poll for messages
curl "https://api.mailchk.io/v1/test-inboxes/a1b2c3d4-.../messages" \
-H "X-API-Key: YOUR_API_KEY"
# 4. Inspect a captured email
curl "https://api.mailchk.io/v1/test-inboxes/a1b2c3d4-.../messages/MSG_ID" \
-H "X-API-Key: YOUR_API_KEY"Base URL
https://api.mailchk.ioAuthenticate with your API key in the X-API-Key header. See the authentication guide for details.
Endpoints
/v1/test-inboxesCosts 1 validation creditCreate a new test inbox. Returns a unique email address that accepts incoming emails. Requires a label to help you organise your tests.
Auth: API Key or JWT
Request Body
{
"label": "CI signup flow" // required, max 100 chars
}Response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"address": "test-k9m2x7p3qr@mailchk.email",
"label": "CI signup flow",
"message_count": 0,
"created_at": "2026-02-15T10:00:00.000Z"
}/v1/test-inboxesList all test inboxes for the authenticated user.
Auth: API Key or JWT
Response
{
"inboxes": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"address": "test-k9m2x7p3qr@mailchk.email",
"label": "CI signup flow",
"message_count": 3,
"created_at": "2026-02-15T10:00:00.000Z"
}
]
}/v1/test-inboxes/:idDelete a test inbox and all its messages. Also removes stored email files from storage.
Auth: API Key or JWT
Response
{
"success": true
}/v1/test-inboxes/:id/messagesList all messages received by a test inbox. Returns metadata only (no full email content).
Auth: API Key or JWT
Response
{
"messages": [
{
"id": "msg-1234-5678-abcd",
"from_address": "noreply@yourapp.com",
"to_address": "test-k9m2x7p3qr@mailchk.email",
"subject": "Your order #4521 has shipped",
"text_preview": "Hi there, Great news! Your order...",
"has_html": true,
"has_attachments": true,
"attachment_count": 1,
"raw_size": 24576,
"received_at": "2026-02-15T10:05:30.000Z"
}
]
}/v1/test-inboxes/:id/messages/:msgIdGet the full parsed content of a captured email — HTML, plain text, headers, and attachments (base64-encoded).
Auth: API Key or JWT
Response
{
"id": "msg-1234-5678-abcd",
"inbox_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"from": {
"name": "YourApp",
"address": "noreply@yourapp.com"
},
"to": [
{
"name": "",
"address": "test-k9m2x7p3qr@mailchk.email"
}
],
"cc": [],
"subject": "Your order #4521 has shipped",
"date": "2026-02-15T10:05:30.000Z",
"headers": [
{ "key": "From", "value": "YourApp <noreply@yourapp.com>" },
{ "key": "To", "value": "test-k9m2x7p3qr@mailchk.email" },
{ "key": "Subject", "value": "Your order #4521 has shipped" },
{ "key": "Content-Type", "value": "multipart/mixed" },
{ "key": "DKIM-Signature", "value": "v=1; a=rsa-sha256; ..." },
{ "key": "X-Mailer", "value": "SendGrid" }
],
"text": "Hi there,\nGreat news! Your order #4521 has shipped...",
"html": "<html><body><h1>Your order has shipped!</h1>...</body></html>",
"attachments": [
{
"filename": "shipping-label.pdf",
"mimeType": "application/pdf",
"size": 15234,
"contentId": null,
"content": "JVBERi0xLjQK..."
}
],
"raw_size": 24576,
"received_at": "2026-02-15T10:05:30.000Z"
}Message Detail Fields
Fields returned by GET /v1/test-inboxes/:id/messages/:msgId:
| Field | Type | Description |
|---|---|---|
| id | string | Unique message identifier |
| inbox_id | string | The test inbox that received this email |
| from | object | Sender with name and address fields |
| to | array | Recipients array with name and address fields |
| cc | array | CC recipients (same format as to) |
| subject | string | Email subject line |
| date | string | Date header from the email (ISO 8601) |
| headers | array | All email headers as {key, value} pairs |
| text | string? | Plain text body (null if no text part) |
| html | string? | HTML body (null if no HTML part) |
| attachments | array | Attachments with filename, mimeType, size, contentId, and base64 content |
| raw_size | number | Size of the raw .eml file in bytes |
| received_at | string | When the email was received (ISO 8601) |
Attachment Fields
| Field | Type | Description |
|---|---|---|
| filename | string | Original filename of the attachment |
| mimeType | string | MIME type (e.g., application/pdf, image/png) |
| size | number | Size of the attachment in bytes |
| contentId | string? | Content-ID for inline images (used in HTML src="cid:...") |
| content | string | Base64-encoded binary content of the attachment |
Error Codes
Bad Request
Maximum active inboxes reached (5 per user), or invalid request body
Authentication Required
Missing or invalid API key / JWT token. Code: AUTH_REQUIRED
Forbidden
Free plan — Email Testing requires a paid plan or purchased credits
Not Found
Inbox or message not found, or inbox belongs to a different user
Usage Limit Exceeded
Subscription limit reached and no credits remaining. Code: USAGE_LIMIT_EXCEEDED
CI/CD Integration
Test your transactional emails in CI. Create an inbox before your test suite runs, trigger emails through your app, then assert on the captured content.
# GitHub Actions example — test your signup email flow
name: Email Integration Tests
on: [push]
jobs:
test-emails:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test inbox
id: inbox
run: |
RESPONSE=$(curl -s -X POST "https://api.mailchk.io/v1/test-inboxes" \
-H "X-API-Key: ${{ secrets.MAILCHK_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"label": "CI run #${{ github.run_number }}"}')
echo "INBOX_ID=$(echo $RESPONSE | jq -r '.id')" >> $GITHUB_OUTPUT
echo "INBOX_ADDR=$(echo $RESPONSE | jq -r '.address')" >> $GITHUB_OUTPUT
- name: Trigger signup email
run: |
# Call your app's signup endpoint with the test inbox address
curl -X POST "http://localhost:3000/api/signup" \
-H "Content-Type: application/json" \
-d '{"email": "${{ steps.inbox.outputs.INBOX_ADDR }}"}'
- name: Wait for email & verify
run: |
sleep 10
MESSAGES=$(curl -s "https://api.mailchk.io/v1/test-inboxes/${{ steps.inbox.outputs.INBOX_ID }}/messages" \
-H "X-API-Key: ${{ secrets.MAILCHK_API_KEY }}")
COUNT=$(echo $MESSAGES | jq '.messages | length')
if [ "$COUNT" -eq "0" ]; then
echo "❌ No email received!"
exit 1
fi
SUBJECT=$(echo $MESSAGES | jq -r '.messages[0].subject')
echo "✅ Email received: $SUBJECT"
- name: Cleanup
if: always()
run: |
curl -s -X DELETE "https://api.mailchk.io/v1/test-inboxes/${{ steps.inbox.outputs.INBOX_ID }}" \
-H "X-API-Key: ${{ secrets.MAILCHK_API_KEY }}"Signup & Onboarding
Verify welcome emails, verification links, and onboarding sequences arrive with correct content.
Password Reset
Assert reset tokens are present, links are correct, and emails render properly.
Order Notifications
Check order confirmations, shipping updates, and receipts contain the right data.
Ready to Start Testing?
Create your first test inbox in seconds. Use the dashboard or integrate via API.