Mailboxes API
Mailboxes represent individual email accounts within a domain. Each mailbox has a local part (the part before @), a password hashed with Argon2id, a quota, and a Maildir on disk. Postfix and Dovecot pick up new mailboxes immediately via SQL lookups – no service reload is needed.
All endpoints require authentication. domain_admin users are scoped to their assigned domains.
List mailboxes
Section titled “List mailboxes”GET /api/v1/mailboxesReturns a paginated list of mailboxes.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
domain_id |
string (UUID) | Yes (for domain_admin) |
Filter by domain. |
active |
boolean | No | Filter by active status. |
cursor |
string | No | Pagination cursor. |
limit |
integer | No | Items per page (default 50, max 200). |
Example:
curl "https://mail.example.com/api/v1/mailboxes?domain_id=0192abc0-..." \ -H "Authorization: Bearer vectis_sk_abc123..."Response:
{ "data": [ { "id": "0192abc0-def1-7000-8000-000000000010", "domain_id": "0192abc0-def1-7000-8000-000000000001", "local_part": "alice", "display_name": "Alice Johnson", "quota_mb": 2048, "active": true, "created_at": "2026-03-20T14:30:00Z", "updated_at": "2026-03-20T14:30:00Z" }, { "id": "0192abc0-def1-7000-8000-000000000011", "domain_id": "0192abc0-def1-7000-8000-000000000001", "local_part": "bob", "display_name": "Bob Smith", "quota_mb": 1024, "active": true, "created_at": "2026-03-21T09:15:00Z", "updated_at": "2026-03-21T09:15:00Z" } ], "meta": { "request_id": "...", "timestamp": "...", "pagination": { "next_cursor": "", "has_more": false } }}Create mailbox
Section titled “Create mailbox”POST /api/v1/mailboxesCreates a new mailbox. The password is hashed with Argon2id before storage. A Maildir directory structure is created on disk at /var/vectis/mail/<domain>/<local_part>/Maildir/{cur,new,tmp}.
Request body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
domain_id |
string (UUID) | Yes | – | ID of the parent domain. |
local_part |
string | Yes | – | Local part of the email address (before @). |
password |
string | Yes | – | Plaintext password (hashed server-side with Argon2id). |
display_name |
string | No | null |
Full name of the mailbox owner. |
quota_mb |
integer | No | 1024 |
Mailbox quota in megabytes. |
active |
boolean | No | true |
Whether the mailbox can send and receive mail. |
Example:
curl -X POST https://mail.example.com/api/v1/mailboxes \ -H "Authorization: Bearer vectis_sk_abc123..." \ -H "Content-Type: application/json" \ -d '{ "domain_id": "0192abc0-def1-7000-8000-000000000001", "local_part": "alice", "password": "a-strong-passphrase", "display_name": "Alice Johnson", "quota_mb": 2048 }'Response (201 Created):
{ "data": { "id": "0192abc0-def1-7000-8000-000000000010", "domain_id": "0192abc0-def1-7000-8000-000000000001", "local_part": "alice", "display_name": "Alice Johnson", "quota_mb": 2048, "active": true, "created_at": "2026-04-04T12:00:00Z", "updated_at": "2026-04-04T12:00:00Z" }, "meta": { "request_id": "...", "timestamp": "..." }}Validation rules:
- The domain must exist and be active.
local_partmust be unique within the domain.- If the domain has
max_mailboxesset, creation fails if the limit is reached.
Errors:
| Code | Status | Description |
|---|---|---|
MISSING_FIELDS |
400 | Required fields missing. |
DOMAIN_NOT_FOUND |
404 | Domain ID does not exist. |
DOMAIN_INACTIVE |
403 | Domain is deactivated. |
CONFLICT |
409 | Mailbox already exists for this local_part and domain. |
Get mailbox
Section titled “Get mailbox”GET /api/v1/mailboxes/{id}Returns full details for a single mailbox, including quota usage.
curl https://mail.example.com/api/v1/mailboxes/0192abc0-def1-7000-8000-000000000010 \ -H "Authorization: Bearer vectis_sk_abc123..."Update mailbox
Section titled “Update mailbox”PATCH /api/v1/mailboxes/{id}Updates mailbox settings. Only include the fields you want to change.
Request body (all fields optional):
| Field | Type | Description |
|---|---|---|
password |
string | New password (re-hashed with Argon2id). |
display_name |
string | Updated display name. |
quota_mb |
integer | New quota in megabytes. |
active |
boolean | Enable or disable the mailbox. |
Example – update quota and display name:
curl -X PATCH https://mail.example.com/api/v1/mailboxes/0192abc0-... \ -H "Authorization: Bearer vectis_sk_abc123..." \ -H "Content-Type: application/json" \ -d '{"quota_mb": 4096, "display_name": "Alice M. Johnson"}'Example – change password:
curl -X PATCH https://mail.example.com/api/v1/mailboxes/0192abc0-... \ -H "Authorization: Bearer vectis_sk_abc123..." \ -H "Content-Type: application/json" \ -d '{"password": "new-strong-passphrase"}'Delete mailbox
Section titled “Delete mailbox”DELETE /api/v1/mailboxes/{id}Deletes a mailbox. Requires the X-Confirm-Delete: true header to prevent accidental deletion.
Optionally archive the mailbox’s mail data before deletion by including {"archive": true} in the request body. Archived mail is saved to /var/vectis/archives/<domain>/<local_part>-<timestamp>/.
Example:
curl -X DELETE https://mail.example.com/api/v1/mailboxes/0192abc0-... \ -H "Authorization: Bearer vectis_sk_abc123..." \ -H "X-Confirm-Delete: true" \ -H "Content-Type: application/json" \ -d '{"archive": true}'Response:
{ "data": { "message": "Mailbox deleted", "archived": true, "archive_path": "/var/vectis/archives/example.com/alice-20260404-120000/" }}Without the confirmation header, the API returns:
{ "error": { "code": "CONFIRMATION_REQUIRED", "message": "Set X-Confirm-Delete: true header to confirm mailbox deletion" }}Password hashing
Section titled “Password hashing”Passwords are hashed server-side using Argon2id with the following parameters:
| Parameter | Value |
|---|---|
| Memory | 65,536 KB (64 MB) |
| Iterations | 3 |
| Parallelism | 4 |
| Format | PHC string ($argon2id$v=19$m=65536,t=3,p=4$salt$hash) |
Passwords are never stored in plaintext or returned in API responses.
Related
Section titled “Related”- Domains API – manage the parent domains
- Aliases API – forward mail to or from mailboxes
- Sending Email – send mail from a mailbox via the API
- CLI mailbox commands – manage mailboxes from the command line
New self-hosting guides, in your inbox
Occasional email when we publish a new guide or ship a release. No spam, unsubscribe anytime.
