Integrate bulk temporary email capabilities into your automated QA test suites, registration flows, or application checks using our fast, standard REST API.
To successfully receive emails on custom domains, developers follow these three simple steps:
Register a custom domain name and verify the TXT record matching the generated token.
Point your DNS MX record with priority 10 to our inbound mail server: mail.mailzan.com.
Generate temporary mailboxes on the fly and retrieve email bodies or verify codes.
All REST API v1 endpoints require authorization. You must generate an API Key in your Dashboard and pass it as an HTTP header:
x-api-key: your_plain_api_key_here
Generate a unique temporary address. The domain must be registered and verified in your workspace.
/api/v1/mailboxes
curl -X POST https://mailzan.com/api/v1/mailboxes \
-H "Content-Type: application/json" \
-H "x-api-key: your_api_key" \
-d '{"username": "qa-test-102", "domainId": "domain_uuid"}'
const response = await fetch('https://mailzan.com/api/v1/mailboxes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your_api_key'
},
body: JSON.stringify({
username: 'qa-test-102',
domainId: 'domain_uuid'
})
});
const data = await response.json();
console.log(data);
import requests
url = "https://mailzan.com/api/v1/mailboxes"
headers = {
"Content-Type": "application/json",
"x-api-key": "your_api_key"
}
payload = {
"username": "qa-test-102",
"domainId": "domain_uuid"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
<?php
$ch = curl_init('https://mailzan.com/api/v1/mailboxes');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'x-api-key: your_api_key'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'username' => 'qa-test-102',
'domainId' => 'domain_uuid'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
?>
require 'net/http'
require 'json'
require 'uri'
uri = URI.parse("https://mailzan.com/api/v1/mailboxes")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["x-api-key"] = "your_api_key"
request.body = JSON.dump({
"username" => "qa-test-102",
"domainId" => "domain_uuid"
})
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
puts JSON.parse(response.body)
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
url := "https://mailzan.com/api/v1/mailboxes"
payload, _ := json.Marshal(map[string]string{
"username": "qa-test-102",
"domainId": "domain_uuid",
})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", "your_api_key")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
{
"message": "Mailbox created successfully",
"mailbox": {
"id": "mailbox_uuid",
"tenantId": "tenant_uuid",
"domainId": "domain_uuid",
"username": "qa-test-102",
"address": "qa-test-102@mailzan.com",
"isActive": true,
"createdAt": "2026-07-05T08:00:00.000Z"
}
}
Queries inbound emails received. Large html/text fields are omitted to optimize bandwidth.
/api/v1/emails?mailboxId=mailbox_uuid&limit=10
curl -X GET "https://mailzan.com/api/v1/emails?mailboxId=mailbox_uuid&limit=10" \
-H "x-api-key: your_api_key"
const response = await fetch('https://mailzan.com/api/v1/emails?mailboxId=mailbox_uuid&limit=10', {
method: 'GET',
headers: {
'x-api-key': 'your_api_key'
}
});
const data = await response.json();
console.log(data.emails);
import requests
url = "https://mailzan.com/api/v1/emails"
params = {
"mailboxId": "mailbox_uuid",
"limit": 10
}
headers = {
"x-api-key": "your_api_key"
}
response = requests.get(url, params=params, headers=headers)
print(response.json())
<?php
$ch = curl_init('https://mailzan.com/api/v1/emails?mailboxId=mailbox_uuid&limit=10');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'x-api-key: your_api_key'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
?>
require 'net/http'
require 'json'
require 'uri'
uri = URI.parse("https://mailzan.com/api/v1/emails?mailboxId=mailbox_uuid&limit=10")
request = Net::HTTP::Get.new(uri)
request["x-api-key"] = "your_api_key"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
puts JSON.parse(response.body)
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
url := "https://mailzan.com/api/v1/emails?mailboxId=mailbox_uuid&limit=10"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("x-api-key", "your_api_key")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
{
"emails": [
{
"id": "email_uuid",
"mailboxId": "mailbox_uuid",
"from": "sender@external.com",
"to": "qa-test-102@mailzan.com",
"subject": "Verification Code: 98122",
"size": 1024,
"createdAt": "2026-07-05T08:05:00.000Z"
}
]
}
When webhook target endpoints are signed, TMaaS sends the signature in header x-tmaas-signature. Developers can verify payloads using Node's standard crypto package:
const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-tmaas-signature'];
const computed = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(req.body))
.digest('hex');
return signature === computed;
}