Send a single email
Send a single transactional email. Returns 202 Accepted with the email ID.
Request body
| Field | Type | Required | Description |
|---|
from | string or { email, name } | ✅ | Sender address. Must belong to a verified domain. |
to | array | ✅ | Recipients (1–50). Each: { email, name? } |
cc | array | — | CC recipients (max 50) |
bcc | array | — | BCC recipients (max 50) |
replyTo | string | — | Reply-to address |
subject | string | ✅ | Subject line (1–998 characters) |
html | string | ✅* | HTML body (max 5 MB) |
text | string | ✅* | Plain text body (max 1 MB) |
headers | object | — | Custom email headers (key–value map) |
tags | string[] | — | Up to 10 tags (max 100 chars each) |
scheduledAt | string | — | ISO 8601 datetime (must be ≥ 1 min in the future) |
idempotencyKey | string | — | Unique key (max 255 chars). Also settable via X-Idempotency-Key header. |
attachments | array | — | Up to 10 attachments. Each: { filename, content, contentType? } |
metadata | object | — | Arbitrary JSON stored with the email |
* At least one of html or text is required.
The total number of recipients across to, cc, and bcc must not exceed 50.
Example
curl -X POST https://api.mail.gorillaa.one/v1/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": { "email": "[email protected]", "name": "Your App" },
"to": [
{ "email": "[email protected]", "name": "Alice" }
],
"subject": "Your invoice is ready",
"html": "<h1>Invoice #1234</h1><p>Your invoice is attached.</p>",
"text": "Invoice #1234 - Your invoice is attached.",
"tags": ["invoice", "billing"],
"metadata": { "invoiceId": "inv_1234", "userId": "usr_567" }
}'
const response = await fetch("https://api.mail.gorillaa.one/v1/emails", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: { email: "[email protected]", name: "Your App" },
to: [{ email: "[email protected]", name: "Alice" }],
subject: "Your invoice is ready",
html: "<h1>Invoice #1234</h1><p>Your invoice is attached.</p>",
tags: ["invoice", "billing"],
metadata: { invoiceId: "inv_1234", userId: "usr_567" },
}),
});
const data = await response.json();
// { data: { id: "em_abc123", status: "queued" } }
import requests
response = requests.post(
"https://api.mail.gorillaa.one/v1/emails",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"from": {"email": "[email protected]", "name": "Your App"},
"to": [{"email": "[email protected]", "name": "Alice"}],
"subject": "Your invoice is ready",
"html": "<h1>Invoice #1234</h1><p>Your invoice is attached.</p>",
"tags": ["invoice", "billing"],
"metadata": {"invoiceId": "inv_1234", "userId": "usr_567"},
},
)
print(response.json())
Response — 202 Accepted
{
"data": {
"id": "em_abc123",
"status": "queued"
}
}
If any recipients are on the suppression list, the response includes them:
{
"data": {
"id": "em_abc123",
"status": "queued",
"warnings": ["Some recipients are suppressed"],
"suppressedRecipients": [
{ "email": "[email protected]", "reason": "hard_bounce" }
]
}
}
For scheduled emails, scheduledAt is included in the response:
{
"data": {
"id": "em_abc123",
"status": "scheduled",
"scheduledAt": "2026-02-10T09:00:00Z"
}
}
Batch send
Send up to 100 emails in a single request. Each email in the array uses the same schema as a single send.
curl -X POST https://api.mail.gorillaa.one/v1/emails/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
{
"from": "[email protected]",
"to": [{ "email": "[email protected]" }],
"subject": "Welcome, Alice!",
"html": "<p>Welcome aboard!</p>"
},
{
"from": "[email protected]",
"to": [{ "email": "[email protected]" }],
"subject": "Welcome, Bob!",
"html": "<p>Welcome aboard!</p>"
}
]
}'
Response — 202 Accepted
{
"data": {
"data": [
{
"id": "em_abc123",
"emailId": "em_abc123",
"status": "queued",
"subject": "Welcome, Alice!",
"recipientCount": 1
},
{
"id": "em_def456",
"emailId": "em_def456",
"status": "queued",
"subject": "Welcome, Bob!",
"recipientCount": 1
}
],
"summary": {
"total": 2,
"successful": 2,
"failed": 0
}
}
}
If some emails fail validation, those entries will include an error object. Successfully validated emails are still queued.
Scheduling
Set the scheduledAt field to an ISO 8601 datetime to delay delivery:
{
"from": "[email protected]",
"to": [{ "email": "[email protected]" }],
"subject": "Scheduled email",
"html": "<p>This arrives later.</p>",
"scheduledAt": "2026-02-10T09:00:00Z"
}
scheduledAt must be at least 1 minute in the future. Dates in the past are rejected.
Idempotency
To prevent duplicate sends (e.g. on network retries), include an idempotency key:
curl -X POST https://api.mail.gorillaa.one/v1/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: order-confirmation-12345" \
-d '{ ... }'
Or pass it in the body as "idempotencyKey": "order-confirmation-12345".
- Duplicate requests within 24 hours return the original response.
- Keys must be unique per organization and ≤ 255 characters.
- Use meaningful keys like
order-confirmation-{orderId} or welcome-email-{userId}.
Attachments
Add up to 10 attachments per email. Content must be Base64-encoded.
{
"from": "[email protected]",
"to": [{ "email": "[email protected]" }],
"subject": "Your report",
"html": "<p>Please find your report attached.</p>",
"attachments": [
{
"filename": "report.pdf",
"content": "JVBERi0xLjQK...",
"contentType": "application/pdf"
}
]
}
| Field | Type | Required | Description |
|---|
filename | string | ✅ | Display name of the file (max 255 chars) |
content | string | ✅ | Base64-encoded file content |
contentType | string | — | MIME type (max 100 chars, e.g. application/pdf) |
Retrieve email status
curl https://api.mail.gorillaa.one/v1/emails/em_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
Response includes the full email object wrapped in data, with current status, sender/recipient details, timestamps, and associated events:
{
"data": {
"id": "em_abc123",
"organizationId": "org_xyz",
"status": "delivered",
"fromEmail": "[email protected]",
"fromName": "Your App",
"toEmails": ["[email protected]"],
"ccEmails": [],
"bccEmails": [],
"subject": "Your invoice is ready",
"createdAt": "2026-02-09T10:00:00Z",
"sentAt": "2026-02-09T10:00:02Z",
"deliveredAt": "2026-02-09T10:00:05Z",
"events": [
{ "type": "queued", "timestamp": "2026-02-09T10:00:00Z" },
{ "type": "sent", "timestamp": "2026-02-09T10:00:02Z" },
{ "type": "delivered", "timestamp": "2026-02-09T10:00:05Z" }
]
}
}
List emails
| Parameter | Type | Default | Description |
|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
status | string | — | Filter: scheduled, queued, sending, sent, delivered, bounced, failed |
from | string | — | Filter by sender email or domain |
startDate | string | — | ISO 8601 datetime — return emails created after this date |
endDate | string | — | ISO 8601 datetime — return emails created before this date |
curl "https://api.mail.gorillaa.one/v1/emails?status=delivered&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
Response
{
"data": [
{
"id": "em_abc123",
"status": "delivered",
"fromEmail": "[email protected]",
"subject": "Your invoice is ready",
"createdAt": "2026-02-09T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 47,
"totalPages": 5
}
}