Skip to content

Aliases API

Aliases forward incoming mail to one or more destination addresses. They take effect immediately via Postfix SQL lookups — no service reload is needed.

All endpoints require authentication. domain_admin users are scoped to their assigned domains.

GET /api/v1/aliases

Returns a paginated list of aliases.

Query parameters:

ParameterTypeDescription
domain_idstring (UUID)Filter by domain. Required for domain_admin role.
cursorstringPagination cursor.
limitintegerItems per page (default 50, max 200).

Example:

Terminal window
curl "https://mail.example.com/api/v1/aliases?domain_id=0192abc0-..." \
-H "Authorization: Bearer vectis_sk_abc123..."

Response:

{
"data": [
{
"id": "0192abc0-def1-7000-8000-000000000020",
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "info",
"destination": "alice@example.com",
"active": true,
"created_at": "2026-03-22T11:00:00Z",
"updated_at": "2026-03-22T11:00:00Z"
},
{
"id": "0192abc0-def1-7000-8000-000000000021",
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "",
"destination": "catchall@example.com",
"active": true,
"created_at": "2026-03-22T11:05:00Z",
"updated_at": "2026-03-22T11:05:00Z"
}
],
"meta": {
"request_id": "...",
"timestamp": "...",
"pagination": { "next_cursor": "", "has_more": false }
}
}
POST /api/v1/aliases

Creates a new alias.

Request body:

FieldTypeRequiredDescription
domain_idstring (UUID)YesID of the domain this alias belongs to.
source_local_partstringYesLocal part to match. Use empty string "" for catch-all.
destinationstringYesDestination email address(es). Comma-separated for multiple.
activebooleanNoDefaults to true.

Example — standard alias:

Terminal window
curl -X POST https://mail.example.com/api/v1/aliases \
-H "Authorization: Bearer vectis_sk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "info",
"destination": "alice@example.com"
}'

This creates info@example.com which forwards to alice@example.com.

Example — multiple destinations:

Terminal window
curl -X POST https://mail.example.com/api/v1/aliases \
-H "Authorization: Bearer vectis_sk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "support",
"destination": "alice@example.com,bob@example.com"
}'

Example — catch-all alias:

Terminal window
curl -X POST https://mail.example.com/api/v1/aliases \
-H "Authorization: Bearer vectis_sk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "",
"destination": "catchall@example.com"
}'

A catch-all alias matches any address at the domain that does not have a corresponding mailbox or explicit alias. Set source_local_part to an empty string "" to create one.

Response (201 Created):

{
"data": {
"id": "0192abc0-def1-7000-8000-000000000020",
"domain_id": "0192abc0-def1-7000-8000-000000000001",
"source_local_part": "info",
"destination": "alice@example.com",
"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.
  • source_local_part must be unique within the domain (only one alias per source address).
  • Aliases cannot chain — an alias destination cannot be another alias source within the same domain.
  • destination can be a local mailbox address or an external address (or a mix).

Errors:

CodeStatusDescription
MISSING_FIELDS400Required fields missing.
DOMAIN_NOT_FOUND404Domain ID does not exist.
CONFLICT409An alias with this source_local_part already exists on the domain.
GET /api/v1/aliases/{id}

Returns details for a single alias.

Terminal window
curl https://mail.example.com/api/v1/aliases/0192abc0-def1-7000-8000-000000000020 \
-H "Authorization: Bearer vectis_sk_abc123..."
PATCH /api/v1/aliases/{id}

Updates an alias. Only include the fields you want to change.

Request body (all fields optional):

FieldTypeDescription
destinationstringNew destination address(es).
activebooleanEnable or disable the alias.

Example:

Terminal window
curl -X PATCH https://mail.example.com/api/v1/aliases/0192abc0-... \
-H "Authorization: Bearer vectis_sk_abc123..." \
-H "Content-Type: application/json" \
-d '{"destination": "alice@example.com,carol@example.com", "active": true}'
DELETE /api/v1/aliases/{id}

Deletes an alias. The change takes effect immediately.

Terminal window
curl -X DELETE https://mail.example.com/api/v1/aliases/0192abc0-... \
-H "Authorization: Bearer vectis_sk_abc123..."

Response:

{
"data": { "message": "Alias deleted" },
"meta": { "request_id": "...", "timestamp": "..." }
}

When source_local_part is an empty string, the alias acts as a catch-all for the domain. Postfix evaluates aliases in this order:

  1. Check for an exact mailbox match (local_part@domain).
  2. Check for an exact alias match (source_local_part@domain).
  3. Check for a catch-all alias (empty source_local_part for the domain).
  4. If none match, reject the message (no such user).

Only one catch-all alias can exist per domain (enforced by the unique constraint on domain_id + source_local_part).

The destination field accepts several formats:

FormatExampleDescription
Local addressalice@example.comDeliver to a local mailbox.
External addressforward@gmail.comForward to an external address.
Multiple addressesalice@example.com,bob@other.comComma-separated list, up to 10 recipients.