Reference

API reference

This page provides the complete reference for MailLaser's webhook payload format and SMTP protocol behavior.


EmailPayload JSON schema

Every webhook delivery sends a JSON object with this structure:

{
  "sender": "string (required)",
  "sender_name": "string (optional)",
  "recipient": "string (required)",
  "subject": "string (required)",
  "body": "string (required)",
  "html_body": "string (optional)",
  "headers": "object (optional)"
}

Field reference

FieldTypeRequiredSerializationDescription
senderStringYesAlways presentEmail address from the SMTP MAIL FROM command.
sender_nameOption<String>NoOmitted when NoneDisplay name from the From: header. For example, "John Doe" from John Doe <john@example.com>. None when the From: header contains only an address or is absent.
recipientStringYesAlways presentEmail address from the SMTP RCPT TO command that matched a configured target.
subjectStringYesAlways presentValue of the Subject: header. Empty string if the header is missing.
bodyStringYesAlways presentPlain text email body. If the email has a text/html part, this is generated from that HTML using html2text (80-character width). If the email has a text/plain part and no HTML, this contains the raw text. Empty string if neither is found.
html_bodyOption<String>NoOmitted when NoneRaw HTML content from the text/html MIME part. None when the email has no HTML content.
headersOption<HashMap<String, String>>NoOmitted when NoneKey-value map of email headers matching the configured MAIL_LASER_HEADER_PREFIX prefixes. None when no prefixes are configured or no headers match.

Serialization behavior

Optional fields use #[serde(skip_serializing_if = "Option::is_none")]. When a field has no value, it is absent from the JSON rather than set to null.

Minimal payload (plain text email, no display name, no header passthrough):

{
  "sender": "user@example.com",
  "recipient": "alerts@myapp.com",
  "subject": "Test",
  "body": "Hello world"
}

Maximal payload (all optional fields present):

{
  "sender": "user@example.com",
  "sender_name": "Jane Smith",
  "recipient": "alerts@myapp.com",
  "subject": "Monthly Report",
  "body": "Please review the attached report.\n\nBest regards,\nJane",
  "html_body": "<html><body><p>Please review the attached report.</p><p>Best regards,<br>Jane</p></body></html>",
  "headers": {
    "X-Priority": "1",
    "X-Request-Id": "abc-123-def"
  }
}

HTTP request details

PropertyValue
MethodPOST
Content-Typeapplication/json
User-AgentMailLaser/2.0.0
BodyJSON-serialized EmailPayload

The User-Agent value is derived from Cargo.toml at compile time using env!("CARGO_PKG_NAME") and env!("CARGO_PKG_VERSION").


SMTP command reference

Greeting

Server responseMeaning
220 MailLaser SMTP Server ReadyConnection accepted, waiting for EHLO/HELO.

EHLO / HELO

CommandServer responseNext state
EHLO domain250-MailLaser greets domain then 250 STARTTLSGreeted
HELO domain250 MailLaserGreeted

EHLO without a domain uses client as the default.

STARTTLS

CommandState requiredServer responseEffect
STARTTLSGreeted220 Go aheadTLS handshake begins. Client must re-send EHLO/HELO after handshake.
STARTTLSAny other state503 Bad sequence of commandsNo effect.
STARTTLSAlready in TLS503 STARTTLS already activeNo effect.

MAIL FROM

CommandState requiredServer responseEffect
MAIL FROM:<user@example.com>Greeted250 OKSender recorded. Transitions to MailFrom state.
MAIL FROM: (empty)Greeted501 Syntax error in MAIL FROM parametersNo state change.

RCPT TO

CommandState requiredServer responseEffect
RCPT TO:<match@target.com>MailFrom or RcptTo250 OKRecipient accepted. Transitions to RcptTo state.
RCPT TO:<unknown@other.com>MailFrom or RcptTo550 No such user hereRecipient rejected. Accepted recipient cleared.

DATA

CommandState requiredServer responseEffect
DATARcptTo (with valid sender and recipient)354 Start mail input; end with <CRLF>.<CRLF>Transitions to Data state.
DATAWithout valid MAIL FROM/RCPT TO503 Bad sequence of commandsNo state change.
. (end of data)Data250 OK: Message accepted for deliveryEmail parsed and forwarded. State resets to Greeted.

QUIT

CommandState requiredServer responseEffect
QUITAny (except Data)221 ByeConnection closed.
QUITDataTreated as a data linePart of email body.

Health check endpoint

PropertyValue
PathGET /health (any HTTP method accepted)
Success response200 OK (empty body)
Other paths404 Not Found (body: Not Found)
Default port8080
Previous
DNS and network setup