Skip to content

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 ​

MethodEndpointDescription
POST/api/emails/sendSend a new outbound email
GET/api/emails/outbound/{outboundEmailId}Get outbound email status
POST/api/emails/{emailId}/replyReply to an inbound email
POST/api/emails/{emailId}/forwardForward 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 from is omitted, Mailisk sends from outbound-delivery@{namespace}.mailisk.net.
  • New outbound emails and replies require at least one recipient and either html or text content.
  • The outbound email entitlement allows at most 4 total recipients across to, cc, and bcc. For replies, the recipient derived from the source email counts toward this limit.
  • 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-stream when 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 ​

NameRequiredTypeDescription
namespaceRequiredStringThe namespace to send from.

Body ​

NameRequiredTypeDescription
fromOptionalOutboundEmailAddressSender override. The email address must belong to the requested namespace.
reply_toOptionalOutboundEmailAddressReply-To address for the outbound message.
toOptionalString[]Primary recipients. At least one recipient across to, cc, or bcc is required.
ccOptionalString[]Carbon copy recipients.
bccOptionalString[]Blind carbon copy recipients.
subjectRequiredStringEmail subject. Maximum length is 998 characters.
htmlOptionalStringHTML body. Either html or text is required.
textOptionalStringPlain text body. Either html or text is required.
attachmentsOptionalOutboundEmailAttachment[]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 ​

NameDescription
outboundEmailIdThe 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 ​

NameDescription
emailIdThe inbound email ID returned by Search Inbox.

Body ​

NameRequiredTypeDescription
fromOptionalOutboundEmailAddressSender override. The email address must belong to the inbound email namespace.
ccOptionalString[]Carbon copy recipients.
bccOptionalString[]Blind carbon copy recipients.
subjectOptionalStringReply subject. Defaults to Re: {original subject}.
htmlOptionalStringHTML reply body. Either html or text is required.
textOptionalStringPlain text reply body. Either html or text is required.
attachmentsOptionalOutboundEmailAttachment[]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 ​

NameDescription
emailIdThe inbound email ID returned by Search Inbox.

Body ​

NameRequiredTypeDescription
fromOptionalOutboundEmailAddressSender override. The email address must belong to the inbound email namespace.
toRequiredString[]Recipients to forward the message to.
ccOptionalString[]Carbon copy recipients.
bccOptionalString[]Blind carbon copy recipients.
subjectOptionalStringForwarded email subject. Defaults to Fwd: {original subject}.
htmlOptionalStringOptional HTML content to prefix before the forwarded message.
textOptionalStringOptional 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;
}