Skip to content

Accounts

EndpointWhat it does
POST /accountsRegister an account id derived on the device from a recovery phrase. Takes accountId, authVerifier and authPublicKey. Returns the account as operator, with a session token and expiresAt. The phrase is never sent. An id that already has an account returns 409 account_exists.
POST /accounts/challengeSend an accountId. Returns a single-use nonce, its expiresAt two minutes out, and an ephemeral X25519 challengeKey. The answer is the same whether or not the account exists.
POST /accounts/verifySend accountId, nonce and proof. Returns the account as operator, with a session token and expiresAt. Every wrong answer is 401 no_such_account, and a nonce past its two minutes is 401 challenge_expired. See Authentication.
GET /accounts/meThe authenticated account as operator, and its plan.
POST /accounts/signoutEnd the current session. Session only.
GET /accounts/sessionsThe account’s live sessions, each with id, createdAt, expiresAt and current. Session only.
DELETE /accounts/sessionsEnd every session except the current one. Returns how many were revoked. Session only.
DELETE /accounts/sessions/:idEnd one session. Session only.
DELETE /accounts/meErase the account and everything in it, immediately. Its addresses are retired and never reissued. Needs a fresh proof; see Deleting the account. Session only.
GET /overviewAccount counters for the dashboard.
GET /activityAccount activity, newest first, up to limit entries (default 20, at most 200), paged with cursor. Kept 90 days. See Usage.
GET /activity/dailyActivity counted by day, from and to as YYYY-MM-DD (the last 30 days by default), newest first: days, each a day and counts by kind, and retentionDays. Past 90 days only the counts are kept, a year on Fleet and two on Enterprise. Fleet and up; 402 plan_capability_required below.
GET /auditWho changed the account, newest first, paged with limit and cursor: each entry’s action (such as api_key.created, device.paired, plan.changed), at, actor (session with its session id, apiKey with the key’s id, device, member with a team member’s account id, or staff) and targetId. No IP address or content is recorded. Kept 90 days, a year on Fleet and two on Enterprise; shown on Fleet and up. Session only.
GET /usageWhat the account has used against its plan. See Usage.
GET /accounts/liveThe event stream, as a WebSocket. Sessions on any plan, API keys on Operator and up.

“Session only” endpoints answer 403 session_required to an API key.

A session lasts 30 days, so on its own it is not enough to erase the account. Send a proof that you hold the recovery phrase now:

  1. POST /accounts/challenge with your accountId, as when signing in.
  2. DELETE /accounts/me with { "nonce": "…", "proof": "…" }. The proof is computed as for POST /accounts/verify, under the domain mailcycle/v1/delete-proof in place of mailcycle/v1/auth-proof, so a sign-in proof cannot stand in for it.

Without a body, only a session signed in within the last 10 minutes is accepted. Anything else answers 403 confirmation_required. The nonce is spent whatever the outcome.

If the account balance still holds money you paid in, deleting is refused with 409 balance_held, before the proof is checked. Ask for the balance back through support first, or add "forfeitBalance": true to the body to confirm it will be lost. See the Refund Policy.

© Northlab Studios Ltd, trading as Mailcycle. Registered in England and Wales, company no. 17462734. Registered office: 167-169 Great Portland Street, London W1W 5PF.