Send mail

POST /members/send sends one email in a project. The effective principal needs active project membership and mail.send. Use the production base and JSON request format with a Bearer access token and, when needed, an organization selection.

Request fields

Field Type Required/default Meaning
project_id UUID string Required for normal requests Project returned by project creation or listing.
method string Defaults to email email or blank uses email; other delivery methods fail with 400.
sender_email string Required From email address; alias from_email.
recipient_email string Required One recipient email address; alias to_email.
sender_name string or null Optional From display name; alias from_name. Blank/omitted uses the service's configured display name when available.
recipient_name string or null Optional Recipient display name; alias to_name.
reply_to_email string or null Optional Reply-To address.
subject string Defaults to an empty string Subject line.
body_text string or null At least one nonblank body Plain text; alias body.
body_html string or null At least one nonblank body HTML; when supplied alone, a plain-text alternative is derived.

Use canonical fields consistently. Email addresses are trimmed, validated, and lowercased. Display names and subject are trimmed and must not contain CR/LF characters. Body line endings normalize to LF; wholly blank bodies are treated as absent. Supplying both text and HTML creates alternatives. Sender and Reply-To fields describe the message; they do not select its owner or grant sending authority.

{
  "project_id":"<project-uuid>",
  "sender_email":"sender@example.com",
  "sender_name":"Example App",
  "recipient_email":"recipient@example.com",
  "subject":"Your receipt",
  "body_text":"Thank you for your order."
}

Normal callers must provide project_id. A machine deployment may have a server-configured default project; omission works only for an app principal with that configuration. The default does not grant membership or mail.send. Include the explicit project ID in portable integrations.

The service sets the owner, actor, and source. Caller-supplied owner, actor, owner_scope, organization_id, and client_id fail with 400. Use only documented message and workspace fields.

Queue response and logging

A successful response has status: 1, comment: "OK", and these data fields:

Field Meaning
success true when accepted by the mail transport.
method, provider, transport email, postfix, and sendmail.
status, queued queued and true; no recipient-delivery confirmation.
logged Whether an outbound-attempt record was stored.
item Stored log record when available; otherwise an empty object/array.
message_id Composed message identifier, or null.
log_error null when logging succeeded; error detail when logging failed.
{
  "status":1,
  "comment":"OK",
  "data":{
    "success":true,"method":"email","provider":"postfix",
    "transport":"sendmail","status":"queued","queued":true,
    "logged":false,"item":[],"message_id":"<message-id>",
    "log_error":"<logging-error>"
  }
}

Transport failure returns an error and attempts to store a failed record. A message can be accepted even if logging fails; logged: false is not a send failure. Keep queue acceptance and log persistence as separate outcomes.

Retry handling

The API does not provide an idempotency key or deduplication guarantee. A timeout or connection loss may occur after transport acceptance. A repeated send can produce another message. Reconcile with your application state and project logs before deciding to resend; absence of a log alone cannot prove the message was not queued.