Skip to content

Accounts

Create, authenticate, and manage email accounts. Free and Pro users use the same endpoints.

Get PoW Challenge

GET /api/challenge

Returns a proof-of-work challenge that must be solved before creating a free account. The client must find a nonce such that SHA-256(salt + nonce) has the required number of leading zero bits.

Response (200):

json
{
  "id": "a1b2c3d4...",
  "salt": "e5f6a7b8...",
  "difficulty": 20,
  "expires_at": 1700000000
}
FieldTypeDescription
idstringChallenge ID
saltstringHex-encoded salt
difficultyintegerRequired leading zero bits (typically 20-28)
expires_atintegerUnix timestamp when challenge expires

Create an Account

POST /api/accounts

Creates an email account and returns a JWT token + account ID. Free users must solve a PoW challenge first.

Request:

json
{
  "address": "demo@mail.td",
  "password": "supersecret",
  "pow": {
    "id": "a1b2c3d4...",
    "nonce": "00000abc..."
  }
}
FieldTypeRequiredDescription
addressstringYesEmail address (local@domain)
passwordstringYesPassword (min 6 characters)
powobjectFree usersSolved proof-of-work challenge
pow.idstringChallenge ID from GET /api/challenge
pow.noncestringSolution nonce

Response (201):

json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-1234567890ab",
  "address": "demo@mail.td",
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

INFO

Save both id (account ID) and token. The id is used as {account_id} in all subsequent API paths.

Pro users can skip the PoW challenge by including a Pro token in the Authorization header. Pro accounts can also create addresses on custom domains and get higher storage quotas.

Errors:

CodeErrorDescription
400proof of work requiredFree users must include pow field
400invalid_addressMalformed email address
400invalid_domainDomain not available
400password_too_shortPassword under minimum length
403invalid proof of workPoW solution is incorrect
403challenge not found or expiredChallenge expired, get a new one
403account_limit_reachedQuota exceeded
409address_takenAddress already in use

Sign In

POST /api/token

Authenticate with an existing account and get a new JWT token.

Request:

json
{
  "address": "demo@mail.td",
  "password": "supersecret"
}

Response (200):

json
{
  "id": "a1b2c3d4-...",
  "address": "demo@mail.td",
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

This is the universal email login — works for accounts created by free users and Pro users alike.

Get Account Info

GET /api/accounts/{account_id}

Returns account details including storage usage.

Response (200):

json
{
  "id": "a1b2c3d4-...",
  "address": "demo@mail.td",
  "role": "user",
  "quota": 41943040,
  "used": 1234567,
  "created_at": "2025-01-15T10:30:00Z"
}
FieldTypeDescription
quotaintegerStorage limit in bytes
usedintegerCurrent storage usage in bytes

Delete Account

DELETE /api/accounts/{account_id}

Permanently deletes the account and all its messages. This action is irreversible.

Response: 204 No Content

Reset Password

PUT /api/accounts/{account_id}/reset-password

Resets the account's authentication credentials. All existing tokens are invalidated.

Request:

json
{
  "password": "newpassword123"
}

Response (200):

json
{
  "message": "password_reset"
}

Access Control

Token typeCan access
Free JWTOnly the account it was issued for
Pro JWTAny account owned by the Pro user
Pro API Token (tm_pro_)Any account owned by the Pro user

Attempting to access an account you don't own returns 403 Forbidden (free) or 404 Not Found (Pro).

Mail.td API Documentation