Ware SendDeveloper Documentation
API v1Engine 1.3.3HTTP / SMTP

Developer Documentation

Public reference for integrating your application with Ware Send through HTTP API v1 or SMTP Submission for legacy systems. This page documents only the public integration contract and does not expose licensing, installation, or private infrastructure internals.

QUICK START

First send

Use the URL provided during Ware Send deployment and a valid Bearer credential.

Base URL

Examples use https://mail.yourdomain.com. Replace it with the FQDN configured for your installation.

cURL
curl -X POST "https://mail.seudominio.com.br/api/v1/send" \
  -H "Authorization: Bearer $WARESEND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from_name": "Minha Empresa",
    "from_email": "notificacoes@seudominio.com.br",
    "to": ["cliente@example.com"],
    "subject": "Pedido confirmado",
    "html": "<h1>Pedido confirmado</h1>",
    "text": "Pedido confirmado"
  }'
202 Accepted
{
  "ok": true,
  "queued": true,
  "status": "accepted",
  "queue_id": "wsq_...",
  "message_id": "<...@mail.seudominio.com.br>",
  "accepted_at": "2026-08-24T03:00:00Z",
  "cost_class": "tiny",
  "version": "1.3.3"
}
What does accepted mean?

Ware Send validated and persisted the work in its durable queue and assumed responsibility for processing. It does not mean the recipient server has already confirmed delivery.

AUTHENTICATION

Bearer token

Protected endpoints require the credential in the HTTP Authorization header.

HTTP Header
Authorization: Bearer <TOKEN>
Use it on the backend

Do not expose the credential in public JavaScript, distributed applications or source code accessible to end users.

Credential delivery

The Bearer credential is delivered securely, with one-time viewing, to the technical owner or developer designated during integration deployment.

Need a new token?

Request a new credential from DB Ware or the authorized Ware Send installation owner. The previous token cannot be recovered; after the change, the old credential should be revoked.

ENDPOINTS

Quick reference

POST/api/v1/send

Receives and persists a message for asynchronous processing.

Bearer
GET/api/v1/info

Capabilities and limits announced by the installed Engine.

Bearer
GET/api/v1/messages/status?message_id=...

Queries the known state of an accepted message.

Bearer
GET/api/v1/engine/status

Operational snapshot of the engine, queue, resources and campaigns.

Bearer
GET/api/v1/engine/activity

Current activity and recent Engine events.

Bearer
GET/api/v1/engine/analytics

Time-series and operational aggregates for throughput, queue, resources, scheduler, domains and campaigns.

Bearer
GET/health

Basic service health.

Public
GET/ready

Operational readiness for license, queue, Postfix and DKIM.

Public

SEND MESSAGE

Send a message

Send UTF-8 JSON to /api/v1/send. The API validates, persists and responds asynchronously.

POST/api/v1/sendBearer

PAYLOAD

Send fields

The fields below form the current public API v1 contract.

FieldTypeRequiredDescription
from_namestringNoFriendly sender name.
from_emailstringYesAuthorized sender address for the configured domain.
tostring | arrayNoPrimary recipient. Accepts one e-mail address as a string or multiple addresses as an array.
ccstring | arrayNoCarbon-copy recipient. Accepts a string or an array.
bccstring | arrayNoBlind-copy recipient. Accepts a string or an array and is never exposed in a visible header.
to_visiblebooleanNoControls recipient visibility. Optional; default false. false isolates each recipient; true allows shared To/Cc headers. Bcc is never shown.
reply_tostringNoOptional Reply-To address.
subjectstringYesMessage subject.
htmlstringNoHTML body.
textstringNoPlain-text body.
tenantstringNoLogical identifier for the application, customer or integration context.
campaign_idstringNoLogical identifier used to group operational activity for a campaign.
campaign_report_emailstringNoOptional e-mail destination for the campaign completion report. Requires campaign_id; the address remains bound to that campaign while its state exists.
idempotency_keystringNoStable key used to prevent accidental resubmission of the same request.
headersobjectNoAdditional non-reserved headers. Structural email headers are controlled by the Engine.
attachmentsarrayNoRegular or inline/CID attachments.

