Mail API Integration Guide¶
This guide explains how to integrate the Mail API into your applications.
Base URL¶
Authentication¶
All API requests require authentication via the X-MAILAPI-TOKEN header.
Token Types¶
| Type | Access Level |
|---|---|
| Admin Token | Full access to all endpoints and all mailboxes |
| User Token | Access only to the mailbox associated with the token |
Contact your administrator to obtain an API token.
Quick Start Examples¶
cURL¶
curl -X GET "https://mail-api.solutechhub.com/api/v1/mail/sent" \
-H "X-MAILAPI-TOKEN: your-token-here"
Python¶
import requests
API_URL = "https://mail-api.solutechhub.com/api/v1"
TOKEN = "your-token-here"
headers = {"X-MAILAPI-TOKEN": TOKEN}
response = requests.get(f"{API_URL}/mail/sent", headers=headers)
print(response.json())
JavaScript (Node.js)¶
const axios = require('axios');
const API_URL = 'https://mail-api.solutechhub.com/api/v1';
const TOKEN = 'your-token-here';
const headers = { 'X-MAILAPI-TOKEN': TOKEN };
axios.get(`${API_URL}/mail/sent`, { headers })
.then(response => console.log(response.data))
.catch(error => console.error(error));
PHP¶
<?php
$apiUrl = "https://mail-api.solutechhub.com/api/v1";
$token = "your-token-here";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiUrl/mail/sent");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-MAILAPI-TOKEN: $token"
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
API Endpoints¶
1. Send Email¶
Send an email through the API.
Endpoint: POST /mail/send
Request Body:
{
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"cc": ["cc@example.com"],
"bcc": ["bcc@example.com"],
"subject": "Hello from API",
"body": {
"text": "Plain text version of the email",
"html": "<h1>HTML version</h1><p>This is the HTML body.</p>"
},
"reply_to": "replyto@yourdomain.com",
"headers": {
"X-Custom-Header": "custom-value"
},
"attachments": [
{
"filename": "document.pdf",
"content": "base64-encoded-content-here",
"content_type": "application/pdf"
}
]
}
Required Fields: - from - Sender email address (must be from an allowed domain) - to - Array of recipient email addresses - body - Object containing text and/or html content
Optional Fields: - cc - Array of CC recipients - bcc - Array of BCC recipients - subject - Email subject - reply_to - Reply-To address - headers - Custom email headers - attachments - Array of attachments (base64 encoded)
Response (202 Accepted):
{
"success": true,
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "submitted",
"queue_id": "4f0Bn53bY2z6v2j",
"recipient_count": 3
}
Example - Python:
import requests
import base64
API_URL = "https://mail-api.solutechhub.com/api/v1"
TOKEN = "your-token-here"
# Read and encode attachment
with open("document.pdf", "rb") as f:
attachment_content = base64.b64encode(f.read()).decode()
email_data = {
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Invoice Attached",
"body": {
"text": "Please find the invoice attached.",
"html": "<p>Please find the invoice attached.</p>"
},
"attachments": [
{
"filename": "invoice.pdf",
"content": attachment_content,
"content_type": "application/pdf"
}
]
}
response = requests.post(
f"{API_URL}/mail/send",
json=email_data,
headers={"X-MAILAPI-TOKEN": TOKEN}
)
result = response.json()
print(f"Message ID: {result['message_id']}")
2. Check Message Status¶
Get the delivery status of a sent message.
Endpoint: GET /mail/{message_id}/status
Response:
{
"success": true,
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "sent",
"created_at": "2024-01-27T10:30:00Z",
"submitted_at": "2024-01-27T10:30:01Z",
"recipients": [
{
"email": "recipient1@example.com",
"type": "to",
"status": "sent",
"dsn_code": "2.0.0",
"delivered_at": "2024-01-27T10:30:05Z"
},
{
"email": "recipient2@example.com",
"type": "to",
"status": "bounced",
"dsn_code": "5.1.1",
"smtp_response": "Mailbox not found"
}
]
}
Status Values: - pending - Message created but not yet sent - submitted - Message submitted to mail server - sent - All recipients delivered successfully - partial - Some recipients delivered, some failed - bounced - All recipients failed - failed - Submission failed
Example - JavaScript:
const axios = require('axios');
const API_URL = 'https://mail-api.solutechhub.com/api/v1';
const TOKEN = 'your-token-here';
const MESSAGE_ID = '550e8400-e29b-41d4-a716-446655440000';
axios.get(`${API_URL}/mail/${MESSAGE_ID}/status`, {
headers: { 'X-MAILAPI-TOKEN': TOKEN }
})
.then(response => {
const { status, recipients } = response.data;
console.log(`Overall status: ${status}`);
recipients.forEach(r => {
console.log(` ${r.email}: ${r.status}`);
});
});
3. List Sent Messages¶
Get a list of messages sent via the API.
Endpoint: GET /mail/sent
Query Parameters: - limit (default: 50) - Number of messages to return - offset (default: 0) - Number of messages to skip
Response:
{
"success": true,
"total": 150,
"messages": [
{
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"from": "sender@yourdomain.com",
"to": ["recipient@example.com"],
"subject": "Hello",
"status": "sent",
"created_at": "2024-01-27T10:30:00Z",
"submitted_at": "2024-01-27T10:30:01Z"
}
]
}
4. List Mailbox Folders¶
Get a list of folders in a mailbox.
Endpoint: GET /mailbox/{email}/folders
Note: User tokens can only access their own mailbox.
Response:
{
"success": true,
"mailbox": "user@yourdomain.com",
"folders": [
{"name": "INBOX", "messages": 150, "unread": 12, "size": 52428800},
{"name": "Sent", "messages": 89, "unread": 0, "size": 15728640},
{"name": "Drafts", "messages": 3, "unread": 0, "size": 102400},
{"name": "Trash", "messages": 45, "unread": 0, "size": 8388608},
{"name": "Spam", "messages": 23, "unread": 23, "size": 2097152}
]
}
5. List Messages in Folder¶
Get a list of messages in a specific folder.
Endpoint: GET /mailbox/{email}/messages
Query Parameters: - folder (default: "INBOX") - Folder name - limit (default: 50, max: 200) - Number of messages - offset (default: 0) - Pagination offset
Response:
{
"success": true,
"mailbox": "user@yourdomain.com",
"folder": "INBOX",
"total": 150,
"messages": [
{
"uid": 1234,
"message_id": "<abc123@example.com>",
"from": {"name": "John Doe", "email": "john@example.com"},
"to": [{"name": "User", "email": "user@yourdomain.com"}],
"subject": "Meeting tomorrow",
"date": "2024-01-27T10:30:00Z",
"size": 15360,
"flags": ["\\Seen"],
"has_attachments": true
}
]
}
Example - PHP:
<?php
$apiUrl = "https://mail-api.solutechhub.com/api/v1";
$token = "your-token-here";
$email = "user@yourdomain.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiUrl/mailbox/$email/messages?folder=INBOX&limit=20");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-MAILAPI-TOKEN: $token"]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
foreach ($data['messages'] as $msg) {
echo "{$msg['subject']} - {$msg['from']['email']}\n";
}
6. Get Full Message¶
Get the complete content of a specific message.
Endpoint: GET /mailbox/{email}/messages/{uid}
Query Parameters: - folder (default: "INBOX") - Folder containing the message
Response:
{
"success": true,
"uid": 1234,
"message_id": "<abc123@example.com>",
"from": {"name": "John Doe", "email": "john@example.com"},
"to": [{"name": "User", "email": "user@yourdomain.com"}],
"cc": [],
"subject": "Meeting tomorrow",
"date": "2024-01-27T10:30:00Z",
"headers": {
"X-Priority": "1",
"Reply-To": "john@example.com"
},
"body": {
"text": "Plain text content of the email...",
"html": "<html><body><p>HTML content...</p></body></html>"
},
"attachments": [
{
"index": 0,
"filename": "agenda.pdf",
"content_type": "application/pdf",
"size": 102400,
"content_id": null
}
],
"flags": ["\\Seen"]
}
7. Download Attachment¶
Download an attachment from a message.
Endpoint: GET /mailbox/{email}/messages/{uid}/attachment/{index}
Query Parameters: - folder (default: "INBOX") - Folder containing the message
Response: Binary file with appropriate Content-Type header
Example - Python:
import requests
API_URL = "https://mail-api.solutechhub.com/api/v1"
TOKEN = "your-token-here"
email = "user@yourdomain.com"
uid = 1234
attachment_index = 0
response = requests.get(
f"{API_URL}/mailbox/{email}/messages/{uid}/attachment/{attachment_index}",
headers={"X-MAILAPI-TOKEN": TOKEN}
)
# Get filename from Content-Disposition header
filename = response.headers.get('Content-Disposition', '').split('filename=')[-1].strip('"')
with open(filename or "attachment", "wb") as f:
f.write(response.content)
8. Search Messages¶
Search for messages in a mailbox.
Endpoint: GET /mailbox/{email}/search
Query Parameters: - q (required) - Search query (min 2 characters) - folder (default: "INBOX") - Folder to search - limit (default: 50) - Max results
Response:
{
"success": true,
"query": "meeting",
"total": 23,
"messages": [
{
"uid": 1234,
"folder": "INBOX",
"from": {"name": "John", "email": "john@example.com"},
"subject": "Meeting tomorrow",
"date": "2024-01-27T10:30:00Z",
"snippet": "...discuss the meeting agenda..."
}
]
}
9. Get Delivery Statistics¶
Get aggregate delivery statistics for a time period.
Endpoint: GET /stats/delivery
Query Parameters: - start_date - Start date (ISO 8601, default: 7 days ago) - end_date - End date (ISO 8601, default: now) - sender - Filter by sender email or domain - group_by - Group by: "day", "hour", or "domain"
Response:
{
"success": true,
"period": {
"start": "2024-01-20T00:00:00Z",
"end": "2024-01-27T23:59:59Z"
},
"summary": {
"total_sent": 1250,
"delivered": 1180,
"bounced": 45,
"deferred": 20,
"rejected": 5,
"delivery_rate": 94.4
},
"breakdown": [
{"date": "2024-01-27", "sent": 180, "delivered": 172, "bounced": 6, "deferred": 2},
{"date": "2024-01-26", "sent": 165, "delivered": 158, "bounced": 5, "deferred": 2}
]
}
10. Get Domain Statistics¶
Get statistics for a specific domain.
Endpoint: GET /stats/domain/{domain}
Query Parameters: - start_date - Start date (ISO 8601) - end_date - End date (ISO 8601)
Response:
{
"success": true,
"domain": "yourdomain.com",
"period": {
"start": "2024-01-20T00:00:00Z",
"end": "2024-01-27T23:59:59Z"
},
"outbound": {
"total": 450,
"delivered": 430,
"bounced": 15,
"deferred": 5,
"top_recipients": [
{"domain": "gmail.com", "count": 120},
{"domain": "outlook.com", "count": 85}
]
},
"inbound": {
"total": 320,
"accepted": 310,
"rejected": 10,
"spam": 15,
"top_senders": [
{"domain": "gmail.com", "count": 95}
]
}
}
11. Get Current Token Info¶
Get information about the currently used token.
Endpoint: GET /tokens/me
Response:
{
"id": 1,
"token_prefix": "Bxe2GOed",
"token_type": "admin",
"email": null,
"name": "My API Token",
"is_active": true,
"created_at": "2024-01-27T10:00:00Z",
"last_used_at": "2024-01-27T15:30:00Z",
"expires_at": null
}
12. Self-Signup¶
Create a new account and domain. No authentication required.
Endpoint: POST /auth/signup
Request Body:
{
"domain": "yourdomain.com",
"email": "admin@yourdomain.com",
"password": "SecurePassword123",
"name": "Your Name"
}
Validation: - Email must end with @{domain} - Password must be at least 8 characters - Domain must not already exist - Rate limited to 3 signups per hour per domain
Response (201 Created):
{
"success": true,
"token": "session-token-here",
"token_type": "user",
"email": "admin@yourdomain.com",
"name": "Your Name",
"domain": "yourdomain.com",
"domain_status": "pending",
"expires_at": "2026-02-15T22:00:00Z",
"message": "Account created! Your domain 'yourdomain.com' is pending admin approval."
}
Notes: - Domain is created with active=0 (pending admin approval) - User mailbox is active immediately (can log in) - User is auto-granted manage_domains permission on their domain - A session token is returned for auto-login
13. Bulk Grant Permissions¶
Grant multiple permissions to a user at once. Admin only.
Endpoint: POST /permissions/bulk
Request Body:
{
"email": "user@domain.com",
"permissions": ["manage_users", "manage_domains", "view_mailbox", "view_stats", "send_mail"],
"domain": "domain.com"
}
Available Permissions: | Permission | Description | |------------|-------------| | manage_users | Create, update, delete users in the domain | | manage_domains | View DNS config, verify records | | view_mailbox | Read emails of any user in the domain | | view_stats | View delivery statistics | | send_mail | Send email as any user in the domain |
Response (201 Created):
{
"success": true,
"message": "Granted 4 permissions, skipped 1 already existing",
"granted": ["manage_users", "view_mailbox", "view_stats", "send_mail"],
"skipped": ["manage_domains"]
}
14. List Pending Domains¶
List domains awaiting admin approval. Admin only.
Endpoint: GET /domains/pending
Response:
{
"success": true,
"total": 2,
"domains": [
{
"domain": "newdomain.com",
"active": false,
"created": "2026-02-15T10:00:00Z",
"creator_email": "admin@newdomain.com"
}
]
}
15. Approve Domain¶
Approve a pending domain, generating DKIM keys and activating it. Admin only.
Endpoint: POST /domains/{domain}/approve
Response:
{
"success": true,
"message": "Domain newdomain.com has been approved and activated",
"domain": "newdomain.com",
"active": true
}
Error Handling¶
All errors return a consistent JSON structure:
Common Error Codes¶
| Code | HTTP Status | Description |
|---|---|---|
NO_API_TOKEN | 401 | Missing X-MAILAPI-TOKEN header |
INVALID_TOKEN | 401 | Token not found or invalid |
TOKEN_EXPIRED | 401 | Token has expired or is inactive |
ACCESS_DENIED | 403 | Token doesn't have access to resource |
DOMAIN_NOT_ALLOWED | 403 | Sender domain not in allowed list |
SENDER_NOT_AUTHORIZED | 403 | Token can't send as this address |
MAILBOX_NOT_FOUND | 404 | Mailbox doesn't exist |
MESSAGE_NOT_FOUND | 404 | Message not found |
INVALID_FOLDER | 400 | Folder doesn't exist |
SEND_FAILED | 500 | Failed to send email |
IMAP_ERROR | 500 | IMAP connection error |
Example Error Handling - Python:¶
import requests
def send_email(data):
response = requests.post(
f"{API_URL}/mail/send",
json=data,
headers={"X-MAILAPI-TOKEN": TOKEN}
)
result = response.json()
if not result.get("success", False):
error_code = result.get("error", "UNKNOWN")
error_message = result.get("message", "Unknown error")
if error_code == "DOMAIN_NOT_ALLOWED":
print(f"Error: {error_message}")
print("Please use an email address from an allowed domain.")
elif error_code == "INVALID_TOKEN":
print("Error: Your API token is invalid.")
else:
print(f"Error ({error_code}): {error_message}")
return None
return result
Rate Limits¶
The API enforces rate limits to ensure fair usage:
- 100 requests per minute per token
- 1000 requests per hour per token
When rate limited, you'll receive a 429 Too Many Requests response.
Best Practices¶
-
Store tokens securely - Never expose tokens in client-side code or version control
-
Use user tokens when possible - For user-facing applications, create user tokens limited to specific mailboxes
-
Handle errors gracefully - Always check the
successfield and handle errors appropriately -
Implement retry logic - For transient errors (5xx), implement exponential backoff
-
Track message IDs - Store the
message_idreturned from/mail/sendto track delivery status -
Paginate large requests - Use
limitandoffsetparameters for listing endpoints -
Cache token info - Cache the result of
/tokens/meto reduce API calls
Support¶
- API Documentation (Interactive): https://mail-api.solutechhub.com/docs
- Alternative Documentation: https://mail-api.solutechhub.com/redoc
- Health Check: https://mail-api.solutechhub.com/health
For API token requests or issues, contact your system administrator.