Skip to content
01Integration

The primary surface is the REST API and the MCP server.

There is no dashboard as the main path. Send, query, seal and verify over HTTP or from an agent that speaks MCP. The UI comes later.

POST /v1/messages · MCP

02Ingest

POST /v1/messages with Idempotency-Key.

Fixes Message-ID and Date, hashes the exact byte stream that will go over the wire, and will not re-send if you replay the same key. Body accepts from, to, subject and html.

POST /v1/messages
curl -X POST https://api.mailack.com/v1/messages \
  -H "Authorization: Bearer $MAILACK_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "noreply@acme.mx",
    "to": "cliente@ejemplo.com",
    "subject": "Estado de cuenta",
    "html": "<p>Tu estado de cuenta está listo.</p>"
  }'
03Query and evidence

Status, proof bundle and on-demand sealing.

Read the message, download the proof package (hash, Merkle path, certificate) or request an individual seal when you need one.

GET /v1/messages/{id}
curl -s https://api.mailack.com/v1/messages/$MESSAGE_ID \
  -H "Authorization: Bearer $MAILACK_API_KEY"
GET /v1/messages/{id}/proof-bundle
curl -s https://api.mailack.com/v1/messages/$MESSAGE_ID/proof-bundle \
  -H "Authorization: Bearer $MAILACK_API_KEY" \
  -o bundle.json
POST /v1/messages/{id}/seal
curl -X POST https://api.mailack.com/v1/messages/$MESSAGE_ID/seal \
  -H "Authorization: Bearer $MAILACK_API_KEY"
04Verification

Check it without taking our word.

POST /v1/verify recomputes the inclusion proof from the API. And whoever receives a bundle can check it at mailack.com/verificar: the verification runs in their browser, with nothing uploaded.

POST /v1/verify
curl -s -X POST https://api.mailack.com/v1/verify \
  -H "Authorization: Bearer $MAILACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message_id": "'"$MESSAGE_ID"'"}'

Canonical hash

Recomputes the hash of the message byte stream and compares it to the one in the bundle.

Merkle inclusion proof

Walks the inclusion path (RFC 6962, 0x00 leaf / 0x01 node prefixes) up to the batch root.

Root against the certificate

Checks the tree root against the NOM-151 preservation certificate issued by PSC Codex.
05MCP server

Agents that send, query, verify and operate.

mailack-mcp exposes MCP tools over the same API: send messages, read status, fetch proof bundles, verify and run allowed operations (suppression, event lookup).

Add the server to the MCP client you use (Claude Desktop, Cursor or any stdio-capable host). Auth is the API key in the process environment.

mcpServers.mailack
{
  "mcpServers": {
    "Mailack": {
      "command": "./bin/mailack-mcp",
      "env": {
        "MAILACK_API_KEY": "mlk_...",
        "MAILACK_API_URL": "https://api.mailack.com"
      }
    }
  }
}
06Services

Six processes, one evidence contract.

Each service has a narrow role. Delivery does not depend on the LLM; sealing never re-serializes the MIME.

mailack-apiREST ingest and query. Multi-tenant, idempotent.
mailack-sealerMerkle windows of 1 h or 10 000 leaves. Seals the root with NOM-151.
mailack-opsDeterministic governor per IP/ISP pair. Rates, pauses, failover.
mailack-mcpMCP server for AI agents.
mailack-dispatcherSMTP delivery with literal transcript, rate gate and deterministic split.
mailack-collectorReceives DSN and ARF: archives raw, parses, correlates VERP.
07Multi-tenant

RLS, suppression and VERP correlation.

PostgreSQL with Row Level Security. Each tenant only sees its rows. Working tables are messages, batches, events, suppressions and access_log.

Global and per-tenant suppression

An address can be blocked system-wide or only in your tenant. The dispatcher honours both layers before the message is queued.

VERP correlation

Return-path bounce+<message-uuid>@mailack.com. Every DSN or ARF is tied to the original message without relying on the destination's Message-ID.

Policy isolation

RLS in the database; the API key identifies tenant and scope. No cross-tenant reads on query or access_log.