Helios PostDeveloper docs
DocumentationAPI keys

LUCION MAIL DEVELOPER GUIDE · v0.4.17

API keys

Create, protect, use, rotate, and revoke Helios Post credentials, including keys without automatic expiry.

Updated October 14, 2026Official product documentation

Credential model

A Helios Post API key is a high-entropy bearer credential. Anyone holding it can exercise the scopes stored with that key until its expiry or revocation. The database stores a SHA-256 verifier, not the raw key; the raw secret is returned only at creation time.

Keys may be personal-account credentials or organization shared-mailbox credentials. Shared-mailbox keys are administrator-created and bound to exactly one mailbox; they do not authenticate to Lucion Identity or grant alias administration. The owner is derived from the signed-in session at creation, then the key’s stored account binding is checked on API access.

Create a key

  1. Sign in to Helios Post with Lucion Identity and verify the account email.
  2. Open Settings → API keys.
  3. Enter a non-sensitive label that identifies the integration and owner.
  4. Select only the needed scope or scopes.
  5. The default lifetime is 30 days. Choose 7 or 90 days if needed. Choosing Never — revoke manually requires checking an explicit confirmation.
  6. Review the expiry choice and create the key. Mail sends a security alert to the verified email.
  7. Copy the key once into a server-side secret manager. The key cannot be displayed again.

If the security notification cannot be delivered, creation fails closed: the new key is revoked and its secret is not returned.

Keys that never expire

Select Never — revoke manually and confirm the warning before creating one. The server rejects a no-expiry request without this confirmation. The database stores `expires_at = null`; API authentication treats that value as no automatic expiry. The account’s 10-key limit counts non-expiring keys as active. A key still stops working immediately after its `revoked_at` value is set.

Non-expiring means “no automatic time-based expiry”; it does not mean irrevocable. You can revoke it from Settings at any time.

Scopes

  • mail.read: reads message properties, recipient lists, message text, and attachment metadata for the one bound mailbox.
  • mail.send: sends plain-text messages from an address owned by the one bound mailbox.

Read scope includes private correspondence. Send scope can cause external email to be sent. Avoid granting both unless the integration needs both operations.

Safe storage and handling

  • Put the secret in a server-side secret manager; inject it at runtime.
  • Never put it in browser JavaScript, a URL, a query parameter, a mobile app bundle, a source repository, or a support ticket.
  • Do not log the Authorization header or full request object.
  • Restrict vault access to the integration’s runtime identity.
  • Use TLS and redact credentials from traces and error reporting.

Rotation and revocation

To rotate, create a replacement with the same or narrower scopes, update and verify the integration, then revoke the old key. If exposure is suspected, revoke first and repair the integration afterward. Revocation is checked on each request; it does not require waiting for token expiry.

Revoked keys remain represented by metadata for operational history, but cannot authenticate. The raw secret is not recoverable from the stored hash.

Listing and account limits

The signed-in settings view displays the name, prefix, scopes, creation time, expiry or “never expires” status, last-used time, and most recent authenticated request IP. The last-use address comes from Cloudflare's edge header, is validated, and is visible only to the account owner. It never returns the secret. Each account may hold at most 10 active keys, counting keys with no expiry and keys whose expiry is still in the future. Revoke or allow a finite key to expire before creating another.

Security alerts

Key creation requires a verified Identity email and a successful Resend notification. The alert includes the key label, scopes, creation time, and either the expiry date or a statement that manual revocation is required. It never includes the bearer secret.

Signed send webhooks

For a key with the mail.send scope, add a public HTTPS destination in Settings → API keys. Helios Post sends the metadata-only mail.send.accepted event after the provider accepts an API send and the sent status is saved. This event means provider acceptance, not recipient delivery. API-key sends only are included; interactive Mail sends are not.

A webhook signing secret is shown once when you save or change the destination. Store it in a server-side secret manager. Helios Post encrypts it at rest with AES-GCM using the Cloudflare secret LUCION_MAIL_WEBHOOK_ENCRYPTION_KEY (minimum 32 characters). Rotating that encryption key requires re-saving each webhook destination. Never put either secret in client code or logs.

Each request includes X-Lucion-Webhook-Timestamp and X-Lucion-Webhook-Signature: v1=<hex HMAC-SHA256>. Verify the HMAC over the exact UTF-8 bytes of timestamp + "." + raw request body with your signing secret, and reject timestamps outside your replay window. Delivery runs after the API response and is best-effort; non-2xx responses and timeouts are not retried in this release. The event ID is stable for a provider message, so consumers should deduplicate it.

Webhook payloads contain only event type, timestamp, provider message ID, and mailbox account ID; they exclude message bodies and recipients. Use a public HTTPS endpoint on port 443. Redirects are not followed.

Documentation for Helios Post 0.4.17. Check release history when upgrading.