Appearance
Outbound Email
/api
The Outbound Email API lets you send email from Mailisk namespaces, reply to inbound emails, forward inbound emails, and inspect delivery status and provider events.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /api/emails/send | Send a new outbound email |
GET | /api/emails/outbound/{outboundEmailId} | Get outbound email status |
POST | /api/emails/{emailId}/reply | Reply to an inbound email |
POST | /api/emails/{emailId}/forward | Forward an inbound email |
Sending rules
- Recipients must be verified external destinations or addresses under the same namespace.
- Sender overrides must belong to the requested namespace, for example
support@mynamespace.mailisk.net. - If
fromis omitted, Mailisk sends fromoutbound-delivery@{namespace}.mailisk.net. - New outbound emails and replies require at least one recipient and either
htmlortextcontent. - Messages sent only to same-namespace recipients do not consume outbound usage because they are counted as inbound email when delivered. Messages with any external recipient consume outbound usage.
- Attachments must be base64 encoded. Use
application/octet-streamwhen you need the file to remain a downloadable attachment across mail clients and parsers. - Outbound emails can include at most 20 attachments, and the total encoded message size must not exceed 5 MB.
Send Outbound Email
POST /api/emails/send
This endpoint creates and queues a new outbound email from a namespace.
sh
curl --request POST \
--url 'https://api.mailisk.com/api/emails/send?namespace=mynamespace' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: {Api Key}' \
--data '{
"from": {
"email": "support@mynamespace.mailisk.net",
"name": "Support"
},
"to": ["customer@mynamespace.mailisk.net"],
"subject": "Hello from Mailisk",
"text": "This is the plain text body.",
"html": "<p>This is the HTML body.</p>"
}'js
const outboundEmail = await mailisk.sendEmail("mynamespace", {
from: {
email: "support@mynamespace.mailisk.net",
name: "Support",
},
to: ["customer@mynamespace.mailisk.net"],
subject: "Hello from Mailisk",
text: "This is the plain text body.",
html: "<p>This is the HTML body.</p>",
});Query
| Name | Required | Type | Description |
|---|---|---|---|
namespace | Required | String | The namespace to send from. |
Body
| Name | Required | Type | Description |
|---|---|---|---|
from | Optional | OutboundEmailAddress | Sender override. The email address must belong to the requested namespace. |
reply_to | Optional | OutboundEmailAddress | Reply-To address for the outbound message. |
to | Optional | String[] | Primary recipients. At least one recipient across to, cc, or bcc is required. |
cc | Optional | String[] | Carbon copy recipients. |
bcc | Optional | String[] | Blind carbon copy recipients. |
subject | Required | String | Email subject. Maximum length is 998 characters. |
html | Optional | String | HTML body. Either html or text is required. |
text | Optional | String | Plain text body. Either html or text is required. |
attachments | Optional | OutboundEmailAttachment[] | Attachments encoded with base64 content. At most 20 attachments are allowed. |
Sending attachments
Encode file bytes as base64 in content_base64.
js
const fs = require("node:fs");
const content = fs.readFileSync("report.txt");
await mailisk.sendEmail("mynamespace", {
to: ["customer@mynamespace.mailisk.net"],
subject: "Report",
text: "Attached.",
attachments: [
{
filename: "report.txt",
content_type: "application/octet-stream",
content_base64: content.toString("base64"),
},
],
});When sending to a same-namespace address, use Search Inbox and Get Attachment to confirm that the message and attachment arrived.
Response
json
{
"id": "5a6205b2-2538-4744-b63f-f43e3d60b79f",
"organisation_id": "67f3dcb7-a707-422b-a907-5da53f026fe3",
"type": "new",
"status": "queued",
"from": {
"email": "support@mynamespace.mailisk.net",
"name": "Support"
},
"subject": "Hello from Mailisk",
"recipient_count": 1,
"attachment_count": 0,
"message_id": "<5a6205b2-2538-4744-b63f-f43e3d60b79f@mynamespace.mailisk.net>",
"queued_at": "2026-04-28T08:24:58.000Z",
"created_at": "2026-04-28T08:24:58.000Z",
"updated_at": "2026-04-28T08:24:58.000Z"
}Get Outbound Email
GET /api/emails/outbound/{outboundEmailId}
This endpoint returns the current delivery state for an outbound email, including recipient statuses, a delivery summary, and provider delivery events.
sh
curl --request GET \
--url https://api.mailisk.com/api/emails/outbound/{outboundEmailId} \
--header 'Accept: application/json' \
--header 'X-Api-Key: {Api Key}'js
const outboundEmail = await mailisk.getOutboundEmail(outboundEmailId);Path Params
| Name | Description |
|---|---|
outboundEmailId | The outbound email UUID to fetch. |
Response
json
{
"id": "5a6205b2-2538-4744-b63f-f43e3d60b79f",
"organisation_id": "67f3dcb7-a707-422b-a907-5da53f026fe3",
"type": "new",
"status": "sent",
"from": {
"email": "support@mynamespace.mailisk.net",
"name": "Support"
},
"subject": "Hello from Mailisk",
"recipient_count": 1,
"attachment_count": 0,
"message_id": "<5a6205b2-2538-4744-b63f-f43e3d60b79f@mynamespace.mailisk.net>",
"provider": "mailisk",
"provider_message_id": "provider-message-id",
"queued_at": "2026-04-28T08:24:58.000Z",
"sent_at": "2026-04-28T08:25:01.000Z",
"created_at": "2026-04-28T08:24:58.000Z",
"updated_at": "2026-04-28T08:25:01.000Z",
"delivery_summary": {
"pending": 0,
"accepted": 0,
"queued": 0,
"sent": 1,
"delayed": 0,
"deferred": 0,
"delivered": 0,
"bounced": 0,
"expired": 0,
"complained": 0,
"unsubscribed": 0,
"suppressed": 0,
"rejected": 0,
"failed": 0,
"cancelled": 0
},
"recipients": [
{
"id": "af0957ab-45bb-4b71-8b84-041407a9e13a",
"type": "to",
"email": "customer@mynamespace.mailisk.net",
"delivery_status": "sent",
"sent_at": "2026-04-28T08:25:01.000Z",
"attempt_count": 1
}
],
"events": [
{
"id": "e049fd60-49fb-46c6-9bf5-4453c5ebfc4d",
"provider": "mailisk",
"provider_message_id": "provider-message-id",
"provider_event_id": "provider-event-id",
"event_type": "delivered",
"occurred_at": "2026-04-28T08:25:03.000Z",
"recipients": [
{
"id": "9c9aa979-4674-4750-a952-6d7b235418d8",
"outbound_email_recipient_id": "af0957ab-45bb-4b71-8b84-041407a9e13a",
"email": "customer@mynamespace.mailisk.net",
"attempt_count": 1
}
],
"created_at": "2026-04-28T08:25:03.000Z"
}
]
}Reply to Email
POST /api/emails/{emailId}/reply
This endpoint creates and queues a reply to an inbound email. Mailisk derives the reply recipient and threading headers from the source email. If subject is omitted, Mailisk uses Re: {original subject}.
sh
curl --request POST \
--url https://api.mailisk.com/api/emails/{emailId}/reply \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: {Api Key}' \
--data '{
"text": "Thanks, we received your message."
}'js
const reply = await mailisk.replyToEmail(emailId, {
text: "Thanks, we received your message.",
});Path Params
| Name | Description |
|---|---|
emailId | The inbound email ID returned by Search Inbox. |
Body
| Name | Required | Type | Description |
|---|---|---|---|
from | Optional | OutboundEmailAddress | Sender override. The email address must belong to the inbound email namespace. |
cc | Optional | String[] | Carbon copy recipients. |
bcc | Optional | String[] | Blind carbon copy recipients. |
subject | Optional | String | Reply subject. Defaults to Re: {original subject}. |
html | Optional | String | HTML reply body. Either html or text is required. |
text | Optional | String | Plain text reply body. Either html or text is required. |
attachments | Optional | OutboundEmailAttachment[] | Reply attachments encoded with base64 content. At most 20 attachments are allowed. |
Response
Returns an OutboundEmailResponse. See the Send Outbound Email response for the common response shape.
Forward an Email
POST /api/emails/{emailId}/forward
This endpoint creates and queues a forwarded copy of an inbound email. The to list is required. Optional html or text content is prepended before the forwarded message.
sh
curl --request POST \
--url https://api.mailisk.com/api/emails/{emailId}/forward \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: {Api Key}' \
--data '{
"to": ["customer@mynamespace.mailisk.net"],
"text": "Forwarding this along."
}'js
const forwarded = await mailisk.forwardEmail(emailId, {
to: ["customer@mynamespace.mailisk.net"],
text: "Forwarding this along.",
});Path Params
| Name | Description |
|---|---|
emailId | The inbound email ID returned by Search Inbox. |
Body
| Name | Required | Type | Description |
|---|---|---|---|
from | Optional | OutboundEmailAddress | Sender override. The email address must belong to the inbound email namespace. |
to | Required | String[] | Recipients to forward the message to. |
cc | Optional | String[] | Carbon copy recipients. |
bcc | Optional | String[] | Blind carbon copy recipients. |
subject | Optional | String | Forwarded email subject. Defaults to Fwd: {original subject}. |
html | Optional | String | Optional HTML content to prefix before the forwarded message. |
text | Optional | String | Optional plain text content to prefix before the forwarded message. |
Response
Returns an OutboundEmailResponse. See the Send Outbound Email response for the common response shape.
Typescript types
typescript
type OutboundEmailType = 'new' | 'reply' | 'forward';
type OutboundEmailStatus = 'queued' | 'sending' | 'sent' | 'failed';
type OutboundEmailRecipientType = 'to' | 'cc' | 'bcc';
type OutboundEmailRecipientDeliveryStatus =
| 'pending'
| 'accepted'
| 'queued'
| 'sent'
| 'delayed'
| 'deferred'
| 'delivered'
| 'bounced'
| 'expired'
| 'complained'
| 'unsubscribed'
| 'suppressed'
| 'rejected'
| 'failed'
| 'cancelled';
type OutboundEmailEventType =
| 'accepted'
| 'queued'
| 'sent'
| 'failed'
| 'rejected'
| 'delayed'
| 'deferred'
| 'delivered'
| 'bounced'
| 'expired'
| 'complained'
| 'unsubscribed'
| 'suppressed'
| 'cancelled'
| 'opened'
| 'clicked';
interface OutboundEmailAddress {
/** Email address */
email: string;
/** Display name, if one is specified */
name?: string;
}
interface OutboundEmailAttachment {
/** Attachment filename shown to recipients */
filename: string;
/** MIME type for the attachment */
content_type: string;
/** Base64 encoded file bytes */
content_base64: string;
/** Optional Content-ID for inline attachments */
content_id?: string;
/** Attachment disposition */
disposition?: 'attachment' | 'inline';
}
interface SendOutboundEmailRequest {
from?: OutboundEmailAddress;
reply_to?: OutboundEmailAddress;
to?: string[];
cc?: string[];
bcc?: string[];
subject: string;
html?: string;
text?: string;
attachments?: OutboundEmailAttachment[];
}
interface ReplyOutboundEmailRequest {
from?: OutboundEmailAddress;
cc?: string[];
bcc?: string[];
subject?: string;
html?: string;
text?: string;
attachments?: OutboundEmailAttachment[];
}
interface ForwardOutboundEmailRequest {
from?: OutboundEmailAddress;
to: string[];
cc?: string[];
bcc?: string[];
subject?: string;
html?: string;
text?: string;
}
interface OutboundEmailResponse {
/** Unique identifier for the outbound email */
id: string;
/** Unique identifier for the organisation */
organisation_id: string;
/** Outbound email type */
type: OutboundEmailType;
/** Current email queue status */
status: OutboundEmailStatus;
/** Sender */
from: OutboundEmailAddress;
/** Reply-To address */
reply_to?: OutboundEmailAddress;
/** Subject */
subject: string;
/** Number of recipients */
recipient_count: number;
/** Number of attachments */
attachment_count: number;
/** Message-ID header */
message_id: string;
/** Delivery provider name */
provider?: string;
/** Provider message ID */
provider_message_id?: string;
/** Failure reason if the message failed */
failure_reason?: string;
queued_at: string;
sending_at?: string;
sent_at?: string;
failed_at?: string;
created_at: string;
updated_at: string;
}
interface OutboundEmailDeliverySummary {
pending: number;
accepted: number;
queued: number;
sent: number;
delayed: number;
deferred: number;
delivered: number;
bounced: number;
expired: number;
complained: number;
unsubscribed: number;
suppressed: number;
rejected: number;
failed: number;
cancelled: number;
}
interface OutboundEmailRecipient {
id: string;
type: OutboundEmailRecipientType;
email: string;
name?: string;
delivery_status: OutboundEmailRecipientDeliveryStatus;
last_event_type?: string;
last_event_at?: string;
accepted_at?: string;
queued_at?: string;
sent_at?: string;
delayed_at?: string;
deferred_at?: string;
delivered_at?: string;
bounced_at?: string;
expired_at?: string;
complained_at?: string;
unsubscribed_at?: string;
suppressed_at?: string;
rejected_at?: string;
failed_at?: string;
cancelled_at?: string;
last_smtp_code?: string;
last_enhanced_status_code?: string;
last_smtp_response?: string;
attempt_count: number;
bounce_type?: string;
bounce_subtype?: string;
bounce_classification?: string;
complaint_feedback_type?: string;
}
interface OutboundEmailDetailResponse extends OutboundEmailResponse {
delivery_summary: OutboundEmailDeliverySummary;
recipients: OutboundEmailRecipient[];
events: OutboundEmailEvent[];
}
interface OutboundEmailEventRecipient {
id: string;
outbound_email_recipient_id?: string;
email: string;
smtp_code?: string;
enhanced_status_code?: string;
smtp_response?: string;
diagnostic_code?: string;
action?: string;
attempt_count?: number;
bounce_classification?: string;
}
interface OutboundEmailEvent {
id: string;
provider: string;
provider_message_id?: string;
provider_event_id?: string;
event_type: OutboundEmailEventType;
event_subtype?: string;
occurred_at: string;
recipients: OutboundEmailEventRecipient[];
created_at: string;
}