* At least one recipient is required among to, cc and bcc, and at least one body is required between html and text. In the HTTP API, to/cc/bcc accept a string or an array and there is no application-level recipient-count ceiling; request size and host resources remain practical bounds. SMTP Submission has an independent limit announced by GET /api/v1/info.

RECIPIENT PRIVACY

Private by default for multi-recipient sends

Recipient lists in the API are routing input for the Engine. Supplying many addresses in one payload does not authorize Ware Send to expose that list to recipients.

Default · to_visible=false
{
  "to": [
    "empresa-a@example.com",
    "empresa-b@example.com",
    "empresa-c@example.com"
  ],
  "subject": "Comunicado",
  "html": "<p>Olá</p>"
}
Safe default: to_visible = false

When to_visible is omitted or false, the Engine performs internal fan-out and materializes an individual delivery for each recipient. The received message shows only that recipient in To:; all other to, cc and bcc addresses remain hidden.

Explicit opt-in · to_visible=true
{
  "to": ["a@example.com", "b@example.com"],
  "cc": ["c@example.com"],
  "to_visible": true,
  "subject": "Reunião compartilhada",
  "text": "Mensagem"
}
Visibility requires explicit opt-in

Only to_visible:true allows the request To and Cc lists to appear together in visible headers. Use this mode only when all participants are allowed to know the other addresses.

Bcc is never visible

Bcc remains envelope-only. The Engine never emits a visible Bcc header, including when to_visible=true.

Fan-out is the Engine responsibility

The HTTP API has no application-level recipient-count ceiling. The Engine splits and processes the accepted set internally. Request size and host resources are practical bounds; SMTP Submission has its own independent limit.

Jobs and recipients are different metrics

A request containing many addresses is still one logical job but contains multiple recipients. Use accepted_recipients_total and postfix_queued_recipients_total for recipient volume; accepted_total and postfix_queued_total count jobs.

ATTACHMENTS

Attachments and inline images

API v1 remains compatible with Base64 attachments. After acceptance, the Engine persists content as a Blob and processes delivery asynchronously.

Regular attachment
{
  "filename": "fatura.pdf",
  "content_type": "application/pdf",
  "content_base64": "JVBERi0xLjQK..."
}
Inline image / CID
{
  "html": "<img src=\"cid:logo_empresa\" alt=\"Logo\">",
  "attachments": [{
    "filename": "logo.png",
    "content_type": "image/png",
    "content_base64": "iVBORw0KGgoAAA...",
    "cid": "logo_empresa",
    "inline": true
  }]
}
Main rules

filename and content_base64 are required for each attachment. Inline attachments require a valid cid and an HTML body. Duplicate CIDs in the same message are rejected.

RELIABILITY

Idempotency and campaigns

idempotency_key

Use a predictable key per logical event. If the same request has already been accepted, Ware Send may return the previous reference with duplicate: true without creating new work.

campaign_id

Groups operational activity for large campaigns and lets you track accepted, processed, retries and failures in the Engine snapshot.

campaign_report_email

Bind campaign_report_email to campaign_id to automatically receive a completion summary and detailed HTML report. Its delivery semantics end at Postfix handoff, not inbox placement.

Idempotency in progress

If another request with the same key is still being consolidated, the API may return 409 Conflict. Wait and query or resend using the same key.

CAMPAIGN COMPLETION

Campaign completion report

When campaign_report_email is supplied with campaign_id, Ware Send tracks that campaign until Engine-terminal state and sends a styled HTML summary to the configured address with one self-contained detailed HTML attachment.

