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.
End user mailboxes
Mailboxes that your product's end users connect with a guest link are separate from the routes and polling groups
above. They are not mailer routes: Confluye does not store their messages, does not trigger workflows from them and does
not make them available to workflow blocks. Confluye reads only what the connection's capabilities include: with mail
it reads the inbox and sent mail (with a bounded first load of the last 90 days), and with calendar it reads the
calendar (a bounded first load of the last 30 days and what is ahead). A connection with only one of them never
delivers the other stream. What is new is delivered to the product as signed mail.batch events. See
Mailboxes and calendars in the end users API.
