Werkmail Docs
Contents

API

Errors and limits

Error shape

Failed requests return JSON:

json
{
  "code": "content_blocked",
  "error": "message blocked by the content gate",
  "hint": "Remove promotional phrasing or send on the broadcast route after DOI."
}

hint is safe to show in a UI. Do not parse error for control flow — use code.

HTTP status

Status Typical meaning
202 Send accepted (queued)
400 Validation, wrong route/kind, missing fields
401 Missing or invalid bearer
403 Authenticated but not allowed (role / plan / paused)
404 Unknown id (or hidden cross-tenant id)
409 Conflict (duplicate, already in that state)
410 Retired endpoint (POST /api/public/unsubscribe)
413 Body larger than the message cap (~48 MiB)
422 Content gate hard-block or compliance gate
429 Rate limit or monthly cap

Common codes

Code What to do
content_blocked Read content_reasons; use POST …/send/score
suppressed Recipient is on a team/project/route list
paused Reputation or abuse pause — fix the list, then resume
plan_cap Monthly volume reached
warm_up Wait or stay on transactional
impressum_incomplete Fill street, city, privacy URL
dkim_unverified Publish DKIM and re-check DNS
route_kind_mismatch Newsletter → broadcast; termin → outgoing
safe_mode Recipient not on the allowlist / simulator
attachment_rejected Type, size, or double-extension

Exact strings can grow; treat unknown codes as generic failures and show hint.

Idempotency

Idempotency-Key (or X-Idempotency-Key) on single send, and idempotency_key on batch items / bulk, replay the original status and body for the same workspace + key. Keys are scoped per tenant.

Rate limits

Werkmail applies a per-tenant client limiter in addition to the outbound platform. Bursting thousands of un-idempotent POSTs will 429. Prefer batch/bulk and backoff on 429.

HTTP bodies are capped at MaxMessageRequestBytes (tens of MiB) so a single request cannot exhaust the process.

View this page as Markdown · llms.txt · full corpus