POST /api/v1/send
{
  "tenant": "erp-production",
  "campaign_id": "invoice-batch-2026-08-26",
  "campaign_report_email": "mail-ops@example.com",
  "from_email": "billing@example.com",
  "to": ["customer@example.net"],
  "subject": "Invoice",
  "text": "Your invoice is attached."
}
202 Accepted
{
  "ok": true,
  "status": "accepted",
  "message_id": "wsm_...",
  "campaign_report_requested": true,
  "version": "1.3.3"
}
Field rule

The field is optional. When supplied, campaign_id is required. The same campaign_id cannot silently switch report destination while campaign state exists; use a unique ID per logical campaign.

When the report is issued

After all accepted campaign jobs are POSTFIX_QUEUED or terminal Engine failures and no new campaign work is accepted during the configured quiet period (default: 60 seconds). Later work may produce a new revision.

What it certifies

The report certifies Ware Send completion and local Postfix handoff, including Queue-ID where available. It is not an inbox receipt. Remote delivery, defer, bounce and provider classification require MTA/DSN evidence.

What the customer receives

The e-mail body contains a styled summary; the attached HTML details campaign/tenant, accepted jobs and recipients, bytes, Postfix handoff, failures, retries, Queue-IDs, per-domain distribution and revision. Tokens, passwords, license secrets and message bodies are excluded.

OBSERVABILITY

Message and engine status

The endpoints below let you observe execution without directly accessing the VPS.

GET/api/v1/messages/status?message_id=...Bearer

Returns the latest known state for the indicated message.

Example
{
  "ok": true,
  "message_id": "<...@mail.seudominio.com.br>",
  "queue_id": "wsq_...",
  "state": "POSTFIX_QUEUED",
  "stage": "POSTFIX_OWNS_MESSAGE",
  "postfix_queue_id": "4ABC123DEF",
  "cost_class": "tiny",
  "recipients": 1,
  "attempts": 0,
  "version": "1.3.3"
}
GET/api/v1/engine/statusBearer

Broad Engine snapshot: backlog, workers, ingress and egress rates, resources, Postfix queue, adaptive state, recent activity and campaigns.

GET/api/v1/engine/activityBearer

Reduced view for frequent monitoring: adaptive state, pending work, active jobs, recent events and throughput.

GET/api/v1/engine/analyticsBearer

Time-series and operational aggregates for throughput, queue, resources, scheduler, domains and campaigns.

ACCEPTEDQUEUEDMATERIALIZINGPOSTFIX_QUEUED

API v1 currently tracks Ware Send responsibility precisely through Postfix acceptance. Final per-recipient confirmation, DSN/bounce and remote-delivery states will be documented when they become part of the public contract.

HTTP

Responses and errors

HTTPMeaningRecommended handling
202Message accepted and persisted.Store message_id and queue_id when you need to track processing.
200Successful query or idempotent send already accepted.For duplicates, inspect duplicate: true.
400Invalid JSON or fields.Fix the payload. Unknown fields are also rejected.
401Credential missing, invalid or revoked.Check the Bearer token configured by the application.
403Installation has no operational license.Contact the person responsible for the Ware Send installation.
409Idempotency key is already being processed.Wait and retry using the same key.
503Queue unavailable or temporary backpressure.Honor Retry-After when present and retry with backoff.
Authentication error
{
  "ok": false,
  "error": "unauthorized"
}

LEGACY SYSTEMS

SMTP Submission

For legacy systems that cannot consume an HTTP API, Ware Send provides authenticated SMTP Submission. SMTP enters the same engine, queue, scheduler, workers and Postfix path used by the API; there is no separate delivery pipeline.

Available in Engine 1.0.0

SMTP Submission is authenticated application ingress only. It is not inbound MX, mailbox, POP3, IMAP or webmail; port 25 remains part of the MTA/Postfix role.

SMTPmail.seudominio.com.br:587 / :465TLS + AUTH

