API reference
REST: POST /v1/messages
The canonical send endpoint. A drop-in for the SendGrid, Postmark, and SES REST shape: swap the base URL and the bearer, keep your code.
POST /v1/messages
Accepts a JSON message envelope. Returns a trace_id immediately and continues the routing decision + provider attempt asynchronously. The trace ID is public-shareable.
POST https://api.mailnix.ch/v1/messages
Authorization: Bearer mnx_live_…
Content-Type: application/jsonRequest body
{
"to": ["jordan@acme.com"],
"cc": [],
"bcc": [],
"from": "noreply@example.com",
"reply_to": "support@example.com",
"subject": "Your receipt",
"text": "Plain-text body",
"html": "<p>HTML body</p>",
"destination_id": null,
"template_id": null,
"template_vars": {},
"send_at": null,
"idempotency_key": "checkout-7c2d-receipt",
"attachments": [
{
"filename": "receipt.pdf",
"content": "<base64>",
"content_type": "application/pdf"
}
]
}destination_id is optional; omit it and mailnix picks a destination from your routing rules. template_id + template_vars render a saved Sprig template server-side. send_at is an RFC3339 timestamp up to 3 days in the future (Pro+ only).
The outcome field
The response carries an outcome string that tells you exactly what mailnix did with the message:
relayed: sent to a real provider.captured.anonymous_project: the project is anonymous; capture only.captured.sandbox_destination: the matched destination is insandboxmode.captured.no_route: no routing rule matched; the project'sno_route_policywascapture.
Idempotency
Pass an idempotency_key on retry-prone callers (checkout, signup, webhook worker). mailnix indexes the key per project for 24 hours; a duplicate POST returns the original trace ID instead of producing a second send.
Scheduled sends
Set send_at to an RFC3339 timestamp in the future (max 3 days, Pro+). The response carries the same shape but with status: "queued"; the actual provider attempt happens at send_at. Cancel via DELETE /v1/messages/scheduled/<trace_id>.
Errors
Every error has the same envelope shape:
{
"error": {
"code": "validation_failed",
"message": "from address is missing",
"next_action": "supply a verified sender or set destination_id"
}
}Common codes: validation_failed, quota_exceeded, quota_exhausted_captures (HTTP 402), destination_misconfigured, provider_rate_limited, insufficient_scope.