Mailer
Workspace API for mailer routes, inbox, inbound webhooks, polling, and replies.
Mailer endpoints under /api/v1/mailer require a workspace bearer API key unless noted.
Missing or invalid tokens return 401. Non-workspace keys return 403.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/mailer/routes | List routes and inbound links |
| POST | /api/v1/mailer/routes | Create an inbound route (Idempotency-Key required) |
| GET | /api/v1/mailer/routes/{id} | Get one route and links |
| PATCH | /api/v1/mailer/routes/{id} | Update route; rotation requires Idempotency-Key |
| PATCH | /api/v1/mailer/routes/{id}/google-dwd | Bind or clear DWD (Admin/Owner) |
| POST | /api/v1/mailer/inbound | Generic inbound (API key) |
| POST | /api/v1/mailer/inbound/{routeId} | Signed inbound (HMAC, no bearer) |
| GET | /api/v1/mailer/threads | List threads (cursor, limit) |
| GET | /api/v1/mailer/threads/{id} | Thread plus up to 100 messages |
| GET | /api/v1/mailer/messages | List messages (threadId, cursor, limit) |
| POST | /api/v1/mailer/messages/{id}/reply | Reply (Idempotency-Key required) |
| GET | /api/v1/mailer/reply-reservations/{id} | Read reservation (Admin/Owner) |
| PATCH | /api/v1/mailer/reply-reservations/{id} | authorize_retry (Admin/Owner) |
| GET | /api/v1/mailer/polling-groups | List polling groups |
| POST | /api/v1/mailer/polling-groups | Create or upsert a group |
| GET | /api/v1/mailer/polling-groups/{id} | Get one group |
| PATCH | /api/v1/mailer/polling-groups/{id} | Update interval or enabled |
A session-authenticated compatibility path also exists at POST /api/mailer/inbound (not under
/api/v1). Prefer the v1 routes for API keys.
Routes
POST /api/v1/mailer/routes creates provider: inbound with destination workflow.
| Field | Notes |
|---|---|
address | Required; stored trimmed and lowercased |
workflowId | Required; must belong to the API-key workspace |
executionTargetId | Optional immutable destination ID within the selected workflow |
description | Optional |
enabled | Optional; default true |
201 returns { route, signingSecret, links }. links includes self, inbound
(/api/v1/mailer/inbound), and signedInbound (/api/v1/mailer/inbound/{routeId}). Duplicate
addresses within the same destination return 409. The public route object has no signing material.
It includes executionTargetId and targetEnabled. Use signedInbound for explicitly selected
destinations; the address-only endpoint uses the legacy Production route. Source enablement
does not publish the workflow or grant AIMS approval.
PATCH accepts enabled, workflowId, description, and rotateSigningSecret. Rotation
returns a new signingSecret once.
Target-bound routes cannot change their workflow or destination identity.
Generic inbound
curl -X POST https://confluye.run/api/v1/mailer/inbound \
-H "Authorization: Bearer hise_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"to":"inbound@acme.fluxus.local","from":"user@example.com","subject":"Hello","text":"Hi"}'
202 body: { route, message, run: null, outbox, deduplicated }. Lookup failures return 404.
Signed inbound
No bearer token. Sign the exact raw bytes you POST:
x-fluxus-timestamp: <unix seconds>
x-fluxus-signature: v1=<hex hmac-sha256 of "{timestamp}." + rawBody>
Required JSON: externalMessageId, from, subject. Optional: text, html,
externalThreadId, to (must equal the route address). Bodies over 1 MiB return 413. Bad or
missing signatures return 401. Replay / in-progress / unconfigured signing return 409. Success
is 202 in the mailer success envelope.
Inbox
Thread and message lists return { threads|messages, nextCursor }. Invalid cursors throw as a
malformed mail cursor. Message objects include attachmentFileIds, sanitized HTML, and
provider metadata without _triggerOutbox.
Reply
{ "text": "Thanks", "html": "<p>Thanks</p>", "attachmentFileIds": [] }
201 on first send, 200 with deduplicated: true on idempotent replay. Missing
Idempotency-Key is 400. Setup-required (no Gmail/Outlook credential) is 409 with
SETUP_REQUIRED. Reservation conflicts are 409 with code, reservationId, and
reconciliable.
PATCH reservation body must be { "action": "authorize_retry" }. Success returns the
reservation with ISO timestamps.
Polling groups
POST body: provider (gmail | outlook), credentialId (or googleDwdConfigId for Gmail
DWD), optional intervalSeconds (60–86400, default 300), optional enabled. Identity is
workspace + provider + credential + principal + DWD config. Serialized groups include cursor,
nextPollAt, lastPolledAt, and lastError.