Use the installation FQDN with port 587 + STARTTLS or port 465 + implicit TLS. Authentication is mandatory and uses one installation-wide SMTP password, separate from the API. The canonical address derived from the customer domain (for example, example@example.com) is the default identity only: the same password can authenticate any full mailbox in that domain, such as contact@example.com, billing@example.com or nfe@example.com. The canonical short alias (example) remains available for AUTH only. Other domains are rejected and MAIL FROM remains subject to the authorized sender domain. API Bearer tokens do not authenticate SMTP.

Hostmail.seudominio.com.br
Port587 / 465
SecuritySTARTTLS / implicit TLS
AuthenticationAUTH PLAIN / AUTH LOGIN
Usernameexample@example.com
PasswordDedicated SMTP password delivered during deployment or rotation; do not use the API ws_live_ Bearer token.
TLS is mandatory on both ports

On port 587, connect using SMTP and negotiate STARTTLS before AUTH. On port 465, TLS starts immediately when the connection is opened. Ware Send does not accept SMTP authentication without encryption.

SMTP flow
# Porta 587 / STARTTLS
S: 220 mail.seudominio.com.br ESMTP Ware Send 1.0.0
C: EHLO legado.local
S: 250-STARTTLS
C: STARTTLS
   ... TLS handshake ...
C: EHLO legado.local
S: 250-AUTH PLAIN LOGIN
C: AUTH ...
S: 235 2.7.0 Authentication successful
C: MAIL FROM:<notificacoes@seudominio.com.br>
S: 250 2.1.0 Sender OK
C: RCPT TO:<cliente@example.com>
S: 250 2.1.5 Recipient OK
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: ... RFC 5322 / MIME ...
C: .
S: 250 2.0.0 Message accepted for delivery; queue_id=wsq_...
What does 250 mean?

After DATA completes, Ware Send returns 250 only after the work has been persisted to the durable queue. It means responsibility has been assumed, equivalent to HTTP 202 Accepted; it does not mean final recipient delivery.

Limits and recipients

SMTP uses the same message-size and recipient limits configured in the Engine. Query GET /api/v1/info. Multiple RCPT TO commands are supported and clients may reuse one session for multiple messages.

BCC and MIME

RFC 5322/MIME content is preserved. Blind recipients must be in the RCPT TO envelope; if a legacy client also sends Bcc or Resent-Bcc headers, Ware Send removes those headers before delivery to prevent disclosure.

Optional metadata

SMTP clients may send X-WareSend-Tenant and X-WareSend-Campaign-ID headers to associate the message with an operational context and campaign.

SMTP idempotency

The API idempotency_key semantics are not available in SMTP 1.0.0. If the connection drops after DATA but before the client receives 250, acceptance may be ambiguous; do not assume automatic deduplication by Message-ID.

Same API dataplane

After admission, API and SMTP use the same queue and delivery path. There is no SMTP-specific egress ceiling. Numerical throughput depends on installation benchmarking and SMTP client behavior.

GET/api/v1/infoBearer

GET /api/v1/info announces whether SMTP Submission is enabled, the host, default username, auth_domain, username_policy, whether a password is configured, port 587/STARTTLS, port 465/implicit TLS, and AUTH mechanisms.

Discover the configuration
{
  "supports_smtp_submission": true,
  "smtp_submission": {
    "enabled": true,
    "host": "mail.seudominio.com.br",
    "username": "seudominio@seudominio.com.br",
    "auth_domain": "seudominio.com.br",
    "username_policy": "any-mailbox-in-auth-domain",
    "auth_configured": true,
    "auth_mechanisms": ["PLAIN", "LOGIN"],
    "starttls": {"enabled": true, "port": 587, "required": true},
    "implicit_tls": {"enabled": true, "port": 465}
  }
}

WARE SEND

Simple integration. Engine-controlled operation.

The application submits the message; Ware Send assumes persistence, queueing, adaptive control and delivery to the MTA according to infrastructure capacity.

Back to Ware Send