Appearance
Accounts
Create, authenticate, and manage email accounts. Free and Pro users use the same endpoints.
Get PoW Challenge
GET /api/challengeReturns 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
}| Field | Type | Description |
|---|---|---|
id | string | Challenge ID |
salt | string | Hex-encoded salt |
difficulty | integer | Required leading zero bits (typically 20-28) |
expires_at | integer | Unix timestamp when challenge expires |
Create an Account
POST /api/accountsCreates 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..."
}
}| Field | Type | Required | Description |
|---|---|---|---|
address | string | Yes | Email address (local@domain) |
password | string | Yes | Password (min 6 characters) |
pow | object | Free users | Solved proof-of-work challenge |
pow.id | string | — | Challenge ID from GET /api/challenge |
pow.nonce | string | — | Solution 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:
| Code | Error | Description |
|---|---|---|
| 400 | proof of work required | Free users must include pow field |
| 400 | invalid_address | Malformed email address |
| 400 | invalid_domain | Domain not available |
| 400 | password_too_short | Password under minimum length |
| 403 | invalid proof of work | PoW solution is incorrect |
| 403 | challenge not found or expired | Challenge expired, get a new one |
| 403 | account_limit_reached | Quota exceeded |
| 409 | address_taken | Address already in use |
Sign In
POST /api/tokenAuthenticate 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"
}| Field | Type | Description |
|---|---|---|
quota | integer | Storage limit in bytes |
used | integer | Current 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-passwordResets the account's authentication credentials. All existing tokens are invalidated.
Request:
json
{
"password": "newpassword123"
}Response (200):
json
{
"message": "password_reset"
}Access Control
| Token type | Can access |
|---|---|
| Free JWT | Only the account it was issued for |
| Pro JWT | Any 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).