Axuz Developers

POST /messages

Compose — salva rascunho OU envia (interno/externo)

  • Access: Signed in
  • Service: https://mail-api.axuz.net

Accepted authentication

  • sessionCookie — Sessão plena Axuz (cookie de sessão da casa). Sessão restrita é 403 enrollment_required.
  • bearerSession — JWT de acesso da sessão em `Authorization: Bearer`.

- send=false → grava row draft no folder drafts. - send=true interno-only → grava sent no remetente + received em cada destinatário interno (mesma tx). - send=true com destinatário externo → depende do gate MAIL_EXTERNAL_SEND_ENABLED. Ligado: enfileira em mail_outbound_log + dispara Deliver ao MTA. Desligado (default): responde 503 pending_stalwart ANTES de escrever nada. (piso §37.15 / MAIL-03)

Parameters

No parameters.

Request body

application/json · Required

NameTypeRequiredDescription
account_idstring<uuid>yes
toarray<string<email>>no
ccarray<string<email>>no
bccarray<string<email>>no
subjectstringno
body_htmlstringno
body_textstringno
in_reply_tostring<uuid> | nullno
sendbooleanno

false = grava rascunho no folder drafts. true = tenta envio (routing interno + externo). Externo respeita o gate §37.15.

{
  "account_id": "00000000-0000-0000-0000-000000000000",
  "to": [
    "pessoa@example.test"
  ],
  "cc": [
    "pessoa@example.test"
  ],
  "bcc": [
    "pessoa@example.test"
  ],
  "subject": "string",
  "body_html": "string",
  "body_text": "string",
  "in_reply_to": "00000000-0000-0000-0000-000000000000",
  "send": false
}

Responses

201

Rascunho salvo ou mensagem enviada

NameTypeRequiredDescription
messageMailMessageyes
message.idstring<uuid>yes
message.account_idstring<uuid>yes
message.folder_idstring<uuid>yes
message.thread_idstring<uuid>yes
message.in_reply_tostring<uuid> | nullno
message.from_emailstring<email>yes
message.from_namestringno
message.to_emailsarray<string<email>>yes
message.cc_emailsarray<string<email>>no
message.bcc_emailsarray<string<email>>no
message.subjectstringyes
message.body_htmlstringno

Corpo HTML sanitizado (allowlist bluemonday, internal/sanitize). Toda leitura passa pelo mesmo chokepoint (scanMessage), então este campo nunca carrega <script>, atributos on*, javascript:, <iframe>, <object> ou <svg>. A COLUNA homônima no banco guarda o corpo cru (forense) e NÃO é confiável — ela nunca sai pela API.

message.body_textstringno
message.readbooleanyes
message.starredbooleanyes
message.labelsarray<string>no
message.received_atstring<date-time>yes
message.sent_atstring<date-time> | nullno
message.statusstringyes

enum: "draft", "sent", "received", "queued"

message.internalbooleanyes
message.created_atstring<date-time>yes
message.updated_atstring<date-time>yes
internalbooleanyes

True quando todos os destinatários bateram em mail_accounts.email.

externalbooleanyes

True quando pelo menos um destinatário é externo (delegado ao MTA).

400

Payload inválido

401

Sem credencial valida

NameTypeRequiredDescription
errorstringyes

403

Remetente não pertence ao usuário

404

Account not found

429

Teto de envio (F-019) atingido. Header Retry-After em segundos. Só ocorre com send=true — rascunho não consome cota.

NameTypeRequiredDescription
errorstringyes
layerstringyes

Camada que negou.

enum: "user", "mailbox", "pair", "team"

limitintegeryes

Teto da camada que negou.

usedintegeryes

Consumido na janela quando negou.

retry_afterintegeryes

Segundos até a próxima vaga (mínimo 1).

messagestringyes

500

Erro interno. Tente de novo com backoff; reporte o X-Request-Id.

NameTypeRequiredDescription
errorstringyes

503

External send disabled — gate §37.15 rejeitou antes de qualquer INSERT.

NameTypeRequiredDescription
errorstringyes
statusstringyes

Examples

"Try it" is turned off in this reference. Use the examples with your test credential.

curl

curl -sS -X POST 'https://mail-api.axuz.net/messages' \
  -H "Authorization: Bearer $AXUZ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"account_id":"00000000-0000-0000-0000-000000000000","to":["pessoa@example.test"],"cc":["pessoa@example.test"],"bcc":["pessoa@example.test"],"subject":"string","body_html":"string","body_text":"string","in_reply_to":"00000000-0000-0000-0000-000000000000","send":false}'

Node.js

const res = await fetch("https://mail-api.axuz.net/messages", {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.AXUZ_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "account_id": "00000000-0000-0000-0000-000000000000",
    "to": [
      "pessoa@example.test"
    ],
    "cc": [
      "pessoa@example.test"
    ],
    "bcc": [
      "pessoa@example.test"
    ],
    "subject": "string",
    "body_html": "string",
    "body_text": "string",
    "in_reply_to": "00000000-0000-0000-0000-000000000000",
    "send": false
  }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
console.log(await res.json());

Python

import os
import requests

res = requests.request(
    "POST",
    "https://mail-api.axuz.net/messages",
    headers={
        "Authorization": f"Bearer {os.environ['AXUZ_TOKEN']}",
    },
    json={
        "account_id": "00000000-0000-0000-0000-000000000000",
        "to": [
            "pessoa@example.test",
        ],
        "cc": [
            "pessoa@example.test",
        ],
        "bcc": [
            "pessoa@example.test",
        ],
        "subject": "string",
        "body_html": "string",
        "body_text": "string",
        "in_reply_to": "00000000-0000-0000-0000-000000000000",
        "send": False,
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())