Skip to content

Authentication

Every request is made over HTTPS to https://api.mailcycle.email and carries a bearer token:

Terminal window
curl https://api.mailcycle.email/accounts/me \
-H "Authorization: Bearer $TOKEN"

There are three kinds of token.

For scripts and servers, on the Operator plan and higher.

  • Create, list and revoke keys in the app under API. A key’s token starts with mak_ and is shown once.
  • Keys have no expiry date. A key works until you revoke it.
  • While the account is on a plan without the API, a key answers 403 plan_required. It works again after an upgrade.
  • After a missed payment, keys answer 403 payment_required for 21 days, and are deleted if the payment is still missing. See Missed payments.
  • An account can hold 20 keys.

A key can do what a session can, except:

  • create, list or revoke API keys
  • list or end sessions, or sign out
  • change the plan or pay
  • delete the account

Those answer 403 session_required, so a leaked key cannot make more keys, hide from its owner or close the account.

Only a hash of each key is stored, with its last four characters so you can tell keys apart. Its name is encrypted on your device.

A session represents the account and works on every plan. You get one by proving you hold the recovery phrase, with a handshake in which nothing secret crosses the wire:

  1. POST /accounts/challenge with your accountId. The response carries a single-use nonce, its expiresAt two minutes out, and an ephemeral X25519 challengeKey.
  2. POST /accounts/verify with accountId, nonce and a proof: an HMAC-SHA256 over the nonce and account id, keyed by the X25519 shared secret between the account key and the challenge key. The response carries the session token and its expiresAt.

Sessions last 30 days. End one with POST /accounts/signout, or see and end them all under Accounts.

The account key is derived from the recovery phrase, so computing the proof means implementing the same derivation the apps use. An SDK that does this is planned; until then, API keys are the practical way to script against the API.

A device credential represents one paired device. It is minted during pairing, scoped to that device, reads only that device’s mail, and can be revoked on its own. It is never issued by hand.

Every call is checked against the caller’s account. Asking for a record you do not own returns 404, not 403, so the API never confirms that another account’s identifiers exist. A device id is not authorization.