mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-11-11 02:41:33 +00:00
14494 lines
462 KiB
YAML
14494 lines
462 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
description: >-
|
|
The API of mailcow, the mail server suite with antispam, antivirus and a
|
|
web UI.
|
|
|
|
|
|
**API keys**: create them in the mailcow UI under System > Configuration >
|
|
Access > Administrators, card API. A key works from its allowed IP
|
|
addresses (or from anywhere if the IP check is skipped). Read-only keys
|
|
may use the `get` routes only. Keys set in mailcow.conf (`API_KEY`,
|
|
`API_KEY_READ_ONLY`, `API_ALLOW_FROM`) are shown in the UI but can only be
|
|
changed in mailcow.conf. A key acts as an administrator.
|
|
|
|
|
|
**Requests**: `get` routes use GET, all others POST with
|
|
`Content-Type: application/json`.
|
|
|
|
- add: the new object as body
|
|
- edit: `{"items": [...], "attr": {...}}`, `items` are the objects to
|
|
change, `attr` the values to set
|
|
- delete: the list of objects to delete
|
|
|
|
|
|
**Answers**: write routes return the list of messages of the call
|
|
(`type`, `msg`), or `{"type": "success", "msg": "Task completed"}` /
|
|
`{"type": "error", "msg": "Cannot add item"}` if there are none. The
|
|
status is 200 for failures too, so check `type`. Read routes return the
|
|
object or list, `{}` or `[]` if there is nothing. Unknown routes answer
|
|
404, invalid JSON 400, a wrong method 405.
|
|
|
|
title: mailcow API
|
|
version: "1.0.0"
|
|
|
|
servers:
|
|
- url: /
|
|
|
|
components:
|
|
securitySchemes:
|
|
ApiKeyAuth:
|
|
type: apiKey
|
|
in: header
|
|
name: X-API-Key
|
|
schemas:
|
|
Message:
|
|
type: object
|
|
description: >-
|
|
One message of a write call, as the mailcow UI shows it. `msg` is a key
|
|
of the mailcow language files, alone or as a list with the values of its
|
|
placeholders.
|
|
properties:
|
|
type:
|
|
type: string
|
|
enum:
|
|
- success
|
|
- danger
|
|
- warning
|
|
- info
|
|
log:
|
|
type: array
|
|
description: >-
|
|
The call that produced the message (function, action, object,
|
|
data), secrets replaced by `*`
|
|
items: {}
|
|
msg:
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items: {}
|
|
required:
|
|
- type
|
|
- msg
|
|
Messages:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Message"
|
|
TaskResult:
|
|
type: object
|
|
description: Answer of a write call that produced no message
|
|
properties:
|
|
type:
|
|
type: string
|
|
enum:
|
|
- success
|
|
- error
|
|
msg:
|
|
type: string
|
|
examples:
|
|
- Task completed
|
|
- Cannot add item
|
|
required:
|
|
- type
|
|
- msg
|
|
Error:
|
|
type: object
|
|
properties:
|
|
type:
|
|
type: string
|
|
const: error
|
|
msg:
|
|
type: string
|
|
required:
|
|
- type
|
|
- msg
|
|
Domain:
|
|
type: object
|
|
description: >-
|
|
A domain. Quotas and sizes are in bytes; the `*_int` fields repeat the
|
|
value before them.
|
|
properties:
|
|
domain_name:
|
|
type: string
|
|
description: Domain name (IDN as punycode)
|
|
domain_h_name:
|
|
type: string
|
|
description: Domain name in Unicode
|
|
description:
|
|
type: string
|
|
description: Description
|
|
max_new_mailbox_quota:
|
|
type: integer
|
|
description: >-
|
|
Largest quota a new mailbox can get: the free domain quota, at most
|
|
the max. mailbox quota
|
|
def_new_mailbox_quota:
|
|
type: integer
|
|
description: Quota a new mailbox gets by default
|
|
quota_used_in_domain:
|
|
type: [string, integer]
|
|
description: Sum of the quotas of the mailboxes
|
|
bytes_total:
|
|
type: [string, integer]
|
|
description: Storage used by the mailboxes
|
|
msgs_total:
|
|
type: [string, integer]
|
|
description: Number of messages in the mailboxes
|
|
mboxes_in_domain:
|
|
type: integer
|
|
description: Number of mailboxes
|
|
mboxes_left:
|
|
type: integer
|
|
description: Mailboxes that can still be added
|
|
max_num_aliases_for_domain:
|
|
type: integer
|
|
description: Max. number of aliases
|
|
max_num_mboxes_for_domain:
|
|
type: integer
|
|
description: Max. number of mailboxes
|
|
def_quota_for_mbox:
|
|
type: integer
|
|
description: Default quota of new mailboxes
|
|
max_quota_for_mbox:
|
|
type: integer
|
|
description: Max. quota per mailbox
|
|
max_quota_for_domain:
|
|
type: integer
|
|
description: Quota of the whole domain
|
|
relayhost:
|
|
type: [string, integer]
|
|
description: ID of the sender-dependent transport, "0" = none
|
|
backupmx:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Relay domain (backup MX)
|
|
backupmx_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
gal:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Global address list in SOGo
|
|
gal_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
rl:
|
|
description: Rate limit, `false` if none
|
|
oneOf:
|
|
- $ref: "#/components/schemas/DomainRatelimit"
|
|
- type: boolean
|
|
const: false
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Domain active
|
|
active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
relay_all_recipients:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Relay all recipients
|
|
relay_all_recipients_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
relay_unknown_only:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Relay non-existing mailboxes only
|
|
relay_unknown_only_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
created:
|
|
type: string
|
|
description: Creation time (`YYYY-MM-DD hh:mm:ss`)
|
|
modified:
|
|
type: [string, "null"]
|
|
description: Time of the last change
|
|
aliases_in_domain:
|
|
type: [integer, string]
|
|
description: Number of aliases, including those of its alias domains
|
|
aliases_left:
|
|
type: integer
|
|
description: Aliases that can still be added
|
|
domain_admins:
|
|
type: string
|
|
description: Comma-separated domain admins, `-` if none; admins only
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Tags; missing when the domain has none
|
|
DomainRatelimit:
|
|
type: object
|
|
description: Rate limit of a domain or alias domain
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Messages per time frame
|
|
frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
description: Time frame (second, minute, hour, day)
|
|
DomainTemplate:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description: Template ID
|
|
template:
|
|
type: string
|
|
description: Template name
|
|
type:
|
|
type: string
|
|
const: domain
|
|
attributes:
|
|
$ref: "#/components/schemas/DomainTemplateAttributes"
|
|
created:
|
|
type: string
|
|
description: Creation time
|
|
modified:
|
|
type: [string, "null"]
|
|
description: Time of the last change
|
|
DomainTemplateAttributes:
|
|
type: object
|
|
description: Values of a domain template as stored; quotas in bytes
|
|
properties:
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
max_num_aliases_for_domain:
|
|
type: integer
|
|
max_num_mboxes_for_domain:
|
|
type: integer
|
|
def_quota_for_mbox:
|
|
type: integer
|
|
max_quota_for_mbox:
|
|
type: integer
|
|
max_quota_for_domain:
|
|
type: integer
|
|
rl_frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
rl_value:
|
|
type: [string, integer]
|
|
description: Rate limit, "" = none
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
gal:
|
|
type: integer
|
|
enum: [0, 1]
|
|
backupmx:
|
|
type: integer
|
|
enum: [0, 1]
|
|
relay_all_recipients:
|
|
type: integer
|
|
enum: [0, 1]
|
|
relay_unknown_only:
|
|
type: integer
|
|
enum: [0, 1]
|
|
dkim_selector:
|
|
type: string
|
|
key_size:
|
|
type: integer
|
|
DomainTemplateInput:
|
|
type: object
|
|
description: >-
|
|
Values of a domain template, quotas in MiB. The defaults apply when a
|
|
template is added; for edit/domain/template see there.
|
|
properties:
|
|
template:
|
|
type: string
|
|
description: Template name, unique
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
default: []
|
|
description: Tags of new domains
|
|
max_num_aliases_for_domain:
|
|
type: [integer, string]
|
|
default: 400
|
|
description: Max. number of aliases
|
|
max_num_mboxes_for_domain:
|
|
type: [integer, string]
|
|
default: 10
|
|
description: Max. number of mailboxes
|
|
def_quota_for_mbox:
|
|
type: [integer, string]
|
|
default: 3072
|
|
description: Default quota of new mailboxes in MiB
|
|
max_quota_for_mbox:
|
|
type: [integer, string]
|
|
default: 10240
|
|
description: Max. quota per mailbox in MiB
|
|
max_quota_for_domain:
|
|
type: [integer, string]
|
|
default: 10240
|
|
description: Quota of the whole domain in MiB
|
|
rl_value:
|
|
type: [integer, string]
|
|
default: ""
|
|
description: Rate limit, messages per `rl_frame`; empty = none
|
|
rl_frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
default: s
|
|
description: Rate limit time frame
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 1
|
|
gal:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 1
|
|
description: Global address list in SOGo
|
|
backupmx:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Relay domain (backup MX)
|
|
relay_all_recipients:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
relay_unknown_only:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
dkim_selector:
|
|
type: string
|
|
default: dkim
|
|
description: Selector of the DKIM key of new domains
|
|
key_size:
|
|
type: [integer, string]
|
|
default: 2048
|
|
description: DKIM key size in bits of new domains
|
|
AliasDomain:
|
|
type: object
|
|
properties:
|
|
alias_domain:
|
|
type: string
|
|
description: Alias domain name
|
|
target_domain:
|
|
type: string
|
|
description: Domain the alias domain points to
|
|
parent_is_backupmx:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: The target domain is a relay domain
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Alias domain active
|
|
active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
rl:
|
|
description: Rate limit, `false` if none
|
|
oneOf:
|
|
- $ref: "#/components/schemas/DomainRatelimit"
|
|
- type: boolean
|
|
const: false
|
|
created:
|
|
type: string
|
|
description: Creation time
|
|
modified:
|
|
type: [string, "null"]
|
|
description: Time of the last change
|
|
DomainPolicyEntry:
|
|
type: object
|
|
properties:
|
|
object:
|
|
type: string
|
|
description: The domain or mailbox the entry belongs to
|
|
value:
|
|
type: string
|
|
description: Sender address or pattern
|
|
prefid:
|
|
type: integer
|
|
description: Entry ID (for delete/domain-policy)
|
|
DkimKey:
|
|
type: object
|
|
properties:
|
|
pubkey:
|
|
type: string
|
|
description: Public key (base64, without PEM lines)
|
|
length:
|
|
type: string
|
|
enum: ["1024", "2048", "3072", "4096", ">= 8192"]
|
|
description: Key size in bits, estimated from the public key
|
|
dkim_txt:
|
|
type: string
|
|
description: >-
|
|
Content of the DNS TXT record; split into quoted strings of 255
|
|
characters when `SPLIT_DKIM_255` is enabled
|
|
dkim_selector:
|
|
type: string
|
|
description: Selector
|
|
privkey:
|
|
type: string
|
|
description: >-
|
|
Private key in PEM format, base64-encoded, when
|
|
`SHOW_DKIM_PRIV_KEYS` is enabled, else empty
|
|
DomainSearchRequest:
|
|
type: object
|
|
description: >-
|
|
Server-side processing parameters of DataTables
|
|
(https://datatables.net/manual/server-side). Without `start` and
|
|
`length` all matching domains are answered.
|
|
properties:
|
|
draw:
|
|
type: integer
|
|
description: Request counter, answered as it is
|
|
start:
|
|
type: integer
|
|
description: Offset of the first domain
|
|
length:
|
|
type: integer
|
|
description: Number of domains, -1 = all
|
|
search:
|
|
type: object
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Searched in all columns with `searchable` true
|
|
order:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
column:
|
|
type: integer
|
|
description: Position in `columns` (see the description of the route)
|
|
dir:
|
|
type: string
|
|
enum: [asc, desc]
|
|
columns:
|
|
type: array
|
|
description: >-
|
|
The columns of the table; the position gives the database column
|
|
(see the description of the route)
|
|
items:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: [string, integer]
|
|
description: >-
|
|
Column name of the UI; a column position makes
|
|
`search.value` of this entry filter that column
|
|
searchable:
|
|
type: [boolean, string]
|
|
description: Column takes part in the global search; must be set
|
|
orderable:
|
|
type: [boolean, string]
|
|
description: Column may be sorted by; must be set
|
|
search:
|
|
type: object
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Filter of this column
|
|
DomainSearchResult:
|
|
type: object
|
|
properties:
|
|
draw:
|
|
type: integer
|
|
description: "`draw` of the request"
|
|
recordsTotal:
|
|
type: integer
|
|
description: Number of domains the caller can see
|
|
recordsFiltered:
|
|
type: integer
|
|
description: Number of domains that match the search
|
|
data:
|
|
type: array
|
|
description: The domains of the page
|
|
items:
|
|
$ref: "#/components/schemas/Domain"
|
|
MailboxItems:
|
|
description: One mailbox address or a list of them
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
UserAclName:
|
|
type: string
|
|
description: "A user ACL: something the mailbox user may do in the UI"
|
|
enum:
|
|
- spam_alias
|
|
- tls_policy
|
|
- spam_score
|
|
- spam_policy
|
|
- delimiter_action
|
|
- syncjobs
|
|
- eas_reset
|
|
- sogo_profile_reset
|
|
- pushover
|
|
- quarantine
|
|
- quarantine_attachments
|
|
- quarantine_notification
|
|
- quarantine_category
|
|
- app_passwds
|
|
- pw_reset
|
|
ProtocolAccessName:
|
|
type: string
|
|
enum:
|
|
- imap
|
|
- pop3
|
|
- smtp
|
|
- sieve
|
|
- eas
|
|
- dav
|
|
MailboxAttributes:
|
|
type: object
|
|
description: Settings of a mailbox; flags are "0" or "1"
|
|
properties:
|
|
force_pw_update:
|
|
type: [string, integer]
|
|
description: The user must change the password at the next login
|
|
force_tfa:
|
|
type: [string, integer]
|
|
description: The user must set up two-factor authentication at the next login
|
|
tls_enforce_in:
|
|
type: [string, integer]
|
|
tls_enforce_out:
|
|
type: [string, integer]
|
|
sogo_access:
|
|
type: [string, integer]
|
|
description: Login to SOGo from the UI
|
|
imap_access:
|
|
type: [string, integer]
|
|
pop3_access:
|
|
type: [string, integer]
|
|
smtp_access:
|
|
type: [string, integer]
|
|
sieve_access:
|
|
type: [string, integer]
|
|
eas_access:
|
|
type: [string, integer]
|
|
dav_access:
|
|
type: [string, integer]
|
|
relayhost:
|
|
type: [string, integer]
|
|
description: ID of the sender-dependent transport, "0" for none
|
|
shared:
|
|
type: [string, integer]
|
|
description: Shared mailbox without a login of its own
|
|
passwd_update:
|
|
type: [string, integer]
|
|
description: Time of the last password change
|
|
mailbox_format:
|
|
type: string
|
|
quarantine_notification:
|
|
type: string
|
|
enum:
|
|
- never
|
|
- hourly
|
|
- daily
|
|
- weekly
|
|
quarantine_category:
|
|
type: string
|
|
enum:
|
|
- reject
|
|
- add_header
|
|
- all
|
|
attribute_hash:
|
|
type: string
|
|
description: Hash of the template the settings came from, cleared by manual changes
|
|
recovery_email:
|
|
type: string
|
|
description: Address for password reset mails (present after it was set)
|
|
template:
|
|
type: string
|
|
description: Name of the template the mailbox was created from (if any)
|
|
Mailbox:
|
|
type: object
|
|
description: >-
|
|
A mailbox. The reduced form lacks `max_new_quota`, `spam_aliases`,
|
|
`pushover_active`, `rl`, `rl_scope`, `is_relayed` and `sender_acl`;
|
|
`tags` is missing without tags.
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Address of the mailbox
|
|
active:
|
|
type: integer
|
|
description: 1 active, 0 inactive, 2 login disabled (mail is still accepted)
|
|
active_int:
|
|
type: integer
|
|
description: Same as `active`
|
|
domain:
|
|
type: string
|
|
name:
|
|
type: string
|
|
description: Full name
|
|
local_part:
|
|
type: string
|
|
quota:
|
|
type: integer
|
|
description: Quota in bytes, 0 = unlimited
|
|
messages:
|
|
type: integer
|
|
description: Number of messages
|
|
attributes:
|
|
$ref: "#/components/schemas/MailboxAttributes"
|
|
custom_attributes:
|
|
type: [object, array]
|
|
description: Custom attributes (an empty list when there are none)
|
|
additionalProperties:
|
|
type: string
|
|
quota_used:
|
|
type: integer
|
|
description: Used bytes
|
|
percent_in_use:
|
|
type: [integer, string]
|
|
description: Used part of the quota in percent, "- " for unlimited quota
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
authsource:
|
|
type: string
|
|
enum:
|
|
- mailcow
|
|
- keycloak
|
|
- generic-oidc
|
|
- ldap
|
|
percent_class:
|
|
type: string
|
|
enum:
|
|
- info
|
|
- success
|
|
- warning
|
|
- danger
|
|
description: info (unlimited), success, warning (≥ 75 %), danger (≥ 90 %)
|
|
last_imap_login:
|
|
type: integer
|
|
description: Unix time of the last IMAP login, 0 = none
|
|
last_smtp_login:
|
|
type: integer
|
|
last_pop3_login:
|
|
type: integer
|
|
last_sso_login:
|
|
type: integer
|
|
last_sogo_login:
|
|
type: integer
|
|
max_new_quota:
|
|
type: integer
|
|
description: Largest quota in bytes the mailbox may get (domain limits)
|
|
spam_aliases:
|
|
type: integer
|
|
description: Number of valid time-limited aliases
|
|
pushover_active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
rl:
|
|
description: Effective rate limit, `false` if there is none
|
|
oneOf:
|
|
- $ref: "#/components/schemas/MailboxRatelimit"
|
|
- type: boolean
|
|
const: false
|
|
rl_scope:
|
|
type: string
|
|
enum:
|
|
- mailbox
|
|
- domain
|
|
description: Whether `rl` is the mailbox's own limit or the domain limit
|
|
is_relayed:
|
|
type: integer
|
|
description: 1 if the domain is relayed (backup MX)
|
|
sender_acl:
|
|
type: array
|
|
description: Internal addresses and @domains the mailbox may send as
|
|
items:
|
|
type: string
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
MailboxAdd:
|
|
type: object
|
|
required:
|
|
- local_part
|
|
- domain
|
|
properties:
|
|
local_part:
|
|
type: string
|
|
description: Part before the @
|
|
domain:
|
|
type: string
|
|
description: Domain of the mailbox
|
|
name:
|
|
type: string
|
|
description: Full name (`<` and `>` at the ends are removed)
|
|
authsource:
|
|
type: string
|
|
enum:
|
|
- mailcow
|
|
- keycloak
|
|
- generic-oidc
|
|
- ldap
|
|
default: mailcow
|
|
description: Login source; an external one only if it is the configured identity provider, else mailcow
|
|
password:
|
|
type: string
|
|
format: password
|
|
description: Checked against the password policy; empty (with `password2`) for a shared mailbox
|
|
password2:
|
|
type: string
|
|
format: password
|
|
description: The password again
|
|
template:
|
|
type: [integer, string]
|
|
description: ID of the mailbox template for the defaults (default the first)
|
|
quota:
|
|
type: [integer, string]
|
|
description: Quota in MiB, 0 = unlimited
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, 2, "0", "1", "2"]
|
|
description: 1 active, 0 inactive, 2 login disabled (mail is accepted)
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Tags (the first 26 are saved)
|
|
protocol_access:
|
|
type: array
|
|
description: Allowed protocols; when sent it replaces the single `*_access` fields
|
|
items:
|
|
$ref: "#/components/schemas/ProtocolAccessName"
|
|
imap_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
pop3_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
smtp_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
sieve_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
eas_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
dav_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
sogo_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Login to SOGo from the UI
|
|
force_pw_update:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Password change at the first login (always 0 for external sources)
|
|
force_tfa:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Two-factor setup at the first login (always 0 for generic-oidc)
|
|
tls_enforce_in:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
tls_enforce_out:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
relayhost:
|
|
type: [integer, string]
|
|
default: 0
|
|
description: ID of a sender-dependent transport, 0 = none
|
|
shared:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Shared mailbox without a login of its own, opened by group members
|
|
quarantine_notification:
|
|
type: string
|
|
enum:
|
|
- never
|
|
- hourly
|
|
- daily
|
|
- weekly
|
|
quarantine_category:
|
|
type: string
|
|
enum:
|
|
- reject
|
|
- add_header
|
|
- all
|
|
tagged_mail_handler:
|
|
type: string
|
|
enum:
|
|
- subfolder
|
|
- subject
|
|
- none
|
|
description: Handling of mail to address+tag, see `edit/delimiter_action`
|
|
acl:
|
|
type: array
|
|
description: User ACLs to grant; when sent, all others are off
|
|
items:
|
|
$ref: "#/components/schemas/UserAclName"
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Rate limit, messages per `rl_frame` (0 or empty = none)
|
|
rl_frame:
|
|
type: string
|
|
enum:
|
|
- s
|
|
- m
|
|
- h
|
|
- d
|
|
attribute_hash:
|
|
type: string
|
|
description: Internal, the hash of the template the values come from
|
|
MailboxEdit:
|
|
type: object
|
|
properties:
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, 2, "0", "1", "2"]
|
|
description: 1 active, 0 inactive, 2 login disabled (mail is accepted)
|
|
name:
|
|
type: string
|
|
description: Full name; empty keeps the current name
|
|
quota:
|
|
type: [integer, string]
|
|
description: Quota in MiB, 0 = unlimited; empty keeps the current quota
|
|
password:
|
|
type: string
|
|
format: password
|
|
description: New password (authsource mailcow), checked against the password policy
|
|
password2:
|
|
type: string
|
|
format: password
|
|
authsource:
|
|
type: string
|
|
enum:
|
|
- mailcow
|
|
- keycloak
|
|
- generic-oidc
|
|
- ldap
|
|
description: An external source only if it is the configured identity provider
|
|
pw_recovery_email:
|
|
type: string
|
|
description: Address for password reset mails (authsource mailcow only)
|
|
force_pw_update:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
force_tfa:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
sogo_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
protocol_access:
|
|
type: array
|
|
description: Allowed protocols; when sent it replaces the single `*_access` fields
|
|
items:
|
|
$ref: "#/components/schemas/ProtocolAccessName"
|
|
imap_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
pop3_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
smtp_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
sieve_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
eas_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
dav_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
relayhost:
|
|
type: [integer, string]
|
|
description: ID of a sender-dependent transport, 0 = none
|
|
shared:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Tags to add; existing tags stay (remove with `delete/mailbox/tag/{mailbox}`)
|
|
tagged_mail_handler:
|
|
type: string
|
|
enum:
|
|
- subfolder
|
|
- subject
|
|
- none
|
|
sender_acl:
|
|
description: >-
|
|
Replaces the internal addresses and @domains the mailbox may send
|
|
as; `*` (admins only) allows all, `["default"]` removes all
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
extended_sender_acl:
|
|
type: string
|
|
description: Replaces the external sender addresses or domains, separated by space, comma or semicolon
|
|
attribute_hash:
|
|
type: string
|
|
description: Internal; cleared when not sent
|
|
MailboxTemplateInput:
|
|
type: object
|
|
properties:
|
|
quota:
|
|
type: [integer, string]
|
|
default: 0
|
|
description: Quota in MiB, 0 = unlimited
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
tagged_mail_handler:
|
|
type: string
|
|
enum:
|
|
- subfolder
|
|
- subject
|
|
- none
|
|
default: none
|
|
quarantine_notification:
|
|
type: string
|
|
enum:
|
|
- never
|
|
- hourly
|
|
- daily
|
|
- weekly
|
|
default: hourly
|
|
quarantine_category:
|
|
type: string
|
|
enum:
|
|
- reject
|
|
- add_header
|
|
- all
|
|
default: reject
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Rate limit, messages per `rl_frame`
|
|
rl_frame:
|
|
type: string
|
|
enum:
|
|
- s
|
|
- m
|
|
- h
|
|
- d
|
|
default: s
|
|
force_pw_update:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
force_tfa:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
sogo_access:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, 2, "0", "1", "2"]
|
|
default: 1
|
|
tls_enforce_in:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
tls_enforce_out:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
protocol_access:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/ProtocolAccessName"
|
|
description: Allowed protocols (default all)
|
|
acl:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/UserAclName"
|
|
description: User ACLs granted to new mailboxes
|
|
MailboxTemplate:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
template:
|
|
type: string
|
|
description: Name
|
|
type:
|
|
type: string
|
|
const: mailbox
|
|
attributes:
|
|
type: object
|
|
description: The settings as in the example; quota in bytes, one `acl_<name>` flag per user ACL
|
|
additionalProperties: true
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
Resource:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Address of the resource
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- location
|
|
- group
|
|
- thing
|
|
multiple_bookings:
|
|
type: integer
|
|
description: 0 always free, -1 unlimited but busy when booked, n ≥ 1 at most n bookings
|
|
description:
|
|
type: string
|
|
active:
|
|
type: integer
|
|
active_int:
|
|
type: integer
|
|
domain:
|
|
type: string
|
|
local_part:
|
|
type: string
|
|
AppPassword:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
mailbox:
|
|
type: string
|
|
domain:
|
|
type: string
|
|
password:
|
|
type: string
|
|
description: Hash of the app password
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
imap_access:
|
|
type: integer
|
|
smtp_access:
|
|
type: integer
|
|
dav_access:
|
|
type: integer
|
|
eas_access:
|
|
type: integer
|
|
pop3_access:
|
|
type: integer
|
|
sieve_access:
|
|
type: integer
|
|
active:
|
|
type: integer
|
|
SieveFilter:
|
|
type: object
|
|
properties:
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
id:
|
|
type: integer
|
|
username:
|
|
type: string
|
|
description: Mailbox
|
|
filter_type:
|
|
type: string
|
|
enum:
|
|
- prefilter
|
|
- postfilter
|
|
script_data:
|
|
type: string
|
|
description: The Sieve script
|
|
script_desc:
|
|
type: string
|
|
TimeLimitedAlias:
|
|
type: object
|
|
properties:
|
|
address:
|
|
type: string
|
|
goto:
|
|
type: string
|
|
description: Mailbox the alias delivers to
|
|
description:
|
|
type: string
|
|
validity:
|
|
type: integer
|
|
description: Unix time of expiry (0 when made permanent by an edit)
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
permanent:
|
|
type: integer
|
|
enum: [0, 1]
|
|
SpamPolicyEntry:
|
|
type: object
|
|
properties:
|
|
object:
|
|
type: string
|
|
description: Mailbox or domain the entry belongs to
|
|
value:
|
|
type: string
|
|
description: Sender address, domain or pattern
|
|
prefid:
|
|
type: integer
|
|
description: ID for `delete/mailbox-policy`
|
|
MailboxRatelimit:
|
|
type: object
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Number of messages
|
|
frame:
|
|
type: string
|
|
enum:
|
|
- s
|
|
- m
|
|
- h
|
|
- d
|
|
description: Per second, minute, hour or day
|
|
SpamScore:
|
|
type: object
|
|
properties:
|
|
score:
|
|
type: string
|
|
description: '"low,high": junk folder from low, rejected from high'
|
|
LastLogin:
|
|
type: object
|
|
properties:
|
|
ui:
|
|
description: Previous successful UI login, `false` if there is none, `[]` for domain admins
|
|
oneOf:
|
|
- type: object
|
|
properties:
|
|
remote:
|
|
type: string
|
|
description: IP address
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
- type: boolean
|
|
const: false
|
|
- type: array
|
|
maxItems: 0
|
|
sasl:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
real_rip:
|
|
type: string
|
|
description: Client IP; private and internal addresses as "Web/EAS/Internal (address)"
|
|
datetime:
|
|
type: string
|
|
service:
|
|
type: string
|
|
description: e.g. imap, smtp, pop3, SOGO, SSO, MAILCOWUI
|
|
app_password:
|
|
type: integer
|
|
description: ID of the app password used, 0 = none
|
|
app_password_name:
|
|
type: [string, "null"]
|
|
location:
|
|
type: string
|
|
description: Country code of public addresses (if known)
|
|
MailboxSearchRequest:
|
|
type: object
|
|
description: DataTables server-side request
|
|
properties:
|
|
draw:
|
|
type: integer
|
|
description: Counter, returned unchanged
|
|
start:
|
|
type: integer
|
|
description: Offset of the first row; without it all rows are returned
|
|
length:
|
|
type: integer
|
|
description: Rows per page, -1 = all
|
|
search:
|
|
type: object
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Searched in all searchable columns (substring)
|
|
order:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
column:
|
|
type: integer
|
|
description: Column number (index in `columns`)
|
|
dir:
|
|
type: string
|
|
enum:
|
|
- asc
|
|
- desc
|
|
columns:
|
|
type: array
|
|
description: Column n of the table is `columns[n]`; needed to search or sort
|
|
items:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: [string, integer]
|
|
description: >-
|
|
Name of the column in the UI; for this column's
|
|
`search.value` only a column number works, other values
|
|
filter the address
|
|
searchable:
|
|
type: [boolean, string]
|
|
description: true or "true" includes the column in the search
|
|
orderable:
|
|
type: [boolean, string]
|
|
description: true or "true" allows sorting by the column
|
|
search:
|
|
type: object
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: Filter for this column only (substring)
|
|
MailboxSearchResult:
|
|
type: object
|
|
properties:
|
|
draw:
|
|
type: integer
|
|
recordsTotal:
|
|
type: integer
|
|
recordsFiltered:
|
|
type: integer
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
Alias:
|
|
type: object
|
|
properties:
|
|
in_primary_domain:
|
|
type: string
|
|
description: Target domain if `domain` is an alias domain, else empty
|
|
id:
|
|
type: integer
|
|
domain:
|
|
type: string
|
|
description: Domain of the address, a domain or alias domain
|
|
public_comment:
|
|
type: [string, "null"]
|
|
description: Comment shown to the users
|
|
private_comment:
|
|
type: [string, "null"]
|
|
description: Comment for administrators
|
|
goto:
|
|
type: string
|
|
description: >-
|
|
Comma-separated destination addresses, or `null@localhost`
|
|
(discard), `spam@localhost` (learn as spam), `ham@localhost` (learn
|
|
as ham)
|
|
address:
|
|
type: string
|
|
description: Alias address, `@example.org` for a catch-all
|
|
is_catch_all:
|
|
type: integer
|
|
description: 1 = catch-all of the domain
|
|
internal:
|
|
type: integer
|
|
description: 1 = only reachable from its own domain and its alias domains
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
active_int:
|
|
type: integer
|
|
description: Same as `active`
|
|
sogo_visible:
|
|
type: integer
|
|
description: 1 = selectable sender in SOGo
|
|
sogo_visible_int:
|
|
type: integer
|
|
description: Same as `sogo_visible`
|
|
sender_allowed:
|
|
type: integer
|
|
description: 1 = the destination mailboxes may send as this alias
|
|
group_id:
|
|
type: [integer, "null"]
|
|
description: >-
|
|
Mailbox group whose distribution address this is; such aliases can
|
|
only be changed in the group
|
|
group_name:
|
|
type: [string, "null"]
|
|
description: Name of that mailbox group
|
|
created:
|
|
type: string
|
|
description: Creation time, `YYYY-MM-DD hh:mm:ss`
|
|
modified:
|
|
type: [string, "null"]
|
|
description: Time of the last change
|
|
BccMap:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
local_dest:
|
|
type: string
|
|
description: Domain as `@example.org` or the address of a mailbox or alias
|
|
bcc_dest:
|
|
type: string
|
|
description: Address that gets the copies
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
type:
|
|
type: string
|
|
enum:
|
|
- sender
|
|
- rcpt
|
|
description: "`sender`: mail sent by `local_dest`; `rcpt`: mail sent to it"
|
|
created:
|
|
type: string
|
|
domain:
|
|
type: string
|
|
description: Domain of `local_dest`
|
|
modified:
|
|
type: [string, "null"]
|
|
RecipientMap:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
recipient_map_old:
|
|
type: string
|
|
description: Original recipient, an address or `@domain`
|
|
recipient_map_new:
|
|
type: string
|
|
description: New recipient, an address or `@domain`
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
TlsPolicyMap:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
dest:
|
|
type: string
|
|
description: Destination
|
|
policy:
|
|
type: string
|
|
enum:
|
|
- none
|
|
- may
|
|
- encrypt
|
|
- dane
|
|
- dane-only
|
|
- fingerprint
|
|
- verify
|
|
- secure
|
|
parameters:
|
|
type: [string, "null"]
|
|
description: Space-separated `name=value` attributes, may be empty
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
created:
|
|
type: string
|
|
modified:
|
|
type: [string, "null"]
|
|
Relayhost:
|
|
type: object
|
|
description: A sender-dependent transport
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description: The value domains and mailboxes use as `relayhost`
|
|
hostname:
|
|
type: string
|
|
description: Next hop
|
|
username:
|
|
type: string
|
|
description: SMTP user name, empty without authentication
|
|
password:
|
|
type: string
|
|
description: SMTP password in clear text
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
password_short:
|
|
type: string
|
|
description: First three characters of the password and `...`
|
|
used_by_domains:
|
|
type: string
|
|
description: Comma-separated domains that use the transport, may be empty
|
|
used_by_mailboxes:
|
|
type: string
|
|
description: Comma-separated mailboxes that use the transport, may be empty
|
|
Transport:
|
|
type: object
|
|
description: A transport map entry
|
|
properties:
|
|
id:
|
|
type: integer
|
|
is_mx_based:
|
|
type: integer
|
|
description: 1 = `destination` is a regular expression for MX names
|
|
destination:
|
|
type: string
|
|
nexthop:
|
|
type: string
|
|
username:
|
|
type: string
|
|
description: SMTP user name, empty without authentication
|
|
password:
|
|
type: string
|
|
description: SMTP password in clear text
|
|
active:
|
|
type: integer
|
|
description: 1 = active, 0 = inactive
|
|
password_short:
|
|
type: string
|
|
description: First three characters of the password and `...`
|
|
ForwardingHost:
|
|
type: object
|
|
properties:
|
|
host:
|
|
type: string
|
|
description: IP address or network
|
|
source:
|
|
type: string
|
|
description: What was added (host name, domain or the address itself)
|
|
keep_spam:
|
|
type: string
|
|
enum:
|
|
- "yes"
|
|
- "no"
|
|
description: "`yes` = the mail of the host is not scanned for spam"
|
|
RspamdSettingAttributes:
|
|
type: object
|
|
properties:
|
|
desc:
|
|
type: string
|
|
description: Short description
|
|
content:
|
|
type: string
|
|
description: Rule content in Rspamd settings syntax
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = the rule is handed to Rspamd
|
|
default: 0
|
|
required:
|
|
- desc
|
|
- content
|
|
RspamdSetting:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
desc:
|
|
type: string
|
|
description: Short description
|
|
content:
|
|
type: string
|
|
description: Rule content in Rspamd settings syntax
|
|
active:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
RspamdRegexMap:
|
|
type: string
|
|
description: File name of a global Rspamd regex map
|
|
enum:
|
|
- global_mime_from_blacklist.map
|
|
- global_mime_from_whitelist.map
|
|
- global_smtp_from_blacklist.map
|
|
- global_smtp_from_whitelist.map
|
|
- global_rcpt_blacklist.map
|
|
- global_rcpt_whitelist.map
|
|
- fishy_tlds.map
|
|
- bad_words.map
|
|
- bad_words_de.map
|
|
- bad_languages.map
|
|
- bulk_header.map
|
|
- bad_header.map
|
|
- monitoring_nolog.map
|
|
Preset:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: File name of the preset without `.yml`
|
|
headline:
|
|
type: string
|
|
description: Title, translated
|
|
content:
|
|
type: string
|
|
description: Rspamd settings rule or Sieve script
|
|
GlobalFilters:
|
|
type: object
|
|
properties:
|
|
prefilter:
|
|
type: string
|
|
description: Sieve script that runs before the filters of the mailboxes
|
|
postfilter:
|
|
type: string
|
|
description: Sieve script that runs after the filters of the mailboxes
|
|
MailQueueItem:
|
|
type: object
|
|
description: One message of `postqueue -j`
|
|
properties:
|
|
queue_name:
|
|
type: string
|
|
description: Queue, e.g. `active`, `deferred`, `hold`, `incoming`
|
|
queue_id:
|
|
type: string
|
|
arrival_time:
|
|
type: integer
|
|
description: Unix time
|
|
message_size:
|
|
type: integer
|
|
description: Size in bytes
|
|
forced_expire:
|
|
type: boolean
|
|
sender:
|
|
type: string
|
|
recipients:
|
|
type: array
|
|
description: Recipient addresses, with the reason of the delay in brackets if there is one
|
|
items:
|
|
type: string
|
|
QuarantineItem:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
qid:
|
|
type: string
|
|
description: Postfix queue ID of the message
|
|
subject:
|
|
type: string
|
|
virus_flag:
|
|
type: integer
|
|
description: Greater than 0 when Rspamd found a virus (`VIRUS_FOUND`)
|
|
score:
|
|
type: number
|
|
description: Rspamd score
|
|
rcpt:
|
|
type: string
|
|
description: Mailbox the item belongs to
|
|
sender:
|
|
type: string
|
|
action:
|
|
type: string
|
|
description: Rspamd action, e.g. `reject` or `add header`
|
|
created:
|
|
type: integer
|
|
description: Unix time
|
|
notified:
|
|
type: integer
|
|
description: 1 when the recipient got a notification
|
|
QuarantineItemDetails:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
qid:
|
|
type: string
|
|
description: Postfix queue ID of the message
|
|
subject:
|
|
type: string
|
|
score:
|
|
type: number
|
|
description: Rspamd score
|
|
ip:
|
|
type: string
|
|
description: IP of the sending server
|
|
action:
|
|
type: string
|
|
description: Rspamd action
|
|
symbols:
|
|
type: string
|
|
description: Rspamd symbols as JSON text
|
|
fuzzy_hashes:
|
|
type: string
|
|
description: Fuzzy hashes as JSON text
|
|
sender:
|
|
type: string
|
|
rcpt:
|
|
type: string
|
|
description: Mailbox the item belongs to
|
|
msg:
|
|
type: string
|
|
description: The raw message
|
|
domain:
|
|
type: [string, "null"]
|
|
notified:
|
|
type: integer
|
|
description: 1 when the recipient got a notification
|
|
created:
|
|
type: string
|
|
description: Time of quarantining (`YYYY-MM-DD HH:MM:SS`)
|
|
user:
|
|
type: string
|
|
description: Authenticated sender, `unknown` if none
|
|
qhash:
|
|
type: string
|
|
description: Secret of the release and delete links in the notification mails
|
|
Fail2Ban:
|
|
type: object
|
|
properties:
|
|
ban_time:
|
|
type: integer
|
|
description: Ban time in seconds
|
|
ban_time_increment:
|
|
type: boolean
|
|
description: The ban time grows with every ban of a network
|
|
max_ban_time:
|
|
type: integer
|
|
description: Maximum ban time in seconds
|
|
netban_ipv4:
|
|
type: integer
|
|
description: IPv4 prefix length that is banned
|
|
netban_ipv6:
|
|
type: integer
|
|
description: IPv6 prefix length that is banned
|
|
max_attempts:
|
|
type: integer
|
|
description: Failed logins within `retry_window` that lead to a ban
|
|
retry_window:
|
|
type: integer
|
|
description: Window in seconds for `max_attempts`
|
|
banlist_id:
|
|
type: string
|
|
description: ID of the banlist URL `/f2b-banlist?id=<banlist_id>`
|
|
manage_external:
|
|
type: integer
|
|
description: 1 = netfilter sets no rules, the banlist is for an external firewall
|
|
regex:
|
|
type: object
|
|
description: Regex filters by number
|
|
additionalProperties:
|
|
type: string
|
|
whitelist:
|
|
type: string
|
|
description: Allowlisted networks and hosts, one per line
|
|
blacklist:
|
|
type: string
|
|
description: Denylisted networks, one per line
|
|
perm_bans:
|
|
type: array
|
|
description: Permanent bans (only present when there are any)
|
|
items:
|
|
type: object
|
|
properties:
|
|
network:
|
|
type: string
|
|
ip:
|
|
type: string
|
|
active_bans:
|
|
type: array
|
|
description: Active bans (only present when there are any)
|
|
items:
|
|
type: object
|
|
properties:
|
|
queued_for_unban:
|
|
type: integer
|
|
description: 1 when the ban is about to be lifted
|
|
network:
|
|
type: string
|
|
ip:
|
|
type: string
|
|
banned_until:
|
|
type: string
|
|
description: Remaining ban time, e.g. `00h 27m 08s`
|
|
Admin:
|
|
type: object
|
|
description: An administrator account
|
|
properties:
|
|
username:
|
|
type: string
|
|
tfa_active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = two-factor authentication is active
|
|
tfa_active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Same as `tfa_active`
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = the account can log in
|
|
active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Same as `active`
|
|
created:
|
|
type: string
|
|
description: Creation time (`YYYY-MM-DD hh:mm:ss`)
|
|
attributes:
|
|
type: object
|
|
properties:
|
|
force_tfa:
|
|
type: string
|
|
enum: ["0", "1"]
|
|
description: "\"1\" = two-factor authentication must be set up at the next login"
|
|
force_pw_update:
|
|
type: string
|
|
enum: ["0", "1"]
|
|
description: "\"1\" = the password must be changed at the next login"
|
|
DomainAdmin:
|
|
type: object
|
|
description: A domain administrator account
|
|
properties:
|
|
username:
|
|
type: string
|
|
tfa_active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = two-factor authentication is active
|
|
tfa_active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Same as `tfa_active`
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = the account can log in
|
|
active_int:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: Same as `active`
|
|
created:
|
|
type: string
|
|
description: Creation time (`YYYY-MM-DD hh:mm:ss`)
|
|
attributes:
|
|
type: object
|
|
properties:
|
|
force_tfa:
|
|
type: string
|
|
enum: ["0", "1"]
|
|
description: "\"1\" = two-factor authentication must be set up at the next login"
|
|
force_pw_update:
|
|
type: string
|
|
enum: ["0", "1"]
|
|
description: "\"1\" = the password must be changed at the next login"
|
|
selected_domains:
|
|
type: array
|
|
description: The domains the account administers
|
|
items:
|
|
type: string
|
|
unselected_domains:
|
|
description: All other domains, `""` if there are none
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
const: ""
|
|
DomainAdminAcl:
|
|
type: string
|
|
description: >-
|
|
ACL of a domain administrator. New domain administrators get all except
|
|
`pushover`, `extend_sender_acl` (sender ACL with external addresses),
|
|
`unlimited_quota`, `alias_domains` and `domain_desc`.
|
|
enum:
|
|
- syncjobs
|
|
- quarantine
|
|
- login_as
|
|
- sogo_access
|
|
- app_passwds
|
|
- bcc_maps
|
|
- pushover
|
|
- filters
|
|
- ratelimit
|
|
- spam_policy
|
|
- extend_sender_acl
|
|
- unlimited_quota
|
|
- protocol_access
|
|
- smtp_ip_access
|
|
- alias_domains
|
|
- mailbox_relayhost
|
|
- domain_relayhost
|
|
- domain_desc
|
|
- alias_external_goto
|
|
- mailbox_groups
|
|
ApiKey:
|
|
type: object
|
|
description: An API key
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description:
|
|
type: string
|
|
description: Free text; `API_KEY` or `API_KEY_READ_ONLY` for the service keys
|
|
access:
|
|
type: string
|
|
enum:
|
|
- ro
|
|
- rw
|
|
description: "`ro`: read-only (get routes only), `rw`: read/write"
|
|
api_key:
|
|
type: string
|
|
description: The key value, sent in the `X-API-Key` header
|
|
allow_from:
|
|
type: array
|
|
description: IP addresses and networks the key may be used from
|
|
items:
|
|
type: string
|
|
skip_ip_check:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = the key may be used from any address
|
|
service:
|
|
type: integer
|
|
enum: [0, 1]
|
|
description: 1 = service key from mailcow.conf, can only be changed there
|
|
active:
|
|
type: integer
|
|
enum: [0, 1]
|
|
created:
|
|
type: [string, "null"]
|
|
modified:
|
|
type: [string, "null"]
|
|
ApiKeyAttributes:
|
|
type: object
|
|
description: Attributes of an API key for add and edit
|
|
properties:
|
|
description:
|
|
type: string
|
|
description: Free text, at most 255 characters
|
|
default: ""
|
|
access:
|
|
type: string
|
|
enum:
|
|
- ro
|
|
- rw
|
|
description: "`ro`: read-only (get routes only), `rw`: read/write. Required for a new key."
|
|
allow_from:
|
|
description: >-
|
|
Allowed IP addresses and CIDR networks, as list or as string
|
|
separated by spaces, commas, semicolons or newlines. An edit
|
|
replaces the list.
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
skip_ip_check:
|
|
type: [integer, string, boolean]
|
|
description: 1/true = allow the key from any address
|
|
default: 0
|
|
active:
|
|
type: [integer, string, boolean]
|
|
description: 1/true = active
|
|
default: 1
|
|
OAuth2Client:
|
|
type: object
|
|
description: An OAuth2 client of the mailcow OAuth2 server
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description: ID used by the API
|
|
client_id:
|
|
type: string
|
|
description: OAuth2 client ID
|
|
client_secret:
|
|
type: string
|
|
description: OAuth2 client secret
|
|
redirect_uri:
|
|
type: string
|
|
description: Redirect (callback) URL
|
|
grant_types:
|
|
type: [string, "null"]
|
|
description: Not used
|
|
scope:
|
|
type: string
|
|
description: Always `profile`
|
|
user_id:
|
|
type: [string, "null"]
|
|
description: Not used
|
|
SyslogLogEntry:
|
|
type: object
|
|
description: A log line of a container
|
|
properties:
|
|
time:
|
|
type: string
|
|
description: Unix time
|
|
program:
|
|
type: string
|
|
description: Process that wrote the line
|
|
priority:
|
|
type: string
|
|
description: Syslog priority (`info`, `warning`, `err`, ...)
|
|
message:
|
|
type: string
|
|
AcmeLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: string
|
|
description: Unix time
|
|
message:
|
|
type: string
|
|
ApiLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
uri:
|
|
type: string
|
|
description: Request URI
|
|
method:
|
|
type: string
|
|
description: HTTP method
|
|
remote:
|
|
type: string
|
|
description: Client address
|
|
data:
|
|
type: string
|
|
description: Form data of the request (`attr`, `items`), secrets replaced by `*`
|
|
AutodiscoverLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
ua:
|
|
type: string
|
|
description: User agent of the client
|
|
user:
|
|
type: string
|
|
description: Requested e-mail address
|
|
ip:
|
|
type: string
|
|
description: Client address
|
|
service:
|
|
type: string
|
|
description: Offered service (`activesync`, `imap`) or an error
|
|
CronLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
priority:
|
|
type: string
|
|
task:
|
|
type: string
|
|
description: Name of the task
|
|
message:
|
|
type: string
|
|
NetfilterLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
priority:
|
|
type: string
|
|
description: "`info`, `warn` or `crit` (bans)"
|
|
message:
|
|
type: string
|
|
RatelimitLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
rcpt:
|
|
type: string
|
|
description: Recipients, comma separated
|
|
from:
|
|
type: string
|
|
description: Envelope sender
|
|
user:
|
|
type: string
|
|
description: Authenticated user
|
|
rl_info:
|
|
type: string
|
|
description: Rate limit that was hit, `name(hash)`
|
|
rl_name:
|
|
type: string
|
|
description: Name of the rate limit (mailbox or domain)
|
|
rl_hash:
|
|
type: string
|
|
description: Hash of the rate limit bucket (see `delete/rlhash`)
|
|
qid:
|
|
type: string
|
|
description: Postfix queue ID
|
|
ip:
|
|
type: string
|
|
description: Client address
|
|
message_id:
|
|
type: string
|
|
header_subject:
|
|
type: string
|
|
header_from:
|
|
type: string
|
|
RspamdHistoryEntry:
|
|
type: object
|
|
description: A message scanned by Rspamd (fields of Rspamd's history)
|
|
properties:
|
|
unix_time:
|
|
type: integer
|
|
time_real:
|
|
type: number
|
|
description: Scan time in seconds
|
|
score:
|
|
type: number
|
|
required_score:
|
|
type: number
|
|
action:
|
|
type: string
|
|
description: "`no action`, `greylist`, `add header`, `rewrite subject`, `soft reject` or `reject`"
|
|
thresholds:
|
|
type: object
|
|
additionalProperties:
|
|
type: number
|
|
ip:
|
|
type: string
|
|
user:
|
|
type: string
|
|
description: Authenticated user, `unknown` for incoming mail
|
|
sender_smtp:
|
|
type: string
|
|
sender_mime:
|
|
type: string
|
|
rcpt_smtp:
|
|
type: array
|
|
items:
|
|
type: string
|
|
rcpt_mime:
|
|
type: array
|
|
items:
|
|
type: string
|
|
subject:
|
|
type: string
|
|
message-id:
|
|
type: string
|
|
size:
|
|
type: integer
|
|
is_skipped:
|
|
type: boolean
|
|
symbols:
|
|
type: object
|
|
description: Matched symbols by name
|
|
additionalProperties:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
score:
|
|
type: number
|
|
metric_score:
|
|
type: number
|
|
description:
|
|
type: string
|
|
options:
|
|
type: array
|
|
items:
|
|
type: string
|
|
additionalProperties: true
|
|
RspamdStats:
|
|
type: object
|
|
description: Statistics of Rspamd's controller (`/stat`)
|
|
properties:
|
|
version:
|
|
type: string
|
|
config_id:
|
|
type: string
|
|
uptime:
|
|
type: integer
|
|
description: Seconds
|
|
read_only:
|
|
type: boolean
|
|
scanned:
|
|
type: integer
|
|
learned:
|
|
type: integer
|
|
actions:
|
|
type: object
|
|
description: Number of messages per action
|
|
additionalProperties:
|
|
type: integer
|
|
scan_times:
|
|
type: array
|
|
items:
|
|
type: [number, "null"]
|
|
spam_count:
|
|
type: integer
|
|
ham_count:
|
|
type: integer
|
|
connections:
|
|
type: integer
|
|
control_connections:
|
|
type: integer
|
|
total_learns:
|
|
type: integer
|
|
statfiles:
|
|
type: array
|
|
description: Bayes statistics
|
|
items:
|
|
type: object
|
|
fuzzy_hashes:
|
|
type: object
|
|
additionalProperties:
|
|
type: integer
|
|
additionalProperties: true
|
|
SaslLogEntry:
|
|
type: object
|
|
properties:
|
|
service:
|
|
type: string
|
|
description: "`imap`, `pop3`, `smtp`, `sieve`, `SSO` (SOGo), ..."
|
|
app_password:
|
|
type: integer
|
|
description: ID of the app password used, 0 = the mailbox password
|
|
username:
|
|
type: string
|
|
real_rip:
|
|
type: string
|
|
description: Client address
|
|
datetime:
|
|
type: string
|
|
description: Time of the last login (`YYYY-MM-DD hh:mm:ss`)
|
|
UiLogEntry:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
task:
|
|
type: string
|
|
description: ID of the request
|
|
type:
|
|
type: string
|
|
description: "`success`, `danger`, `warning` or `info`"
|
|
msg:
|
|
type: string
|
|
description: The message (JSON)
|
|
call:
|
|
type: string
|
|
description: The call that produced it (JSON)
|
|
user:
|
|
type: string
|
|
description: Account (`API` for API keys)
|
|
role:
|
|
type: string
|
|
remote:
|
|
type: string
|
|
description: Client address
|
|
time:
|
|
type: integer
|
|
description: Unix time
|
|
WatchdogLogEntry:
|
|
type: object
|
|
properties:
|
|
time:
|
|
type: string
|
|
description: Unix time
|
|
service:
|
|
type: string
|
|
description: Checked service
|
|
lvl:
|
|
type: string
|
|
description: Health in percent
|
|
hpnow:
|
|
type: string
|
|
description: Current health points
|
|
hptotal:
|
|
type: string
|
|
description: Maximum health points
|
|
hpdiff:
|
|
type: string
|
|
description: Change since the last check
|
|
ContainerStatus:
|
|
type: object
|
|
properties:
|
|
type:
|
|
type: string
|
|
const: info
|
|
container:
|
|
type: string
|
|
description: Service name
|
|
state:
|
|
type: string
|
|
description: Docker state (`running`, `exited`, `restarting`, ...)
|
|
started_at:
|
|
type: string
|
|
description: Start time (RFC 3339)
|
|
image:
|
|
type: string
|
|
HostStats:
|
|
type: object
|
|
properties:
|
|
cpu:
|
|
type: object
|
|
properties:
|
|
cores:
|
|
type: integer
|
|
usage:
|
|
type: number
|
|
description: CPU usage in percent
|
|
memory:
|
|
type: object
|
|
properties:
|
|
total:
|
|
type: integer
|
|
description: Bytes
|
|
usage:
|
|
type: number
|
|
description: Memory usage in percent
|
|
swap:
|
|
type: array
|
|
description: Swap total, used, free (bytes), used percent, swapped in, swapped out (bytes)
|
|
items:
|
|
type: number
|
|
uptime:
|
|
type: number
|
|
description: Seconds since boot
|
|
system_time:
|
|
type: string
|
|
description: Host time (`DD.MM.YYYY hh:mm:ss`)
|
|
architecture:
|
|
type: string
|
|
PasswordPolicy:
|
|
type: object
|
|
description: Password policy; the values are strings, `false` if never saved
|
|
properties:
|
|
length:
|
|
type: [string, boolean]
|
|
description: Minimum length
|
|
chars:
|
|
type: [string, boolean]
|
|
description: "\"1\": at least one letter"
|
|
special_chars:
|
|
type: [string, boolean]
|
|
description: "\"1\": at least one character that is no letter or digit"
|
|
lowerupper:
|
|
type: [string, boolean]
|
|
description: "\"1\": lowercase and uppercase letters"
|
|
numbers:
|
|
type: [string, boolean]
|
|
description: "\"1\": at least one digit"
|
|
MailboxGroupAttributes:
|
|
type: object
|
|
description: >-
|
|
Attributes of a mailbox group. Flags take `1`, `true`, `on` or `yes`
|
|
for on, anything else is off. Lists take a JSON array or a string
|
|
separated by spaces, commas, semicolons or newlines; entries are
|
|
lowercased.
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: 1-100 characters, unique in the domain
|
|
description:
|
|
type: string
|
|
description: Max. 255 characters
|
|
default: ""
|
|
address:
|
|
type: string
|
|
description: >-
|
|
Distribution address in the domain of the group, not used by a
|
|
mailbox or alias yet; empty = none. Wins over `local_part`.
|
|
local_part:
|
|
type: string
|
|
description: Local part of the address in the domain of the group; empty = no address
|
|
members:
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: string
|
|
description: Regular mailboxes; replaces the manual members the caller may access
|
|
add_members:
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: string
|
|
description: Mailboxes to add
|
|
remove_members:
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: string
|
|
description: Manual members to remove
|
|
send_as:
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: string
|
|
description: >-
|
|
Replaces the addresses the members may send as: mailbox or alias
|
|
addresses or `@domain`; for the group address use `sender_allowed`
|
|
sender_allowed:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: Members may send as the group address
|
|
default: 0
|
|
sogo_visible:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: Offer the group address as identity in SOGo (only with `sender_allowed`)
|
|
default: 0
|
|
internal:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: Only senders of the domain may write to the group address
|
|
default: 0
|
|
active:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
default: 1
|
|
imap_grants:
|
|
description: >-
|
|
Replaces the mailboxes the members may open as Shared/<mailbox>; the
|
|
caller needs access to every owner. `subscribe` subscribes the
|
|
folders for every member once, within 15 minutes. JSON text is
|
|
accepted too.
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: object
|
|
required:
|
|
- owner
|
|
properties:
|
|
owner:
|
|
type: string
|
|
description: Mailbox to share
|
|
rights:
|
|
type: string
|
|
description: >-
|
|
read = lookup, read, write-seen; write = also write,
|
|
write-deleted, insert, post, expunge, create; full = also delete
|
|
enum:
|
|
- read
|
|
- write
|
|
- full
|
|
default: read
|
|
subscribe:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
default: 0
|
|
sogo_grants:
|
|
description: >-
|
|
Replaces the SOGo folders shared with the members; the caller needs
|
|
access to every owner. Pending until the owner has opened SOGo once.
|
|
`subscribe` subscribes every member once. JSON text is accepted too.
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: object
|
|
required:
|
|
- owner
|
|
properties:
|
|
owner:
|
|
type: string
|
|
description: Mailbox whose folder is shared
|
|
type:
|
|
type: string
|
|
enum:
|
|
- Calendar
|
|
- Contacts
|
|
default: Calendar
|
|
folder:
|
|
type: string
|
|
description: SOGo folder id (`A-Za-z0-9._-`, max. 100 characters)
|
|
default: personal
|
|
access:
|
|
type: string
|
|
enum:
|
|
- read
|
|
- write
|
|
default: read
|
|
subscribe:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
default: 0
|
|
template_id:
|
|
type:
|
|
- integer
|
|
- string
|
|
- "null"
|
|
description: >-
|
|
Admins only: id of a mailbox template applied to the members;
|
|
null, empty or 0 = none
|
|
priority:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Admins only: -1000000 to 1000000; of several groups with a
|
|
template the one with the highest priority wins
|
|
default: 0
|
|
idp_ref:
|
|
type: string
|
|
description: >-
|
|
Admins only: Identity Provider group id to sync the members from
|
|
(max. 255 characters); empty = none
|
|
MailboxGroup:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
domain:
|
|
type: string
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
address:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Distribution address, null = none
|
|
sender_allowed:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
sogo_visible:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
internal:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
template_id:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
template:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Name of the template
|
|
priority:
|
|
type: integer
|
|
idp_ref:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Identity Provider group id, set = members are synced
|
|
members:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
source:
|
|
type: string
|
|
description: manual = added in mailcow, idp = added by the identity sync
|
|
enum:
|
|
- manual
|
|
- idp
|
|
send_as:
|
|
type: array
|
|
description: Addresses and `@domain` entries the members may send as
|
|
items:
|
|
type: string
|
|
imap_grants:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
owner:
|
|
type: string
|
|
rights:
|
|
type: string
|
|
enum:
|
|
- read
|
|
- write
|
|
- full
|
|
subscribe:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
state:
|
|
type: string
|
|
description: failed = setting the ACL failed, retried later
|
|
enum:
|
|
- pending
|
|
- applied
|
|
- failed
|
|
last_error:
|
|
type:
|
|
- string
|
|
- "null"
|
|
sogo_grants:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
owner:
|
|
type: string
|
|
type:
|
|
type: string
|
|
enum:
|
|
- Calendar
|
|
- Contacts
|
|
folder:
|
|
type: string
|
|
access:
|
|
type: string
|
|
enum:
|
|
- read
|
|
- write
|
|
subscribe:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
state:
|
|
type: string
|
|
description: pending (`last_error` folder_missing) until the SOGo folder of the owner exists
|
|
enum:
|
|
- pending
|
|
- applied
|
|
- failed
|
|
last_error:
|
|
type:
|
|
- string
|
|
- "null"
|
|
active:
|
|
type: integer
|
|
enum:
|
|
- 0
|
|
- 1
|
|
created:
|
|
type:
|
|
- string
|
|
- "null"
|
|
modified:
|
|
type:
|
|
- string
|
|
- "null"
|
|
can_edit:
|
|
type: boolean
|
|
description: The caller may change the group (false for read-only API keys)
|
|
MailboxGroupMemberships:
|
|
type: object
|
|
properties:
|
|
groups:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
domain:
|
|
type: string
|
|
name:
|
|
type: string
|
|
address:
|
|
type:
|
|
- string
|
|
- "null"
|
|
sender_allowed:
|
|
type: integer
|
|
active:
|
|
type: integer
|
|
priority:
|
|
type: integer
|
|
template:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source:
|
|
type: string
|
|
enum:
|
|
- manual
|
|
- idp
|
|
template:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Effective group template of the mailbox
|
|
send_as:
|
|
type: array
|
|
description: Addresses the mailbox may send as through its active groups
|
|
items:
|
|
type: string
|
|
SyncJobAttributes:
|
|
type: object
|
|
description: >-
|
|
Attributes of a sync job. Flags are cast to integers: `1`, `"1"` and
|
|
`true` are on; `0`, `"0"`, `false` and the string `"true"` are off.
|
|
Flags not sent on add are off. `host1`, `port1`, `enc1` and `authmech1`
|
|
are ignored, the connection comes from `source_id`.
|
|
properties:
|
|
source_id:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Id of an active sync source the caller may see
|
|
(`GET /api/v1/get/syncjob_source/all`)
|
|
user1:
|
|
type: string
|
|
description: Remote username at the source, max. 255 characters
|
|
password1:
|
|
type: string
|
|
format: password
|
|
description: >-
|
|
Remote password; required unless the source uses XOAUTH2 (ignored
|
|
then); empty on edit = keep
|
|
mins_interval:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Minutes between runs, 1-43800
|
|
subfolder2:
|
|
type: string
|
|
description: Folder in the local mailbox to sync into, empty = none
|
|
default: ""
|
|
exclude:
|
|
type: string
|
|
description: Regular expression of remote folders to skip
|
|
default: ""
|
|
maxage:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Only sync messages up to this age in days (1-32000), 0 = all
|
|
default: 0
|
|
maxbytespersecond:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Bandwidth limit in bytes/s (1-125000000), 0 = unlimited; the global
|
|
limit of `edit/imapsync_settings` caps it
|
|
default: 0
|
|
timeout1:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Timeout of the remote connection in seconds (1-32000)
|
|
default: 600
|
|
timeout2:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Timeout of the local connection in seconds (1-32000)
|
|
default: 600
|
|
custom_params:
|
|
type: array
|
|
description: >-
|
|
Extra imapsync options allowed by `GET /api/v1/get/syncjob_options`;
|
|
replaces the stored list, empty or null = none. Max. 100 options,
|
|
values max. 1000 characters, each value is one argument.
|
|
items:
|
|
$ref: "#/components/schemas/SyncJobCustomParam"
|
|
delete2duplicates:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Delete duplicates in the local mailbox (--delete2duplicates)
|
|
delete1:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Delete messages at the source after they were synced (--delete1)
|
|
delete2:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Delete local messages that are not at the source (--delete2)
|
|
automap:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Map special folders like "Sent Items" to their local counterparts (--automap)
|
|
skipcrossduplicates:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Skip duplicates across folders, first come first served (--skipcrossduplicates)
|
|
subscribeall:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Subscribe all folders (--subscribeall)
|
|
dry:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Dry run, change nothing (--dry)
|
|
active:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: The job runs; a new job without `active` is inactive
|
|
default: 0
|
|
SyncJobCustomParam:
|
|
type: object
|
|
required:
|
|
- o
|
|
properties:
|
|
o:
|
|
type: string
|
|
description: Option name, case-insensitive, leading dashes are removed
|
|
example: folder
|
|
v:
|
|
type: string
|
|
description: Value, empty for flags
|
|
default: ""
|
|
example: INBOX
|
|
SyncJob:
|
|
type: object
|
|
description: A sync job; the remote password is never returned.
|
|
properties:
|
|
id:
|
|
type: integer
|
|
user2:
|
|
type: string
|
|
description: Local mailbox
|
|
user1:
|
|
type: string
|
|
description: Remote username
|
|
source_id:
|
|
type: integer
|
|
subfolder2:
|
|
type: string
|
|
exclude:
|
|
type: string
|
|
maxage:
|
|
type: integer
|
|
mins_interval:
|
|
type: integer
|
|
maxbytespersecond:
|
|
type: string
|
|
description: Bytes/s as text, "0" = unlimited
|
|
timeout1:
|
|
type: integer
|
|
timeout2:
|
|
type: integer
|
|
custom_params:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: 'JSON text of the option list, e.g. `[{"o":"folder","v":"INBOX"}]`'
|
|
custom_params_legacy:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Free-text options of jobs from before the allowlist, not used by the runner
|
|
delete2duplicates:
|
|
type: integer
|
|
delete1:
|
|
type: integer
|
|
delete2:
|
|
type: integer
|
|
automap:
|
|
type: integer
|
|
skipcrossduplicates:
|
|
type: integer
|
|
subscribeall:
|
|
type: integer
|
|
dry:
|
|
type: integer
|
|
active:
|
|
type: integer
|
|
regextrans2:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Legacy column, read-only
|
|
authmd51:
|
|
type: integer
|
|
description: Legacy column, read-only
|
|
domain2:
|
|
type: string
|
|
description: Legacy column, read-only
|
|
is_running:
|
|
type: integer
|
|
last_run:
|
|
type:
|
|
- string
|
|
- "null"
|
|
success:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
description: Result of the last run (1 = imapsync exited with 0), null = not run yet
|
|
exit_status:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Exit status name of imapsync, e.g. EX_OK
|
|
prio:
|
|
type: integer
|
|
description: Queue priority, higher runs first
|
|
created:
|
|
type:
|
|
- string
|
|
- "null"
|
|
modified:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_name:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_description:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_host:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_port:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
source_enc:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_auth_type:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_created_by:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_scope:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_oauth_flow:
|
|
type:
|
|
- string
|
|
- "null"
|
|
source_active:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
source_oauth_token_expires:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
description: Expiry (Unix time) of the token of a client_credentials source
|
|
source_oauth_last_refresh_error:
|
|
type:
|
|
- string
|
|
- "null"
|
|
user_token_expires:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
description: Expiry (Unix time) of the sign-in token of an authorization_code source
|
|
user_token_error:
|
|
type:
|
|
- string
|
|
- "null"
|
|
user_token_exists:
|
|
type: integer
|
|
description: 1 = a sign-in token exists for (source, local mailbox, user1)
|
|
log:
|
|
type: string
|
|
description: Output of the last run; empty with `no_log`
|
|
SyncJobSourceAttributes:
|
|
type: object
|
|
description: >-
|
|
Attributes of a sync source; on edit, attributes that are not sent keep
|
|
their value.
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: 1-100 characters, unique per creator
|
|
description:
|
|
type: string
|
|
description: Max. 255 characters
|
|
default: ""
|
|
host:
|
|
type: string
|
|
description: IMAP server, host name or IP address (`host1` is accepted too)
|
|
port:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: 1-65535 (`port1` is accepted too)
|
|
enc:
|
|
type: string
|
|
description: TLS = STARTTLS (`enc1` is accepted too)
|
|
enum:
|
|
- TLS
|
|
- SSL
|
|
- PLAIN
|
|
default: TLS
|
|
verify_cert:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: Verify the server certificate; `0`, `"0"`, `false` or empty = no
|
|
default: 1
|
|
auth_type:
|
|
type: string
|
|
description: >-
|
|
PLAIN, LOGIN and CRAM-MD5 use the password of each job, XOAUTH2 an
|
|
OAuth2 token. Users cannot create or edit XOAUTH2 sources, but may
|
|
use the ones they see.
|
|
enum:
|
|
- PLAIN
|
|
- LOGIN
|
|
- CRAM-MD5
|
|
- XOAUTH2
|
|
default: PLAIN
|
|
active:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: 1 = usable for jobs (cast to integer)
|
|
default: 1
|
|
scope:
|
|
type: string
|
|
description: >-
|
|
Who may use the source: `all` (admins only), `domain` (the
|
|
`domains`), `user` (the `users`; none = only the creator). Sources
|
|
of users and client_credentials sources are always `user` without
|
|
targets. On edit the targets only change when `scope` is sent.
|
|
enum:
|
|
- all
|
|
- domain
|
|
- user
|
|
default: user
|
|
domains:
|
|
type: array
|
|
description: Domains for scope `domain` (at least one), the caller must manage them
|
|
items:
|
|
type: string
|
|
users:
|
|
type: array
|
|
description: Mailboxes for scope `user`, the caller must have access to them
|
|
items:
|
|
type: string
|
|
oauth_flow:
|
|
type: string
|
|
description: >-
|
|
XOAUTH2 grant: client_credentials = one token of the source for all
|
|
mailboxes of the tenant; authorization_code = every mailbox owner
|
|
signs in once in the mailcow UI (redirect URI
|
|
`https://<MAILCOW_HOSTNAME>/syncjob-oauth`)
|
|
enum:
|
|
- client_credentials
|
|
- authorization_code
|
|
default: client_credentials
|
|
oauth_token_endpoint:
|
|
type: string
|
|
description: XOAUTH2, required; https:// URL
|
|
oauth_authorize_endpoint:
|
|
type: string
|
|
description: XOAUTH2 authorization_code, required; https:// URL
|
|
oauth_userinfo_endpoint:
|
|
type: string
|
|
description: >-
|
|
XOAUTH2 authorization_code, optional: identity endpoint used when
|
|
the token response has no usable id_token; https:// URL
|
|
oauth_client_id:
|
|
type: string
|
|
description: XOAUTH2, required, max. 500 characters
|
|
oauth_client_secret:
|
|
type: string
|
|
format: password
|
|
description: >-
|
|
XOAUTH2, required, max. 500 characters; empty on edit = keep. Never
|
|
returned.
|
|
oauth_scope:
|
|
type: string
|
|
description: XOAUTH2, required, max. 500 characters
|
|
oauth_extra_params:
|
|
description: >-
|
|
XOAUTH2, optional: extra OAuth2 parameters as JSON object or JSON
|
|
text (max. 4000 characters). `prompt`, `access_type`, `login_hint`,
|
|
`domain_hint` and `hd` go to the sign-in URL, others to the token
|
|
request; standard fields cannot be overridden.
|
|
type:
|
|
- object
|
|
- string
|
|
- "null"
|
|
additionalProperties:
|
|
type:
|
|
- string
|
|
- number
|
|
- boolean
|
|
- "null"
|
|
SyncJobSource:
|
|
type: object
|
|
description: A sync source; secrets are never returned.
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
created_by:
|
|
type: string
|
|
description: Creator; `API` for API keys, empty = handed over to the admins (creator deleted)
|
|
scope:
|
|
type: string
|
|
enum:
|
|
- all
|
|
- domain
|
|
- user
|
|
domains:
|
|
type: array
|
|
items:
|
|
type: string
|
|
users:
|
|
type: array
|
|
items:
|
|
type: string
|
|
host:
|
|
type: string
|
|
port:
|
|
type: integer
|
|
enc:
|
|
type:
|
|
- string
|
|
- "null"
|
|
host1:
|
|
type: string
|
|
description: Same as `host`
|
|
port1:
|
|
type: integer
|
|
description: Same as `port`
|
|
enc1:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Same as `enc`
|
|
verify_cert:
|
|
type: integer
|
|
auth_type:
|
|
type:
|
|
- string
|
|
- "null"
|
|
active:
|
|
type: integer
|
|
oauth_flow:
|
|
type: string
|
|
oauth_token_endpoint:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_authorize_endpoint:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_userinfo_endpoint:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_client_id:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_scope:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_extra_params:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: JSON text, null for callers who may not edit the source
|
|
oauth_token_expires:
|
|
type:
|
|
- integer
|
|
- "null"
|
|
description: Expiry (Unix time) of the token of a client_credentials source
|
|
oauth_last_refresh_error:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_last_refresh_attempt:
|
|
type:
|
|
- string
|
|
- "null"
|
|
oauth_redirect_uri:
|
|
type: string
|
|
description: Only for authorization_code sources, register it at the provider
|
|
has_client_secret:
|
|
type: boolean
|
|
has_access_token:
|
|
type: boolean
|
|
can_edit:
|
|
type: boolean
|
|
description: The caller may change the source (false for read-only API keys)
|
|
created:
|
|
type:
|
|
- string
|
|
- "null"
|
|
modified:
|
|
type:
|
|
- string
|
|
- "null"
|
|
SyncJobSettings:
|
|
type: object
|
|
properties:
|
|
max_parallel:
|
|
type: integer
|
|
description: Sync jobs running at the same time
|
|
max_bytes_per_second:
|
|
type: integer
|
|
description: Bandwidth limit per sync job process in bytes/s, 0 = unlimited
|
|
max_kb_per_second:
|
|
type: integer
|
|
description: The same in KB/s
|
|
IdentityProviderAttributes:
|
|
type: object
|
|
required:
|
|
- authsource
|
|
description: >-
|
|
Configuration of the Identity Provider. Flags marked (boolean) are on
|
|
for any non-empty value except `0`/`"0"`/`false`; flags marked (0/1) are
|
|
cast to integers (the string `"true"` is 0).
|
|
properties:
|
|
authsource:
|
|
type: string
|
|
description: Provider type (case-insensitive)
|
|
enum:
|
|
- keycloak
|
|
- generic-oidc
|
|
- ldap
|
|
client_id:
|
|
type: string
|
|
description: Keycloak, generic-oidc
|
|
client_secret:
|
|
type: string
|
|
format: password
|
|
description: Keycloak, generic-oidc
|
|
redirect_url:
|
|
type: string
|
|
description: Keycloak, generic-oidc; URL of mailcow the provider redirects to after the login
|
|
redirect_url_extra:
|
|
type:
|
|
- array
|
|
- string
|
|
items:
|
|
type: string
|
|
description: Keycloak, generic-oidc; more allowed redirect URLs, only changed when sent
|
|
server_url:
|
|
type: string
|
|
description: Keycloak base URL
|
|
realm:
|
|
type: string
|
|
description: Keycloak realm
|
|
version:
|
|
type: string
|
|
description: Keycloak version
|
|
mailpassword_flow:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: (0/1) Keycloak; check mail client passwords through the Keycloak admin API
|
|
default: 0
|
|
group_paths:
|
|
type: string
|
|
description: >-
|
|
Keycloak group sync: comma-separated group paths, e.g. `/Sales` or
|
|
`/mailcow/*` (all groups below /mailcow); needs the `query-groups`
|
|
permission
|
|
default: ""
|
|
authorize_url:
|
|
type: string
|
|
description: generic-oidc authorization endpoint
|
|
token_url:
|
|
type: string
|
|
description: generic-oidc token endpoint
|
|
userinfo_url:
|
|
type: string
|
|
description: generic-oidc userinfo endpoint
|
|
client_scopes:
|
|
type: string
|
|
description: generic-oidc scopes
|
|
default: openid profile email mailcow_template
|
|
host:
|
|
type: string
|
|
description: LDAP server, several separated by commas (spaces are removed)
|
|
default: ""
|
|
port:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: LDAP port
|
|
default: 389
|
|
use_ssl:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: (boolean) LDAP over SSL
|
|
default: false
|
|
use_tls:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: (boolean) LDAP StartTLS, ignored with `use_ssl`
|
|
default: false
|
|
basedn:
|
|
type: string
|
|
description: LDAP base DN of the user search
|
|
binddn:
|
|
type: string
|
|
description: LDAP bind DN
|
|
bindpass:
|
|
type: string
|
|
format: password
|
|
description: LDAP bind password
|
|
username_field:
|
|
type: string
|
|
description: LDAP attribute with the mail address of the user
|
|
default: mail
|
|
filter:
|
|
type: string
|
|
description: LDAP filter of the users that may log in
|
|
default: ""
|
|
attribute_field:
|
|
type: string
|
|
description: LDAP attribute whose value is matched against `mappers`
|
|
default: ""
|
|
id_attribute:
|
|
type: string
|
|
description: >-
|
|
LDAP attribute with a stable user id; empty = objectGUID, entryUUID,
|
|
nsUniqueId or ipaUniqueID, else the DN
|
|
default: ""
|
|
disabled_filter:
|
|
type: string
|
|
description: >-
|
|
LDAP filter of disabled users (Active Directory accounts with
|
|
ACCOUNTDISABLE are always disabled)
|
|
default: ""
|
|
group_basedn:
|
|
type: string
|
|
description: LDAP base DN of the group search, empty = `basedn`
|
|
default: ""
|
|
group_filter:
|
|
type: string
|
|
description: LDAP filter of the synced groups, required for the group sync
|
|
default: ""
|
|
group_name_attribute:
|
|
type: string
|
|
default: cn
|
|
group_member_mode:
|
|
type: string
|
|
description: >-
|
|
LDAP source of the memberships: memberOf of the users, member
|
|
attribute of the groups, or Active Directory incl. nested groups
|
|
enum:
|
|
- memberof
|
|
- member
|
|
- ad_chain
|
|
default: memberof
|
|
group_member_attribute:
|
|
type: string
|
|
description: LDAP member attribute for `group_member_mode` member
|
|
default: member
|
|
ignore_ssl_error:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: (boolean) Do not verify TLS certificates
|
|
default: false
|
|
login_provisioning:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: (boolean) Create mailboxes at their first login
|
|
default: false
|
|
periodic_sync:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: (0/1) Keycloak, LDAP; update mailboxes from the provider every `sync_interval`
|
|
default: 0
|
|
import_users:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: (0/1) Keycloak, LDAP; create mailboxes for new users of the provider
|
|
default: 0
|
|
sync_interval:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Keycloak, LDAP; minutes between sync runs (at least 1)
|
|
default: 15
|
|
offboarding:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: >-
|
|
(0/1) Keycloak, LDAP; disable the login (mail still arrives) of users
|
|
disabled at the provider or missing in two complete runs; the sync
|
|
enables only mailboxes it disabled
|
|
default: 0
|
|
offboarding_limit:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Keycloak, LDAP; runs that would disable more mailboxes or remove
|
|
more group memberships than this share in percent (0-100, at least
|
|
5 mailboxes) are blocked
|
|
default: 10
|
|
group_sync:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: >-
|
|
(0/1) Keycloak, LDAP; sync the members of provider groups to mailbox
|
|
groups (members added in mailcow stay)
|
|
default: 0
|
|
group_autocreate:
|
|
type:
|
|
- integer
|
|
- string
|
|
- boolean
|
|
description: >-
|
|
(0/1) Keycloak, LDAP; create a mailbox group for every provider
|
|
group without one
|
|
default: 0
|
|
group_default_domain:
|
|
type: string
|
|
description: Keycloak, LDAP; domain of new groups whose mail is not in a mailcow domain
|
|
default: ""
|
|
default_template:
|
|
type: string
|
|
description: >-
|
|
Mailbox template for new mailboxes without a matching mapping (not
|
|
used for updates); only changed when sent
|
|
mappers:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: >-
|
|
Attribute values, each mapped to the template at the same position
|
|
in `templates`; only changed when both lists are sent, pairs with an
|
|
empty value are dropped
|
|
templates:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Mailbox templates for `mappers`
|
|
IdentityProviderSettings:
|
|
type: object
|
|
description: >-
|
|
Stored settings (see `IdentityProviderAttributes`), mostly as strings.
|
|
Secrets are `*` for read-only API keys.
|
|
properties:
|
|
authsource:
|
|
type: string
|
|
client_secret:
|
|
type: string
|
|
bindpass:
|
|
type: string
|
|
access_token:
|
|
type: string
|
|
description: Cached admin API token of Keycloak
|
|
redirect_url_extra:
|
|
type: array
|
|
items:
|
|
type: string
|
|
mappers:
|
|
type: array
|
|
items:
|
|
type: string
|
|
templates:
|
|
type: array
|
|
items:
|
|
type: string
|
|
use_ssl:
|
|
type: boolean
|
|
use_tls:
|
|
type: boolean
|
|
ignore_ssl_error:
|
|
type: boolean
|
|
login_provisioning:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
additionalProperties:
|
|
type: string
|
|
IdentitySyncStatus:
|
|
type: object
|
|
properties:
|
|
provider:
|
|
type: string
|
|
description: Configured provider, empty = none
|
|
can_sync:
|
|
type: boolean
|
|
description: The provider can be synced (Keycloak, LDAP)
|
|
sync_enabled:
|
|
type: boolean
|
|
description: Scheduled runs are on (periodic sync, import, offboarding or group sync)
|
|
counts:
|
|
type: object
|
|
description: Mailboxes of the provider (no resources)
|
|
properties:
|
|
accounts:
|
|
type: integer
|
|
linked:
|
|
type: integer
|
|
description: Linked to a user of the provider
|
|
idp_disabled:
|
|
type: integer
|
|
description: Login disabled by the sync
|
|
missing:
|
|
type: integer
|
|
description: Not found at the provider by the last runs
|
|
runs:
|
|
type: array
|
|
description: The last 10 runs, newest first
|
|
items:
|
|
$ref: "#/components/schemas/IdentitySyncRun"
|
|
IdentitySyncRun:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
provider:
|
|
type: string
|
|
mode:
|
|
type: string
|
|
enum:
|
|
- run
|
|
- preview
|
|
- force
|
|
status:
|
|
type: string
|
|
enum:
|
|
- pending
|
|
- running
|
|
- ok
|
|
- blocked
|
|
- error
|
|
requested_by:
|
|
type: string
|
|
description: Who requested the run, empty for scheduled runs
|
|
created:
|
|
type: string
|
|
started:
|
|
type:
|
|
- string
|
|
- "null"
|
|
finished:
|
|
type:
|
|
- string
|
|
- "null"
|
|
summary:
|
|
type:
|
|
- object
|
|
- "null"
|
|
description: >-
|
|
Result, null while pending: `counts` per kind of change, `details`
|
|
(up to 50 entries per list), `blocked`, `errors` (up to 50), `mode`;
|
|
failed runs only `error` and `mode`
|
|
properties:
|
|
counts:
|
|
type: object
|
|
additionalProperties:
|
|
type: integer
|
|
details:
|
|
type: object
|
|
additionalProperties:
|
|
type: array
|
|
items:
|
|
type: string
|
|
blocked:
|
|
type: boolean
|
|
errors:
|
|
type: array
|
|
items:
|
|
type: string
|
|
error:
|
|
type: string
|
|
mode:
|
|
type: string
|
|
IdentityLink:
|
|
type: object
|
|
properties:
|
|
provider:
|
|
type: string
|
|
external_id:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: User id at the provider
|
|
idp_disabled:
|
|
type: integer
|
|
description: 1 = login disabled by the identity sync
|
|
missing_since:
|
|
type:
|
|
- string
|
|
- "null"
|
|
description: Since when the sync does not find the user at the provider
|
|
responses:
|
|
Unauthorized:
|
|
description: >-
|
|
The API key is unknown or inactive (`authentication failed`), or the
|
|
request comes from an address the key does not allow
|
|
(`api access denied for ip <address>`)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
example:
|
|
type: error
|
|
msg: authentication failed
|
|
Forbidden:
|
|
description: The API key is read-only
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
example:
|
|
type: error
|
|
msg: API read/write access denied
|
|
WriteResult:
|
|
description: >-
|
|
The messages of the call; `{"type": "success", "msg": "Task completed"}`
|
|
or `{"type": "error", "msg": "Cannot ... item"}` if it produced none.
|
|
Check `type`: the status is 200 for failures too.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- $ref: "#/components/schemas/Messages"
|
|
- $ref: "#/components/schemas/TaskResult"
|
|
examples:
|
|
messages:
|
|
summary: Messages of the call
|
|
value:
|
|
- type: success
|
|
log:
|
|
- mailbox
|
|
- add
|
|
- alias
|
|
- address: alias@example.org
|
|
goto: user@example.org
|
|
msg:
|
|
- alias_added
|
|
- alias@example.org
|
|
failed:
|
|
summary: Failed without a message
|
|
value:
|
|
type: error
|
|
msg: Cannot add item
|
|
AcmeLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/AcmeLogEntry"
|
|
example:
|
|
- time: "1794308452"
|
|
message: mail.example.org - Certificates were successfully validated, no changes or renewals required, sleeping for another day.
|
|
ApiLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/ApiLogEntry"
|
|
example:
|
|
- time: 1794334338
|
|
uri: /api/v1/edit/domain-admin
|
|
method: POST
|
|
remote: 192.0.2.10
|
|
data: "attr='{\"active\":\"1\",\"password\":\"*\",\"password2\":\"*\"}', items='[\"domainadmin1\"]'"
|
|
- time: 1794334330
|
|
uri: /api/v1/get/status/version
|
|
method: GET
|
|
remote: 192.0.2.10
|
|
data: ""
|
|
AutodiscoverLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/AutodiscoverLogEntry"
|
|
example:
|
|
- time: 1794311051
|
|
ua: Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.17928; Pro)
|
|
user: john.doe@example.org
|
|
ip: 198.51.100.7
|
|
service: activesync
|
|
CronLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/CronLogEntry"
|
|
example:
|
|
- time: 1794096901
|
|
priority: warning
|
|
task: Group Shares
|
|
message: "group_imap_grant_failed: info@example.org"
|
|
DovecotLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyslogLogEntry"
|
|
example:
|
|
- time: "1794334332"
|
|
program: dovecot
|
|
priority: info
|
|
message: "imap-login: Login: user=<john.doe@example.org>, method=PLAIN, rip=198.51.100.7, lip=172.22.1.250, mpid=310, TLS, session=<c0kD4l8L2N7GZGMH>"
|
|
NetfilterLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/NetfilterLogEntry"
|
|
example:
|
|
- time: 1794334242
|
|
priority: crit
|
|
message: Banning 203.0.113.5/32 for 30 minutes
|
|
- time: 1794334242
|
|
priority: warn
|
|
message: "203.0.113.5 matched rule id 3 (warning: unknown[203.0.113.5]: SASL LOGIN authentication failed: ...)"
|
|
PostfixLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyslogLogEntry"
|
|
example:
|
|
- time: "1794334301"
|
|
program: postfix/smtpd
|
|
priority: info
|
|
message: "connect from mail.example.com[198.51.100.20]"
|
|
RatelimitLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/RatelimitLogEntry"
|
|
example:
|
|
- time: 1794334001
|
|
rcpt: jane@example.com
|
|
from: john.doe@example.org
|
|
user: john.doe@example.org
|
|
rl_info: john.doe@example.org(RLsdz3tuabozgd4oacbdh8kc78)
|
|
rl_name: john.doe@example.org
|
|
rl_hash: RLsdz3tuabozgd4oacbdh8kc78
|
|
qid: E3CF91500458
|
|
ip: 172.22.1.248
|
|
message_id: 6a-5d892500-7-240abd80@example.org
|
|
header_subject: Newsletter
|
|
header_from: "\"John Doe\" <john.doe@example.org>"
|
|
RspamdHistory:
|
|
description: The scanned messages, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/RspamdHistoryEntry"
|
|
example:
|
|
- unix_time: 1794333685
|
|
time_real: 0.510136
|
|
score: -1.229459
|
|
required_score: 15
|
|
action: no action
|
|
thresholds:
|
|
reject: 15
|
|
add header: 8
|
|
greylist: 7
|
|
ip: 198.51.100.20
|
|
user: unknown
|
|
sender_smtp: jane@example.com
|
|
sender_mime: jane@example.com
|
|
rcpt_smtp:
|
|
- john.doe@example.org
|
|
rcpt_mime:
|
|
- john.doe@example.org
|
|
subject: Meeting tomorrow
|
|
message-id: 20261110190100.428319@mail.example.com
|
|
size: 1015
|
|
is_skipped: false
|
|
symbols:
|
|
DMARC_POLICY_ALLOW:
|
|
name: DMARC_POLICY_ALLOW
|
|
score: -0.5
|
|
metric_score: -0.5
|
|
description: DMARC permit policy
|
|
options:
|
|
- example.com
|
|
- none
|
|
SaslLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SaslLogEntry"
|
|
example:
|
|
- service: imap
|
|
app_password: 0
|
|
username: john.doe@example.org
|
|
real_rip: 198.51.100.7
|
|
datetime: "2026-11-10 19:07:01"
|
|
SogoLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyslogLogEntry"
|
|
example:
|
|
- time: "1794334303"
|
|
program: sogod
|
|
priority: notice
|
|
message: "[52]: 198.51.100.7 \"GET /SOGo/so/john.doe@example.org/Mail/view HTTP/1.1\" 200 2578/0 0.002 - - 0 - 12"
|
|
UiLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/UiLogEntry"
|
|
example:
|
|
- id: 1819
|
|
task: 97D254
|
|
type: success
|
|
msg: "[\"domain_admin_modified\",\"domainadmin1\"]"
|
|
call: "[\"domain_admin\",\"edit\",{\"username\":[\"domainadmin1\"],\"active\":\"1\"}]"
|
|
user: API
|
|
role: admin
|
|
remote: 192.0.2.10
|
|
time: 1794319670
|
|
WatchdogLogs:
|
|
description: The log entries, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/WatchdogLogEntry"
|
|
example:
|
|
- time: "1794334334"
|
|
service: Dovecot
|
|
lvl: "100"
|
|
hpnow: "12"
|
|
hptotal: "12"
|
|
hpdiff: "0"
|
|
parameters:
|
|
MailboxTagsQuery:
|
|
name: tags
|
|
in: query
|
|
required: false
|
|
description: "Comma-separated tags: only mailboxes with a tag containing one of them"
|
|
schema:
|
|
type: string
|
|
example: sales,support
|
|
examples:
|
|
MailboxDetails:
|
|
summary: A mailbox
|
|
value:
|
|
username: john.doe@example.org
|
|
active: 1
|
|
active_int: 1
|
|
domain: example.org
|
|
name: John Doe
|
|
local_part: john.doe
|
|
quota: 3221225472
|
|
messages: 1207
|
|
attributes:
|
|
force_pw_update: "0"
|
|
force_tfa: "0"
|
|
tls_enforce_in: "0"
|
|
tls_enforce_out: "0"
|
|
sogo_access: "1"
|
|
imap_access: "1"
|
|
pop3_access: "0"
|
|
smtp_access: "1"
|
|
sieve_access: "1"
|
|
eas_access: "1"
|
|
dav_access: "1"
|
|
relayhost: "0"
|
|
shared: "0"
|
|
passwd_update: "2026-11-03 09:37:37"
|
|
mailbox_format: "maildir:"
|
|
quarantine_notification: hourly
|
|
quarantine_category: reject
|
|
attribute_hash: ""
|
|
recovery_email: ""
|
|
custom_attributes:
|
|
department: Sales
|
|
quota_used: 418219315
|
|
percent_in_use: 13
|
|
created: "2026-11-03 09:37:37"
|
|
modified: "2026-11-06 20:20:46"
|
|
authsource: mailcow
|
|
percent_class: success
|
|
last_imap_login: 1794052021
|
|
last_smtp_login: 1793788402
|
|
last_pop3_login: 0
|
|
last_sso_login: 1794005152
|
|
last_sogo_login: 1794005160
|
|
max_new_quota: 10737418240
|
|
spam_aliases: 1
|
|
pushover_active: 0
|
|
rl:
|
|
value: "100"
|
|
frame: h
|
|
rl_scope: mailbox
|
|
is_relayed: 0
|
|
sender_acl:
|
|
- sales@example.org
|
|
tags:
|
|
- sales
|
|
MailboxList:
|
|
summary: Mailboxes
|
|
value:
|
|
- username: john.doe@example.org
|
|
active: 1
|
|
active_int: 1
|
|
domain: example.org
|
|
name: John Doe
|
|
local_part: john.doe
|
|
quota: 3221225472
|
|
messages: 1207
|
|
attributes:
|
|
force_pw_update: "0"
|
|
force_tfa: "0"
|
|
tls_enforce_in: "0"
|
|
tls_enforce_out: "0"
|
|
sogo_access: "1"
|
|
imap_access: "1"
|
|
pop3_access: "0"
|
|
smtp_access: "1"
|
|
sieve_access: "1"
|
|
eas_access: "1"
|
|
dav_access: "1"
|
|
relayhost: "0"
|
|
shared: "0"
|
|
passwd_update: "2026-11-03 09:37:37"
|
|
mailbox_format: "maildir:"
|
|
quarantine_notification: hourly
|
|
quarantine_category: reject
|
|
attribute_hash: ""
|
|
custom_attributes: []
|
|
quota_used: 418219315
|
|
percent_in_use: 13
|
|
created: "2026-11-03 09:37:37"
|
|
modified: "2026-11-06 20:20:46"
|
|
authsource: mailcow
|
|
percent_class: success
|
|
last_imap_login: 1794052021
|
|
last_smtp_login: 1793788402
|
|
last_pop3_login: 0
|
|
last_sso_login: 0
|
|
last_sogo_login: 1794005160
|
|
max_new_quota: 10737418240
|
|
spam_aliases: 0
|
|
pushover_active: 0
|
|
rl: false
|
|
rl_scope: domain
|
|
is_relayed: 0
|
|
sender_acl: []
|
|
MailboxSearchPage:
|
|
summary: One page of mailboxes
|
|
value:
|
|
draw: 1
|
|
recordsTotal: 1
|
|
recordsFiltered: 1
|
|
data:
|
|
- username: john.doe@example.org
|
|
active: 1
|
|
active_int: 1
|
|
domain: example.org
|
|
name: John Doe
|
|
local_part: john.doe
|
|
quota: 3221225472
|
|
messages: 1207
|
|
attributes:
|
|
force_pw_update: "0"
|
|
force_tfa: "0"
|
|
tls_enforce_in: "0"
|
|
tls_enforce_out: "0"
|
|
sogo_access: "1"
|
|
imap_access: "1"
|
|
pop3_access: "0"
|
|
smtp_access: "1"
|
|
sieve_access: "1"
|
|
eas_access: "1"
|
|
dav_access: "1"
|
|
relayhost: "0"
|
|
shared: "0"
|
|
passwd_update: "2026-11-03 09:37:37"
|
|
mailbox_format: "maildir:"
|
|
quarantine_notification: hourly
|
|
quarantine_category: reject
|
|
attribute_hash: ""
|
|
custom_attributes: []
|
|
quota_used: 418219315
|
|
percent_in_use: 13
|
|
created: "2026-11-03 09:37:37"
|
|
modified: "2026-11-06 20:20:46"
|
|
authsource: mailcow
|
|
percent_class: success
|
|
last_imap_login: 1794052021
|
|
last_smtp_login: 1793788402
|
|
last_pop3_login: 0
|
|
last_sso_login: 0
|
|
last_sogo_login: 1794005160
|
|
max_new_quota: 10737418240
|
|
spam_aliases: 0
|
|
pushover_active: 0
|
|
rl: false
|
|
rl_scope: domain
|
|
is_relayed: 0
|
|
sender_acl: []
|
|
tags:
|
|
- sales
|
|
|
|
security:
|
|
- ApiKeyAuth: []
|
|
|
|
paths:
|
|
/api/v1/add/alias:
|
|
post:
|
|
tags:
|
|
- Aliases
|
|
summary: Create aliases
|
|
operationId: addAlias
|
|
description: >-
|
|
Creates an alias for every address in `address`, all with the same
|
|
destinations; domain administrators for their domains. Flags not sent
|
|
are 0: send `active`, `sogo_visible` and `sender_allowed` as 1 to get
|
|
an alias like the UI creates it.
|
|
|
|
|
|
Messages: `alias_added`; errors `is_alias_or_mailbox`, `goto_invalid`,
|
|
`external_goto_denied`, `max_alias_exceeded`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
address:
|
|
type: string
|
|
description: >-
|
|
Alias addresses of mailcow domains or alias domains,
|
|
separated by spaces, commas, semicolons or line breaks;
|
|
`@example.org` is a catch-all
|
|
goto:
|
|
type: string
|
|
description: >-
|
|
Destination addresses, separated by spaces, commas,
|
|
semicolons or line breaks; required unless a `goto_*` flag
|
|
is 1
|
|
goto_null:
|
|
type: [boolean, integer, string]
|
|
description: 1 = discard the mail silently; wins over `goto_spam` and `goto_ham`
|
|
default: 0
|
|
goto_spam:
|
|
type: [boolean, integer, string]
|
|
description: 1 = learn the mail as spam; wins over `goto_ham`
|
|
default: 0
|
|
goto_ham:
|
|
type: [boolean, integer, string]
|
|
description: 1 = learn the mail as ham
|
|
default: 0
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
default: 0
|
|
sogo_visible:
|
|
type: [boolean, integer, string]
|
|
description: 1 = selectable sender in SOGo (aliases with a local mailbox as destination)
|
|
default: 0
|
|
internal:
|
|
type: [boolean, integer, string]
|
|
description: 1 = only reachable from its own domain and its alias domains
|
|
default: 0
|
|
sender_allowed:
|
|
type: [boolean, integer, string]
|
|
description: 1 = the destination mailboxes may send as this alias
|
|
default: 0
|
|
public_comment:
|
|
type: string
|
|
description: Comment shown to the users
|
|
maxLength: 160
|
|
private_comment:
|
|
type: string
|
|
description: Comment for administrators
|
|
maxLength: 160
|
|
required:
|
|
- address
|
|
example:
|
|
address: sales@example.org
|
|
goto: anna@example.org,ben@example.org
|
|
active: "1"
|
|
sogo_visible: "1"
|
|
sender_allowed: "1"
|
|
internal: "0"
|
|
public_comment: Sales team
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/time_limited_alias:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Create a time-limited alias
|
|
operationId: addTimeLimitedAlias
|
|
description: >-
|
|
Creates a random alias that delivers to the mailbox until it expires.
|
|
Needs the user ACL `spam_alias`. `domain` must be the domain of the
|
|
mailbox or one of its alias domains.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors `domain_invalid`,
|
|
`validity_missing`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Mailbox the alias delivers to (required for API keys)
|
|
domain:
|
|
type: string
|
|
description: Domain of the alias
|
|
description:
|
|
type: string
|
|
default: ""
|
|
description: Note for the alias
|
|
validity:
|
|
type: [integer, string]
|
|
minimum: 1
|
|
maximum: 87600
|
|
default: 8760
|
|
description: Hours until the alias expires
|
|
permanent:
|
|
type: [boolean, integer, string]
|
|
default: false
|
|
description: true keeps the alias after it expired
|
|
example:
|
|
username: john.doe@example.org
|
|
domain: example.org
|
|
description: Online shop registration
|
|
validity: 720
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/api-key:
|
|
post:
|
|
summary: Create API key
|
|
description: >-
|
|
Creates an API key with a random value; read the value with
|
|
`get/api-key/all`. Without `skip_ip_check`, `allow_from` is required.
|
|
|
|
|
|
Messages: `api_key_added`; errors `api_key_access_invalid`,
|
|
`api_key_network_invalid`, `ip_list_empty`.
|
|
operationId: addApiKey
|
|
tags:
|
|
- API Keys
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/ApiKeyAttributes"
|
|
- required:
|
|
- access
|
|
example:
|
|
description: provisioning
|
|
access: rw
|
|
allow_from: "192.0.2.10, 2001:db8::/64"
|
|
skip_ip_check: 0
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/app-passwd:
|
|
post:
|
|
tags:
|
|
- App Passwords
|
|
summary: Create an app password
|
|
operationId: addAppPassword
|
|
description: >-
|
|
Adds an app password to a mailbox, valid only for the listed protocols.
|
|
Needs the user ACL `app_passwds`.
|
|
|
|
|
|
Messages: `app_passwd_added`; errors `password_complexity`,
|
|
`password_mismatch`, `app_name_empty`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- app_name
|
|
- app_passwd
|
|
- app_passwd2
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Mailbox the app password belongs to (required for API keys)
|
|
app_name:
|
|
type: string
|
|
description: Name of the app password
|
|
app_passwd:
|
|
type: string
|
|
format: password
|
|
description: The password, checked against the password policy
|
|
app_passwd2:
|
|
type: string
|
|
format: password
|
|
description: The password again
|
|
protocols:
|
|
description: Protocols the password is valid for; not listed = not allowed
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- imap_access
|
|
- smtp_access
|
|
- pop3_access
|
|
- sieve_access
|
|
- dav_access
|
|
- eas_access
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: 1 active, 0 inactive
|
|
example:
|
|
username: john.doe@example.org
|
|
app_name: Thunderbird
|
|
app_passwd: eiQu4ahz8iePh
|
|
app_passwd2: eiQu4ahz8iePh
|
|
protocols:
|
|
- imap_access
|
|
- smtp_access
|
|
- sieve_access
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/bcc:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Create a BCC map
|
|
operationId: addBccMap
|
|
description: >-
|
|
Sends a hidden copy of the mail of a domain or address to `bcc_dest`.
|
|
Domain administrators need the BCC maps ACL. Undeliverable copies are
|
|
not reported to the local destination.
|
|
|
|
|
|
Messages: `bcc_saved`; errors `bcc_must_be_email`, `bcc_exists`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
local_dest:
|
|
type: string
|
|
description: A mailcow domain or the address of a mailbox or alias
|
|
bcc_dest:
|
|
type: string
|
|
description: One e-mail address that gets the copies (use an alias for several)
|
|
type:
|
|
type: string
|
|
enum:
|
|
- sender
|
|
- rcpt
|
|
description: >-
|
|
`sender`: copy the mail sent by `local_dest`; `rcpt`: copy
|
|
the mail sent to it
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
default: 0
|
|
required:
|
|
- local_dest
|
|
- bcc_dest
|
|
- type
|
|
example:
|
|
local_dest: example.org
|
|
bcc_dest: archive@example.com
|
|
type: rcpt
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/dkim:
|
|
post:
|
|
summary: Generate DKIM keys
|
|
description: >-
|
|
Generates an RSA DKIM key for each domain or alias domain; existing
|
|
keys are kept.
|
|
|
|
|
|
Messages: `dkim_added`; error `dkim_domain_or_sel_invalid`.
|
|
operationId: addDkimKey
|
|
tags:
|
|
- DKIM
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domains
|
|
- key_size
|
|
properties:
|
|
domains:
|
|
type: string
|
|
description: >-
|
|
Domain names, separated by spaces, commas, semicolons or
|
|
line breaks
|
|
dkim_selector:
|
|
type: string
|
|
default: dkim
|
|
description: Selector (letters, digits, `-`, `_`, `.`)
|
|
key_size:
|
|
type: [integer, string]
|
|
description: RSA key size in bits
|
|
example:
|
|
domains: example.org, example.net
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/dkim_duplicate:
|
|
post:
|
|
summary: Copy a DKIM key to other domains
|
|
description: >-
|
|
Copies the DKIM key and selector of `from_domain` to the `to_domain`
|
|
domains, replacing their keys. Target names are not checked.
|
|
|
|
|
|
Messages: `dkim_duplicated`; error `dkim_domain_or_sel_invalid`.
|
|
operationId: duplicateDkimKey
|
|
tags:
|
|
- DKIM
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- from_domain
|
|
- to_domain
|
|
properties:
|
|
from_domain:
|
|
type: string
|
|
description: Domain whose key is copied
|
|
to_domain:
|
|
description: Domain name or list of domain names that get the key
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
from_domain: example.org
|
|
to_domain:
|
|
- example.net
|
|
- example.com
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/domain:
|
|
post:
|
|
summary: Add a domain
|
|
description: >-
|
|
Adds a domain. Quotas are in MiB. Fields not sent come from the domain
|
|
template in `template` (default: `Default`). Also sets the rate limit
|
|
and creates a DKIM key. SOGo sees the new domain only after a restart
|
|
(`restart_sogo`).
|
|
|
|
|
|
Messages: `domain_added`, `dkim_added`, `rl_saved`; errors
|
|
`domain_invalid`, `domain_exists`, `maxquota_empty`.
|
|
operationId: addDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain name (stored lowercase, IDN as punycode)
|
|
description:
|
|
type: string
|
|
description: Description, default the domain name
|
|
template:
|
|
type: [integer, string]
|
|
description: ID of the domain template for fields not sent
|
|
aliases:
|
|
type: [integer, string]
|
|
description: Max. number of aliases
|
|
mailboxes:
|
|
type: [integer, string]
|
|
description: Max. number of mailboxes
|
|
defquota:
|
|
type: [integer, string]
|
|
description: Default quota of new mailboxes in MiB, must not be 0
|
|
maxquota:
|
|
type: [integer, string]
|
|
description: Max. quota per mailbox in MiB, must not be 0
|
|
quota:
|
|
type: [integer, string]
|
|
description: Quota of the whole domain in MiB
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Domain active
|
|
gal:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Global address list in SOGo
|
|
backupmx:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Relay this domain (backup MX)
|
|
relay_all_recipients:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: >-
|
|
Relay all recipients, not only those with a mailbox; 1 sets
|
|
`backupmx`
|
|
relay_unknown_only:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: >-
|
|
Relay only recipients without a local mailbox; 1 sets
|
|
`backupmx` and `relay_all_recipients`
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: >-
|
|
Tags of the domain, at most 25 (more are dropped with
|
|
`tag_limit_exceeded`)
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Rate limit, messages per `rl_frame`; empty or 0 = none
|
|
rl_frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
description: Rate limit time frame
|
|
dkim_selector:
|
|
type: string
|
|
description: Selector of the DKIM key that is created
|
|
key_size:
|
|
type: [integer, string]
|
|
description: RSA size of the new DKIM key in bits; empty or 0 = no key
|
|
restart_sogo:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Restart SOGo afterwards
|
|
example:
|
|
domain: example.org
|
|
description: Example Org
|
|
aliases: 400
|
|
mailboxes: 10
|
|
defquota: 3072
|
|
maxquota: 10240
|
|
quota: 10240
|
|
active: 1
|
|
gal: 1
|
|
backupmx: 0
|
|
relay_all_recipients: 0
|
|
relay_unknown_only: 0
|
|
tags:
|
|
- customer
|
|
rl_value: 100
|
|
rl_frame: h
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
restart_sogo: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/domain-admin:
|
|
post:
|
|
summary: Create domain administrator
|
|
description: >-
|
|
Creates a domain administrator for the given domains with the default
|
|
ACLs. The username is stored in lowercase and must not be in use by a
|
|
mailbox or administrator. Without `active: 1` the account is disabled.
|
|
Unknown domains are skipped; if none exists, nothing is created, but
|
|
`domain_admin_added` is reported anyway.
|
|
|
|
|
|
Messages: `domain_admin_added`; errors `domain_invalid`,
|
|
`object_exists`, `password_complexity`, `password_mismatch`.
|
|
operationId: addDomainAdmin
|
|
tags:
|
|
- Domain admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Username (letters, digits, `_`, `.`, `-`; stored in lowercase)
|
|
password:
|
|
type: string
|
|
description: Password, must match the password policy
|
|
password2:
|
|
type: string
|
|
description: The password again
|
|
domains:
|
|
description: Domain or list of domains the account administers
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
active:
|
|
type: [integer, string, boolean]
|
|
description: 1 = the account can log in, 0 = disabled
|
|
default: 0
|
|
required:
|
|
- username
|
|
- password
|
|
- password2
|
|
- domains
|
|
example:
|
|
username: domainadmin1
|
|
password: "Rand0m-Passw0rd!"
|
|
password2: "Rand0m-Passw0rd!"
|
|
domains:
|
|
- example.org
|
|
- example.com
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/sso/domain-admin:
|
|
post:
|
|
summary: Issue domain administrator login token
|
|
description: >-
|
|
Issues a one-time login token for an active domain administrator, valid
|
|
for 30 seconds. Opening `/domainadmin/mailbox?sso_token=<token>` on the
|
|
mailcow host logs in without password or two-factor authentication.
|
|
|
|
|
|
Messages: error `object_doesnt_exist`.
|
|
operationId: issueDomainAdminSsoToken
|
|
tags:
|
|
- Single Sign-On
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Username of the domain administrator
|
|
required:
|
|
- username
|
|
example:
|
|
username: domainadmin1
|
|
responses:
|
|
"200":
|
|
description: The token, or the error messages
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: object
|
|
properties:
|
|
token:
|
|
type: string
|
|
description: Login token (five groups of six hex digits)
|
|
required:
|
|
- token
|
|
- $ref: "#/components/schemas/Messages"
|
|
example:
|
|
token: 591F6D-5C3DD2-7455CD-DAF1C1-AA4FCC
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/da-acl:
|
|
post:
|
|
summary: Edit domain administrator ACLs
|
|
description: >-
|
|
Grants the ACLs in `da_acl` and revokes all others; an empty or missing
|
|
`da_acl` revokes all.
|
|
|
|
|
|
Messages: `acl_saved`; error `Cannot determine current ACL`.
|
|
operationId: editDomainAdminAcl
|
|
tags:
|
|
- Domain admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Username of the domain administrator, or a list of usernames
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
da_acl:
|
|
description: The ACLs to grant (a single name or a list)
|
|
oneOf:
|
|
- $ref: "#/components/schemas/DomainAdminAcl"
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/DomainAdminAcl"
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- domainadmin1
|
|
attr:
|
|
da_acl:
|
|
- syncjobs
|
|
- quarantine
|
|
- login_as
|
|
- sogo_access
|
|
- app_passwds
|
|
- bcc_maps
|
|
- filters
|
|
- ratelimit
|
|
- spam_policy
|
|
- protocol_access
|
|
- smtp_ip_access
|
|
- mailbox_relayhost
|
|
- domain_relayhost
|
|
- alias_external_goto
|
|
- mailbox_groups
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/domain-admin:
|
|
post:
|
|
summary: Edit domain administrators
|
|
description: >-
|
|
Changes domain administrators. Fields not sent keep their value, but
|
|
`force_tfa` and `force_pw_update` are reset to 0. `domains` replaces
|
|
the domain list, empty keeps it; an empty `password` keeps the
|
|
password. FIDO2 keys are not moved on rename. A password error ends
|
|
the call after the domains were saved.
|
|
|
|
|
|
Messages: `domain_admin_modified`; errors `domain_invalid`,
|
|
`username_invalid`, `password_mismatch`, `password_complexity`.
|
|
operationId: editDomainAdmin
|
|
tags:
|
|
- Domain admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Username of the domain administrator, or a list of usernames
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
active:
|
|
type: [integer, string, boolean]
|
|
description: 1 = active, 0 = disabled
|
|
username_new:
|
|
type: string
|
|
description: New username (letters, digits, `_`, `.`, `-`)
|
|
domains:
|
|
description: The domains the account administers from now on
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
password:
|
|
type: string
|
|
description: New password; empty or missing keeps the password
|
|
password2:
|
|
type: string
|
|
description: The new password again
|
|
force_tfa:
|
|
type: [integer, string, boolean]
|
|
description: 1 = two-factor authentication must be set up at the next login
|
|
default: 0
|
|
force_pw_update:
|
|
type: [integer, string, boolean]
|
|
description: 1 = the password must be changed at the next login
|
|
default: 0
|
|
disable_tfa:
|
|
type: [integer, string, boolean]
|
|
description: Present (any value) = turn off two-factor authentication
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- domainadmin1
|
|
attr:
|
|
active: 1
|
|
domains:
|
|
- example.org
|
|
password: "N3w-Passw0rd!"
|
|
password2: "N3w-Passw0rd!"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/domain-policy:
|
|
post:
|
|
summary: Add a sender to a domain allow or deny list
|
|
description: >-
|
|
Adds a sender to the allow list (`wl`) or deny list (`bl`) of a domain;
|
|
a sender can be on only one list. Needs the ACL `spam_policy`.
|
|
|
|
|
|
Messages: `domain_modified`; errors `policy_list_from_invalid`,
|
|
`policy_list_from_exists`.
|
|
operationId: addDomainPolicy
|
|
tags:
|
|
- Domain antispam policies
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
- object_list
|
|
- object_from
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain the entry belongs to
|
|
object_list:
|
|
type: string
|
|
enum: [wl, bl]
|
|
description: "`wl` allow list (whitelist), `bl` deny list (blacklist)"
|
|
object_from:
|
|
type: string
|
|
description: >-
|
|
Sender address or pattern with `*` as wildcard; letters,
|
|
digits and `@ _ . - *`
|
|
example:
|
|
domain: example.org
|
|
object_list: wl
|
|
object_from: "*@partner.example.com"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/fwdhost:
|
|
post:
|
|
tags:
|
|
- Forwarding Hosts
|
|
summary: Add forwarding hosts
|
|
operationId: addForwardingHost
|
|
description: >-
|
|
Adds hosts whose mail is accepted unconditionally: no DNSBL checks, no
|
|
greylisting, no spam rejects. A name becomes one entry per address of
|
|
its SPF record, else its MX hosts, else A/AAAA.
|
|
|
|
|
|
Messages: `forwarding_host_added`; errors `invalid_host`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
description: >-
|
|
IPv4 or IPv6 address, network in CIDR notation, host name
|
|
or domain name
|
|
filter_spam:
|
|
type: [boolean, integer, string]
|
|
description: 1 = scan the mail for spam (junk folder, never rejected); else not
|
|
default: 0
|
|
required:
|
|
- hostname
|
|
example:
|
|
hostname: relay.example.com
|
|
filter_spam: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/fwdhost:
|
|
post:
|
|
tags:
|
|
- Forwarding Hosts
|
|
summary: Update forwarding hosts
|
|
operationId: editForwardingHost
|
|
description: >-
|
|
Turns the spam filter of forwarding hosts on or off; without
|
|
`keep_spam` it is turned on.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: >-
|
|
Hosts as get/fwdhost lists them (`host`), a single value or
|
|
a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
keep_spam:
|
|
type: [boolean, integer, string]
|
|
description: 1 = do not scan the mail for spam; else scan it
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 192.0.2.25
|
|
- "2001:db8::25"
|
|
attr:
|
|
keep_spam: "0"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/mailbox:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Create a mailbox
|
|
operationId: addMailbox
|
|
description: >-
|
|
Creates a mailbox, also for domain admins. Quotas are in MiB. Fields
|
|
not sent come from the mailbox template in `template` (default:
|
|
`Default`). Quota 0 (unlimited) needs the `unlimited_quota` ACL.
|
|
|
|
|
|
Messages: `mailbox_added`; errors `object_exists`, `domain_not_found`,
|
|
`password_complexity`, `max_mailbox_exceeded`,
|
|
`mailbox_quota_exceeded`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxAdd"
|
|
example:
|
|
local_part: john.doe
|
|
domain: example.org
|
|
name: John Doe
|
|
password: Moo2Shoh5aiXu
|
|
password2: Moo2Shoh5aiXu
|
|
quota: 3072
|
|
active: 1
|
|
force_pw_update: 1
|
|
tags:
|
|
- sales
|
|
acl:
|
|
- spam_alias
|
|
- spam_score
|
|
- delimiter_action
|
|
- app_passwds
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/mailbox-group:
|
|
post:
|
|
summary: Create mailbox group
|
|
description: >-
|
|
Creates a mailbox group. With an address it is also a distribution list
|
|
to its members; the address counts against the alias limit of the
|
|
domain. Domain admins need the `mailbox_groups` ACL. Follow-up steps
|
|
that fail answer a warning and are retried later.
|
|
|
|
|
|
Messages: `group_added`; warnings `group_template_failed`,
|
|
`group_imap_grant_failed`; errors `object_exists`,
|
|
`group_address_invalid`, `max_alias_exceeded`, `group_member_invalid`.
|
|
operationId: addMailboxGroup
|
|
tags:
|
|
- Groups
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- type: object
|
|
required:
|
|
- domain
|
|
- name
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain of the group (no alias domain), case-insensitive
|
|
- $ref: "#/components/schemas/MailboxGroupAttributes"
|
|
example:
|
|
domain: example.org
|
|
name: Sales
|
|
description: Sales team
|
|
local_part: sales
|
|
members:
|
|
- alice@example.org
|
|
- bob@example.org
|
|
send_as:
|
|
- orders@example.org
|
|
sender_allowed: 1
|
|
imap_grants:
|
|
- owner: shared@example.org
|
|
rights: write
|
|
subscribe: 1
|
|
template_id: 3
|
|
priority: 10
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/oauth2-client:
|
|
post:
|
|
summary: Create OAuth2 client
|
|
description: >-
|
|
Creates an OAuth2 client with random ID and secret; read them with
|
|
`get/oauth2-client/all`. The redirect URI is not validated.
|
|
|
|
|
|
Messages: `Added client access`.
|
|
operationId: addOAuth2Client
|
|
tags:
|
|
- oAuth Clients
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
redirect_uri:
|
|
type: string
|
|
description: Redirect (callback) URL of the client application
|
|
required:
|
|
- redirect_uri
|
|
example:
|
|
redirect_uri: https://app.example.org/oauth/callback
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/recipient_map:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Create a recipient map
|
|
operationId: addRecipientMap
|
|
description: >-
|
|
Rewrites the recipient before delivery: mail to `recipient_map_old`
|
|
goes to `recipient_map_new`.
|
|
|
|
|
|
Messages: `recipient_map_entry_saved`; errors
|
|
`invalid_recipient_map_old`, `invalid_recipient_map_new`,
|
|
`recipient_map_entry_exists`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
recipient_map_old:
|
|
type: string
|
|
description: Original recipient, an e-mail address or a domain (leading `@` optional)
|
|
recipient_map_new:
|
|
type: string
|
|
description: New recipient, an e-mail address or a domain
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
default: 0
|
|
required:
|
|
- recipient_map_old
|
|
- recipient_map_new
|
|
example:
|
|
recipient_map_old: jane.doe@example.org
|
|
recipient_map_new: jane.smith@example.org
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/relayhost:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Create a sender-dependent transport
|
|
operationId: addRelayhost
|
|
description: >-
|
|
Adds an active relay host, used by domains and mailboxes whose
|
|
`relayhost` is set to its ID. Always `smtp:` (TLS when offered, no
|
|
SMTPS). Colons in `username` and `password` are stored escaped, but
|
|
not by edit/relayhost.
|
|
|
|
|
|
Messages: `relayhost_added`; errors `invalid_host`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
description: "Next hop: `host`, `host:25`, `[host]:587` or `[192.0.2.1]:25`"
|
|
username:
|
|
type: string
|
|
description: SMTP user name, empty for no authentication
|
|
default: ""
|
|
password:
|
|
type: string
|
|
description: SMTP password
|
|
default: ""
|
|
required:
|
|
- hostname
|
|
example:
|
|
hostname: "[smtp.example.com]:587"
|
|
username: relay-user@example.com
|
|
password: Secret-Passphrase-42
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/resource:
|
|
post:
|
|
tags:
|
|
- Resources
|
|
summary: Create a resource
|
|
operationId: addResource
|
|
description: >-
|
|
Creates a bookable SOGo resource, also for domain admins. Its address
|
|
is made of the letters and digits of `description` (`Meeting Room 1` →
|
|
`MeetingRoom1@example.org`).
|
|
|
|
|
|
Messages: `resource_added`; errors `resource_invalid`,
|
|
`description_invalid`, `object_exists`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
- description
|
|
- kind
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain of the resource
|
|
description:
|
|
type: string
|
|
description: Name of the resource, also the source of its address
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- location
|
|
- group
|
|
- thing
|
|
description: Type of resource
|
|
multiple_bookings:
|
|
type: [integer, string]
|
|
default: 0
|
|
description: >-
|
|
0 always free, -1 unlimited but busy when booked, n ≥ 1 at
|
|
most n overlapping bookings; below -1 means -1
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: 1 active, 0 inactive
|
|
example:
|
|
domain: example.org
|
|
description: Meeting Room 1
|
|
kind: location
|
|
multiple_bookings: 0
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/syncjob:
|
|
post:
|
|
summary: Create sync job
|
|
description: >-
|
|
Creates a sync job that copies the remote account `user1` into a local
|
|
mailbox; server and authentication come from the sync source. Needs the
|
|
`syncjobs` ACL; API keys must set `username`, users always sync into
|
|
their own mailbox. An invalid `mins_interval` or `exclude` answers
|
|
`access_denied`.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors `no_user_defined`,
|
|
`imapsync_source_unavailable`, `imapsync_source_oauth_connect_required`,
|
|
`object_exists`, `imapsync_custom_param_invalid`.
|
|
operationId: addSyncJob
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- type: object
|
|
required:
|
|
- username
|
|
- source_id
|
|
- user1
|
|
- mins_interval
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: >-
|
|
Local mailbox to sync into (`user2`), cannot be changed
|
|
later; users may leave it out
|
|
- $ref: "#/components/schemas/SyncJobAttributes"
|
|
example:
|
|
username: alice@example.org
|
|
source_id: 3
|
|
user1: alice@old-provider.example.com
|
|
password1: remote-password
|
|
mins_interval: 20
|
|
subfolder2: Imported
|
|
exclude: "(?i)spam|(?i)junk"
|
|
custom_params:
|
|
- o: folder
|
|
v: INBOX
|
|
delete2duplicates: 1
|
|
automap: 1
|
|
subscribeall: 1
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/syncjob_source:
|
|
post:
|
|
summary: Create sync source
|
|
description: >-
|
|
Creates a reusable IMAP server with its authentication that sync jobs
|
|
use by `source_id`. Needs the `syncjobs` ACL. Unless an admin creates
|
|
it, OAuth2 endpoints must resolve to public addresses. A
|
|
client_credentials source fetches its token on save and is saved even
|
|
when that fails.
|
|
|
|
|
|
Messages: `imapsync_source_added`, `imapsync_source_token_refresh_failed`;
|
|
errors `imapsync_source_host_invalid`, `imapsync_source_auth_invalid`,
|
|
`imapsync_source_oauth_invalid`, `imapsync_source_oauth_endpoint_invalid`,
|
|
`object_exists`.
|
|
operationId: addSyncJobSource
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- type: object
|
|
required:
|
|
- name
|
|
- host
|
|
- port
|
|
- $ref: "#/components/schemas/SyncJobSourceAttributes"
|
|
examples:
|
|
password:
|
|
summary: Password source for a domain
|
|
value:
|
|
name: Old provider
|
|
description: Migration from the old provider
|
|
host: imap.example.com
|
|
port: 993
|
|
enc: SSL
|
|
auth_type: PLAIN
|
|
scope: domain
|
|
domains:
|
|
- example.org
|
|
active: 1
|
|
client_credentials:
|
|
summary: XOAUTH2 source with an app token (Microsoft 365)
|
|
value:
|
|
name: M365 tenant
|
|
host: outlook.office365.com
|
|
port: 993
|
|
enc: SSL
|
|
auth_type: XOAUTH2
|
|
oauth_flow: client_credentials
|
|
oauth_token_endpoint: https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token
|
|
oauth_client_id: 11111111-2222-3333-4444-555555555555
|
|
oauth_client_secret: client-secret-value
|
|
oauth_scope: https://outlook.office365.com/.default
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/tls-policy-map:
|
|
post:
|
|
tags:
|
|
- Outgoing TLS Policy Map Overrides
|
|
summary: Create a TLS policy map
|
|
operationId: addTlsPolicyMap
|
|
description: >-
|
|
Sets the TLS policy for outgoing connections to a destination.
|
|
|
|
|
|
Messages: `tls_policy_map_entry_saved`; errors
|
|
`tls_policy_map_dest_invalid`, `tls_policy_map_parameter_invalid`,
|
|
`tls_policy_map_entry_exists`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
dest:
|
|
type: string
|
|
description: >-
|
|
Destination: a domain, `.example.org` for its subdomains or
|
|
a host like `[mail.example.org]:25`
|
|
policy:
|
|
type: string
|
|
description: >-
|
|
Postfix TLS security level (see
|
|
[smtp_tls_policy_maps](https://www.postfix.org/TLS_README.html#client_tls_policy))
|
|
enum:
|
|
- none
|
|
- may
|
|
- encrypt
|
|
- dane
|
|
- dane-only
|
|
- fingerprint
|
|
- verify
|
|
- secure
|
|
parameters:
|
|
type: string
|
|
description: Space-separated `name=value` attributes, may be empty
|
|
default: ""
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
default: 0
|
|
required:
|
|
- dest
|
|
- policy
|
|
example:
|
|
dest: example.com
|
|
policy: encrypt
|
|
parameters: protocols=>=TLSv1.2
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/transport:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Create transport maps
|
|
operationId: addTransport
|
|
description: >-
|
|
Routes mail for each destination over a next hop; overrules
|
|
sender-dependent transports. Always `smtp:` (TLS when offered, no
|
|
SMTPS); addresses ending in `localhost` stay local. `username` and
|
|
`password` apply to all entries of the next hop.
|
|
|
|
|
|
Messages: `relayhost_added`; errors `transport_dest_exists`,
|
|
`invalid_destination`, `next_hop_interferes`,
|
|
`invalid_nexthop_authenticated`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
destination:
|
|
type: string
|
|
description: >-
|
|
Domains, `.example.org` for subdomains, `*` or addresses,
|
|
separated by spaces, commas, semicolons or line breaks;
|
|
with `is_mx_based` a regular expression for the MX name of
|
|
the recipient domain
|
|
nexthop:
|
|
type: string
|
|
description: "`host`, `host:25`, `[host]:25` or an IP address (bracketed automatically)"
|
|
username:
|
|
type: string
|
|
description: SMTP user name, empty for no authentication
|
|
default: ""
|
|
password:
|
|
type: string
|
|
description: SMTP password
|
|
default: ""
|
|
is_mx_based:
|
|
type: [boolean, integer, string]
|
|
description: 1 = `destination` is a regular expression for MX names
|
|
default: 0
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
default: 0
|
|
required:
|
|
- destination
|
|
- nexthop
|
|
example:
|
|
destination: example.com, .example.com
|
|
nexthop: "[mx.example.com]:25"
|
|
username: ""
|
|
password: ""
|
|
is_mx_based: "0"
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/alias:
|
|
post:
|
|
tags:
|
|
- Aliases
|
|
summary: Delete aliases
|
|
operationId: deleteAlias
|
|
description: >-
|
|
Deletes the aliases and the send-as rights granted for their addresses.
|
|
Distribution addresses of mailbox groups cannot be deleted here.
|
|
|
|
|
|
Messages: `alias_removed`; errors `alias_group_managed`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs or addresses of the aliases (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 12
|
|
- info@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/api-key:
|
|
post:
|
|
summary: Delete API keys
|
|
description: >-
|
|
Deletes API keys. Service keys from mailcow.conf cannot be deleted.
|
|
|
|
|
|
Messages: `api_key_deleted`; error `api_key_service_locked`.
|
|
operationId: deleteApiKey
|
|
tags:
|
|
- API Keys
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the API keys
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 3
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/app-passwd:
|
|
post:
|
|
tags:
|
|
- App Passwords
|
|
summary: Delete app passwords
|
|
operationId: deleteAppPassword
|
|
description: >-
|
|
Deletes app passwords by ID. Needs the user ACL `app_passwds`. The
|
|
first unknown or foreign ID stops the call.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: App password IDs
|
|
items:
|
|
type: integer
|
|
example:
|
|
- 23
|
|
- 24
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/bcc:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Delete BCC maps
|
|
operationId: deleteBccMap
|
|
description: >-
|
|
Deletes BCC maps by ID. Same callers as add/bcc. A non-numeric ID stops
|
|
the call.
|
|
|
|
|
|
Messages: `bcc_deleted`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the BCC maps (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 3
|
|
- 4
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/dkim:
|
|
post:
|
|
summary: Delete DKIM keys
|
|
description: >-
|
|
Deletes the DKIM keys of domains. Answers `dkim_removed` also for
|
|
domains without a key.
|
|
operationId: deleteDkimKeys
|
|
tags:
|
|
- DKIM
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Domain names
|
|
items:
|
|
type: string
|
|
example:
|
|
- example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/domain:
|
|
post:
|
|
summary: Delete domains
|
|
description: >-
|
|
Deletes domains without mailboxes or resources, with their aliases,
|
|
alias domains and settings. Domain admins left without a domain are
|
|
deleted too. The DKIM key is kept.
|
|
|
|
|
|
Messages: `domain_removed`; error `domain_not_empty`.
|
|
operationId: deleteDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Domain names
|
|
items:
|
|
type: string
|
|
example:
|
|
- example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/domain-admin:
|
|
post:
|
|
summary: Delete domain administrators
|
|
description: >-
|
|
Deletes domain administrators with their ACLs, two-factor
|
|
authentication and FIDO2 keys.
|
|
|
|
|
|
Messages: `domain_admin_removed`; error `username_invalid`.
|
|
operationId: deleteDomainAdmin
|
|
tags:
|
|
- Domain admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Usernames of the domain administrators
|
|
items:
|
|
type: string
|
|
example:
|
|
- domainadmin1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/domain-policy:
|
|
post:
|
|
summary: Delete entries of domain allow and deny lists
|
|
description: >-
|
|
Deletes allow and deny list entries of domains by `prefid`. Needs the
|
|
ACL `spam_policy`. Unknown IDs and entries of mailboxes answer
|
|
`access_denied`.
|
|
|
|
|
|
Messages: `item_deleted`.
|
|
operationId: deleteDomainPolicy
|
|
tags:
|
|
- Domain antispam policies
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Entry IDs (`prefid`)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 12
|
|
- 13
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/fwdhost:
|
|
post:
|
|
tags:
|
|
- Forwarding Hosts
|
|
summary: Delete forwarding hosts
|
|
operationId: deleteForwardingHost
|
|
description: >-
|
|
Removes forwarding hosts, answering `forwarding_host_removed` also for
|
|
hosts that do not exist.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Hosts as get/fwdhost lists them (`host`; a single value works too)
|
|
items:
|
|
type: string
|
|
example:
|
|
- 192.0.2.25
|
|
- "2001:db8::25"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/fwdhost/{host}:
|
|
get:
|
|
tags:
|
|
- Forwarding Hosts
|
|
summary: Get forwarding hosts
|
|
operationId: getForwardingHosts
|
|
description: >-
|
|
`all` lists the forwarding hosts; any logged-in role may read a single
|
|
address. Networks cannot be read one by one (the slash ends the path).
|
|
`{}` if there is none.
|
|
parameters:
|
|
- name: host
|
|
in: path
|
|
required: true
|
|
description: "`all` or the address of a forwarding host"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of forwarding hosts (`all`) or one host
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/ForwardingHost"
|
|
- $ref: "#/components/schemas/ForwardingHost"
|
|
examples:
|
|
all:
|
|
summary: get/fwdhost/all
|
|
value:
|
|
- host: 192.0.2.25
|
|
source: relay.example.com
|
|
keep_spam: "no"
|
|
- host: "2001:db8::25"
|
|
source: relay.example.com
|
|
keep_spam: "no"
|
|
- host: 198.51.100.0/24
|
|
source: 198.51.100.0/24
|
|
keep_spam: "yes"
|
|
one:
|
|
summary: get/fwdhost/192.0.2.25
|
|
value:
|
|
host: 192.0.2.25
|
|
source: relay.example.com
|
|
keep_spam: "no"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/delete/mailbox:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Delete mailboxes
|
|
operationId: deleteMailbox
|
|
description: >-
|
|
Deletes mailboxes with all their data, including aliases that point
|
|
only to them. Also for domain admins; a mailbox user can delete its own
|
|
mailbox.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
example:
|
|
- john.doe@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/mailbox-group:
|
|
post:
|
|
summary: Delete mailbox groups
|
|
description: >-
|
|
Deletes groups with their address, send-as rights and grants. Members
|
|
keep their mailbox settings; another group's template may become
|
|
effective. Same permissions as edit.
|
|
|
|
|
|
Messages: `group_removed`.
|
|
operationId: deleteMailboxGroups
|
|
tags:
|
|
- Groups
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Group ids
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
example:
|
|
- 7
|
|
- 8
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/identity-link:
|
|
post:
|
|
summary: Remove identity links
|
|
description: >-
|
|
Removes the links of mailboxes to their Identity Provider users, e.g.
|
|
after an address moved to another user; the next sync run or login
|
|
links them again by email. Answers success also for mailboxes without a
|
|
link.
|
|
|
|
|
|
Messages: `iam_link_removed`.
|
|
operationId: deleteIdentityLinks
|
|
tags:
|
|
- Identity Provider
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Mailboxes
|
|
items:
|
|
type: string
|
|
example:
|
|
- alice@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/mailq:
|
|
post:
|
|
summary: Delete queued messages
|
|
description: >-
|
|
Deletes messages from the Postfix queue. To empty the whole queue use
|
|
`super_delete` of `POST /api/v1/edit/mailq`.
|
|
|
|
|
|
Messages: `queue_command_success`; errors `Error: command failed: ...`,
|
|
`unknown`.
|
|
operationId: deleteQueuedMessages
|
|
tags:
|
|
- Queue Manager
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
description: Queue IDs (a single ID works too)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
example:
|
|
- B98C6260CA1
|
|
- 4C1E8260D02
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/oauth2-client:
|
|
post:
|
|
summary: Delete OAuth2 clients
|
|
description: >-
|
|
Deletes OAuth2 clients but not their tokens; revoke these first with
|
|
`revoke_tokens` of `edit/oauth2-client`.
|
|
|
|
|
|
Messages: `items_deleted`.
|
|
operationId: deleteOAuth2Client
|
|
tags:
|
|
- oAuth Clients
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the clients
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/qitem:
|
|
post:
|
|
summary: Delete quarantined messages
|
|
description: >-
|
|
Deletes quarantine items without releasing or learning them. Domain
|
|
admins and mailbox users may delete their own items if the quarantine
|
|
module is allowed for them. Admins get `item_deleted` even for unknown
|
|
IDs.
|
|
operationId: deleteQuarantineItems
|
|
tags:
|
|
- Quarantine
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
description: IDs of quarantine items (a single ID works too)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
example:
|
|
- "33"
|
|
- "34"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/qitem:
|
|
post:
|
|
summary: Release or learn quarantined messages
|
|
description: >-
|
|
By `attr.action`: `release` and `learnham` both deliver the message,
|
|
delete the item and learn it as ham; `learnspam` deletes it and learns
|
|
it as spam. Domain
|
|
admins and mailbox users may act on their own items if the quarantine
|
|
module is allowed for them. A failed delivery stops the remaining
|
|
items.
|
|
|
|
|
|
Messages: `item_released`, `learned_ham`, `qlearn_spam`; errors
|
|
`release_send_failed`, `ham_learn_error`, `spam_learn_error`.
|
|
operationId: editQuarantineItems
|
|
tags:
|
|
- Quarantine
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: ID or list of IDs of quarantine items
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
action:
|
|
type: string
|
|
enum:
|
|
- release
|
|
- learnham
|
|
- learnspam
|
|
required:
|
|
- action
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- "33"
|
|
- "34"
|
|
attr:
|
|
action: release
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/recipient_map:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Delete recipient maps
|
|
operationId: deleteRecipientMap
|
|
description: >-
|
|
Deletes recipient maps by ID. Answers `recipient_map_entry_deleted`
|
|
also for IDs that do not exist; a non-numeric ID stops the call.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the recipient maps (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/relayhost:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Delete sender-dependent transports
|
|
operationId: deleteRelayhost
|
|
description: >-
|
|
Deletes sender-dependent transports by ID, answering
|
|
`relayhost_removed` also for IDs that do not exist. Domains that used
|
|
one fall back to the default route; the `relayhost` of mailboxes is not
|
|
reset.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the sender-dependent transports (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/resource:
|
|
post:
|
|
tags:
|
|
- Resources
|
|
summary: Delete resources
|
|
operationId: deleteResource
|
|
description: >-
|
|
Deletes resources and their SOGo data, also for domain admins.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Resource addresses
|
|
items:
|
|
type: string
|
|
example:
|
|
- MeetingRoom1@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/syncjob:
|
|
post:
|
|
summary: Delete sync jobs
|
|
description: >-
|
|
Deletes sync jobs. Needs the `syncjobs` ACL and access to the mailbox of
|
|
each job. The OAuth2 token of the remote account is deleted when no
|
|
other job uses it.
|
|
|
|
|
|
Messages: `deleted_syncjob`.
|
|
operationId: deleteSyncJobs
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Job ids
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
example:
|
|
- 12
|
|
- 13
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/syncjob_source:
|
|
post:
|
|
summary: Delete sync sources
|
|
description: >-
|
|
Deletes sync sources that no job uses. Needs the `syncjobs` ACL and edit
|
|
rights on the source.
|
|
|
|
|
|
Messages: `imapsync_source_deleted`; errors `imapsync_source_in_use`.
|
|
operationId: deleteSyncJobSources
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Source ids
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
example:
|
|
- 3
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/tls-policy-map:
|
|
post:
|
|
tags:
|
|
- Outgoing TLS Policy Map Overrides
|
|
summary: Delete TLS policy maps
|
|
operationId: deleteTlsPolicyMap
|
|
description: >-
|
|
Deletes TLS policy maps by ID. Answers `tls_policy_map_entry_deleted`
|
|
also for IDs that do not exist; a non-numeric ID stops the call.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the TLS policy maps (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 2
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/transport:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Delete transport maps
|
|
operationId: deleteTransport
|
|
description: >-
|
|
Deletes transport maps by ID, answering `relayhost_removed` also for
|
|
IDs that do not exist.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: IDs of the transport maps (a single value works too)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 4
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/mailbox/tag/{mailbox}:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Remove tags from a mailbox
|
|
operationId: deleteMailboxTags
|
|
description: >-
|
|
Removes tags from the mailbox, also for domain admins. Answers "Cannot
|
|
delete item" when no tag was sent.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Tag names
|
|
items:
|
|
type: string
|
|
example:
|
|
- sales
|
|
- trainee
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/domain/tag/{domain}:
|
|
post:
|
|
summary: Remove tags of a domain
|
|
description: >-
|
|
Removes tags from a domain. Answers `domain_modified` also for tags the
|
|
domain did not have.
|
|
operationId: deleteDomainTags
|
|
tags:
|
|
- Domains
|
|
parameters:
|
|
- name: domain
|
|
in: path
|
|
required: true
|
|
description: Domain name
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Tag names
|
|
items:
|
|
type: string
|
|
example:
|
|
- customer
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/alias:
|
|
post:
|
|
tags:
|
|
- Aliases
|
|
summary: Update aliases
|
|
operationId: editAlias
|
|
description: >-
|
|
Changes the aliases in `items`; fields not sent keep their value,
|
|
except the `goto_*` flags, which are reset to 0. An alias that discards
|
|
or learns its mail therefore needs its `goto_*` flag in every edit,
|
|
else nothing is saved while the answer still says `alias_modified`.
|
|
Invalid destinations are dropped; if none remains, nothing is saved.
|
|
|
|
|
|
Messages: `alias_modified`; errors `alias_invalid`,
|
|
`alias_group_managed`, `goto_invalid`, `is_not_primary_alias`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs or addresses of the aliases, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
address:
|
|
type: string
|
|
description: New alias address, `@example.org` for a catch-all
|
|
goto:
|
|
type: string
|
|
description: >-
|
|
New destination addresses, replacing the current ones;
|
|
ignored if a `goto_*` flag is 1
|
|
goto_null:
|
|
type: [boolean, integer, string]
|
|
description: 1 = discard the mail silently
|
|
default: 0
|
|
goto_spam:
|
|
type: [boolean, integer, string]
|
|
description: 1 = learn the mail as spam
|
|
default: 0
|
|
goto_ham:
|
|
type: [boolean, integer, string]
|
|
description: 1 = learn the mail as ham
|
|
default: 0
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
sogo_visible:
|
|
type: [boolean, integer, string]
|
|
description: 1 = selectable sender in SOGo
|
|
internal:
|
|
type: [boolean, integer, string]
|
|
description: 1 = only reachable from its own domain and its alias domains
|
|
sender_allowed:
|
|
type: [boolean, integer, string]
|
|
description: 1 = the destination mailboxes may send as this alias
|
|
public_comment:
|
|
type: string
|
|
description: Comment shown to the users
|
|
private_comment:
|
|
type: string
|
|
description: Comment for administrators
|
|
expand_alias:
|
|
type: [boolean, integer]
|
|
description: >-
|
|
1 = only create the missing copies of the alias in the
|
|
alias domains of its domain; other attributes are
|
|
ignored
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 12
|
|
attr:
|
|
goto: anna@example.org,ben@example.org,carla@example.org
|
|
active: "1"
|
|
public_comment: Sales team
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/api-key:
|
|
post:
|
|
summary: Edit API keys
|
|
description: >-
|
|
Changes API keys; fields not sent keep their value. `regen_key` sets a
|
|
new random value, which locks out clients using the old one. Service
|
|
keys from mailcow.conf cannot be changed.
|
|
|
|
|
|
Messages: `api_key_modified`; errors `api_key_service_locked`,
|
|
`api_key_network_invalid`, `ip_list_empty`.
|
|
operationId: editApiKey
|
|
tags:
|
|
- API Keys
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: ID of the API key, or a list of IDs
|
|
oneOf:
|
|
- type: [integer, string]
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
attr:
|
|
allOf:
|
|
- $ref: "#/components/schemas/ApiKeyAttributes"
|
|
- type: object
|
|
properties:
|
|
regen_key:
|
|
type: [integer, string, boolean]
|
|
description: 1 = generate a new key value
|
|
default: 0
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 3
|
|
attr:
|
|
allow_from:
|
|
- 192.0.2.10
|
|
- 198.51.100.0/24
|
|
regen_key: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/domain:
|
|
post:
|
|
summary: Edit domains
|
|
description: >-
|
|
Changes domains. Quotas are in MiB. Fields not sent keep their value,
|
|
so do `aliases`, `maxquota` and `quota` sent as 0 or empty. `tags` are
|
|
added; a tag the domain has already ends the call without an answer
|
|
after saving the rest. Domain admins can change only `description`,
|
|
`gal` and `tags`.
|
|
|
|
|
|
Messages: `domain_modified`; errors `domain_invalid`,
|
|
`max_quota_in_use`, `mailboxes_in_use`, `aliases_in_use`.
|
|
operationId: editDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Domain name or list of domain names
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
description:
|
|
type: string
|
|
description: Description
|
|
aliases:
|
|
type: [integer, string]
|
|
description: Max. number of aliases
|
|
mailboxes:
|
|
type: [integer, string]
|
|
description: Max. number of mailboxes
|
|
defquota:
|
|
type: [integer, string]
|
|
description: Default quota of new mailboxes in MiB
|
|
maxquota:
|
|
type: [integer, string]
|
|
description: Max. quota per mailbox in MiB
|
|
quota:
|
|
type: [integer, string]
|
|
description: Quota of the whole domain in MiB
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Domain active
|
|
gal:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Global address list in SOGo
|
|
backupmx:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Relay this domain (backup MX)
|
|
relay_all_recipients:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Relay all recipients; 1 sets `backupmx`
|
|
relay_unknown_only:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: >-
|
|
Relay only recipients without a local mailbox; 1 sets
|
|
`backupmx` and `relay_all_recipients`
|
|
relayhost:
|
|
type: [integer, string]
|
|
description: >-
|
|
ID of the sender-dependent transport (get/relayhost/all)
|
|
the domain sends through, 0 = none
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Tags to add
|
|
example:
|
|
items:
|
|
- example.org
|
|
attr:
|
|
description: Example Org
|
|
aliases: 400
|
|
mailboxes: 20
|
|
defquota: 3072
|
|
maxquota: 10240
|
|
quota: 51200
|
|
active: 1
|
|
gal: 1
|
|
backupmx: 0
|
|
relay_all_recipients: 0
|
|
relay_unknown_only: 0
|
|
relayhost: 0
|
|
tags:
|
|
- premium
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/domain/footer:
|
|
post:
|
|
summary: Set the domain-wide footer
|
|
description: >-
|
|
Sets the footer of all outgoing mail of the domains; fields not sent are
|
|
emptied. Placeholders: `{= auth_user =}`, `{= from_user =}`,
|
|
`{= from_name =}`, `{= from_addr =}`, `{= from_domain =}` and custom
|
|
mailbox attributes.
|
|
|
|
|
|
Messages: `domain_footer_modified`; error `domain_invalid`.
|
|
operationId: editDomainFooter
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Domain name or list of domain names
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
html:
|
|
type: string
|
|
default: ""
|
|
description: HTML footer
|
|
plain:
|
|
type: string
|
|
default: ""
|
|
description: Plain text footer
|
|
skip_replies:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: No footer in replies
|
|
exclude:
|
|
description: >-
|
|
Mailboxes, aliases and alias domains without footer;
|
|
unknown entries are skipped (`username_invalid`)
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
items:
|
|
- example.org
|
|
attr:
|
|
html: "<p>Example Org · {= from_name =}</p>"
|
|
plain: "Example Org - {= from_name =}"
|
|
skip_replies: 1
|
|
exclude:
|
|
- noreply@example.org
|
|
- example.com
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/fail2ban:
|
|
post:
|
|
summary: Edit Fail2Ban settings, bans and filters
|
|
description: >-
|
|
By `attr.action`: `unban`, `whitelist` and `blacklist` unban, allowlist
|
|
or deny the networks in `items`; `unban-all` lifts all active bans;
|
|
`edit-regex` replaces the regex filters with `attr.regex`,
|
|
`reset-regex` restores the defaults. Without `action` the settings are
|
|
saved: fields not sent keep their value, but `ban_time_increment` and
|
|
`manage_external` become 0, and values out of range are clamped. The
|
|
same happens for `unban`, `whitelist`, `blacklist` or `reset-regex`
|
|
without `items`.
|
|
|
|
|
|
Messages: `f2b_modified`, `object_modified`; errors
|
|
`network_host_invalid`, `reset_f2b_regex`.
|
|
operationId: editFail2Ban
|
|
tags:
|
|
- Fail2Ban
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Networks or IPs for `unban`, `whitelist`, `blacklist` (single value or list)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
action:
|
|
type: string
|
|
enum:
|
|
- unban
|
|
- whitelist
|
|
- blacklist
|
|
- unban-all
|
|
- edit-regex
|
|
- reset-regex
|
|
regex:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "`edit-regex`: the regex filters; the first group must match the IP"
|
|
ban_time:
|
|
type: [integer, string]
|
|
description: Ban time in seconds (min. 60)
|
|
ban_time_increment:
|
|
type: [boolean, integer, string]
|
|
description: 1 = the ban time grows with every ban of a network; not sent = 0
|
|
max_ban_time:
|
|
type: [integer, string]
|
|
description: Maximum ban time in seconds (min. 60)
|
|
max_attempts:
|
|
type: [integer, string]
|
|
description: Failed logins within `retry_window` that lead to a ban (min. 1)
|
|
retry_window:
|
|
type: [integer, string]
|
|
description: Window in seconds for `max_attempts` (min. 1)
|
|
netban_ipv4:
|
|
type: [integer, string]
|
|
description: IPv4 prefix length that is banned (8-32)
|
|
netban_ipv6:
|
|
type: [integer, string]
|
|
description: IPv6 prefix length that is banned (8-128)
|
|
whitelist:
|
|
type: string
|
|
description: Allowlist, networks or host names separated by space, comma, semicolon or newline; replaces the list
|
|
blacklist:
|
|
type: string
|
|
description: Denylist, networks separated by space, comma, semicolon or newline; replaces the list
|
|
manage_external:
|
|
type: [boolean, integer, string]
|
|
description: 1 = netfilter sets no rules, block externally with the banlist; not sent = 0
|
|
required:
|
|
- attr
|
|
examples:
|
|
settings:
|
|
summary: Save the settings
|
|
value:
|
|
items: []
|
|
attr:
|
|
ban_time: "1800"
|
|
ban_time_increment: "1"
|
|
max_ban_time: "86400"
|
|
max_attempts: "10"
|
|
retry_window: "600"
|
|
netban_ipv4: "32"
|
|
netban_ipv6: "128"
|
|
whitelist: |-
|
|
192.0.2.0/24
|
|
mail.example.org
|
|
blacklist: 198.51.100.66/32
|
|
manage_external: "0"
|
|
unban:
|
|
summary: Unban a network
|
|
value:
|
|
items:
|
|
- 203.0.113.7/32
|
|
attr:
|
|
action: unban
|
|
regex:
|
|
summary: Replace the regex filters
|
|
value:
|
|
items:
|
|
- self
|
|
attr:
|
|
action: edit-regex
|
|
regex:
|
|
- "^mailcow UI: Invalid password for .+ by ([0-9a-f\\.:]+)$"
|
|
- "^Rspamd UI: Invalid password by ([0-9a-f\\.:]+)$"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/mailbox:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Update mailboxes
|
|
operationId: editMailbox
|
|
description: >-
|
|
Changes mailboxes; fields not sent keep their value. Also for domain
|
|
admins; without the matching ACL their changes to `sogo_access`,
|
|
protocols and `relayhost` are ignored silently and
|
|
`extended_sender_acl` is refused. Quota 0 (unlimited) needs the
|
|
`unlimited_quota` ACL.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors `mailbox_quota_exceeded`,
|
|
`password_complexity`, `sender_acl_invalid`,
|
|
`extended_sender_acl_denied`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
$ref: "#/components/schemas/MailboxEdit"
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
name: John Doe
|
|
quota: 5120
|
|
active: 1
|
|
protocol_access:
|
|
- imap
|
|
- smtp
|
|
- sieve
|
|
- dav
|
|
sender_acl:
|
|
- sales@example.org
|
|
- "@example.com"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/mailbox/custom-attribute:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Set custom attributes of mailboxes
|
|
operationId: editMailboxCustomAttributes
|
|
description: >-
|
|
Replaces the custom attributes (free key/value pairs) of the mailboxes:
|
|
`attribute[i]` gets `value[i]`, all others are removed. Also for domain
|
|
admins.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
attribute:
|
|
description: Attribute names (a single string is one name)
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
value:
|
|
description: Values, in the order of `attribute`
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
attribute:
|
|
- department
|
|
- employee_id
|
|
value:
|
|
- Sales
|
|
- "4711"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/mailbox-group:
|
|
post:
|
|
summary: Update mailbox groups
|
|
description: >-
|
|
Changes groups; fields not sent keep their value. The domain cannot be
|
|
changed, and members from the identity sync cannot be removed here.
|
|
Domain admins need the `mailbox_groups` ACL and cannot edit groups with
|
|
send-as addresses or grants outside their domains.
|
|
|
|
|
|
Messages: `group_modified`; errors `group_member_idp` and those of add.
|
|
operationId: editMailboxGroups
|
|
tags:
|
|
- Groups
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: >-
|
|
Group ids, a list or a single id. An `id` inside `attr`
|
|
replaces `items`.
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
- type:
|
|
- integer
|
|
- string
|
|
attr:
|
|
allOf:
|
|
- $ref: "#/components/schemas/MailboxGroupAttributes"
|
|
- type: object
|
|
properties:
|
|
reapply_template:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Admins only: apply the effective templates to all
|
|
members again, also when nothing changed
|
|
default: 0
|
|
example:
|
|
items:
|
|
- 7
|
|
attr:
|
|
add_members:
|
|
- carol@example.org
|
|
remove_members:
|
|
- bob@example.org
|
|
sogo_grants:
|
|
- owner: shared@example.org
|
|
type: Calendar
|
|
folder: personal
|
|
access: write
|
|
subscribe: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/identity-provider-sync:
|
|
post:
|
|
summary: Request an identity sync run
|
|
description: >-
|
|
Queues an identity sync run (Keycloak and LDAP) that starts within a
|
|
minute, see `GET /api/v1/get/identity-provider/sync-status`. An
|
|
identical pending request is reused.
|
|
|
|
|
|
Messages: `iam_sync_requested`; errors `iam_sync_mode_invalid`,
|
|
`iam_sync_unavailable`.
|
|
operationId: requestIdentitySync
|
|
tags:
|
|
- Identity Provider
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Not used
|
|
attr:
|
|
type: object
|
|
properties:
|
|
mode:
|
|
type: string
|
|
description: >-
|
|
`preview` lists the changes without applying them,
|
|
`run` applies them, `force` applies them without the
|
|
change limit (`offboarding_limit`)
|
|
enum:
|
|
- preview
|
|
- run
|
|
- force
|
|
default: run
|
|
example:
|
|
attr:
|
|
mode: preview
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/mailq:
|
|
post:
|
|
summary: Act on the mail queue
|
|
description: >-
|
|
Runs a Postfix queue command. `hold`, `unhold` and `deliver` act on the
|
|
queue IDs in `items` and do nothing without them; `flush` retries the
|
|
whole queue, `super_delete` deletes every queued message.
|
|
|
|
|
|
Messages: `queue_command_success`; errors `Error: command failed: ...`,
|
|
`unknown`.
|
|
operationId: editMailQueue
|
|
tags:
|
|
- Queue Manager
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Queue ID or list of queue IDs (for `hold`, `unhold`, `deliver`)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
action:
|
|
type: string
|
|
enum:
|
|
- hold
|
|
- unhold
|
|
- deliver
|
|
- flush
|
|
- super_delete
|
|
required:
|
|
- action
|
|
required:
|
|
- attr
|
|
examples:
|
|
hold:
|
|
summary: Hold two messages
|
|
value:
|
|
items:
|
|
- B98C6260CA1
|
|
- 4C1E8260D02
|
|
attr:
|
|
action: hold
|
|
flush:
|
|
summary: Flush the whole queue
|
|
value:
|
|
items: []
|
|
attr:
|
|
action: flush
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/pushover:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Set the Pushover notifications of mailboxes
|
|
operationId: editPushover
|
|
description: >-
|
|
Saves the Pushover settings (push notification on new mail) of the
|
|
mailboxes; `delete: "true"` removes them. Needs the user ACL
|
|
`pushover`; domain admins need their own ACL `pushover`. `key` and
|
|
`token` are required the first time; later, empty fields keep their
|
|
value.
|
|
|
|
|
|
Messages: `pushover_settings_edited`; errors `pushover_key`,
|
|
`pushover_token`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
key:
|
|
type: string
|
|
description: Pushover user key, 30 letters and digits
|
|
token:
|
|
type: string
|
|
description: Pushover application token, 30 letters and digits
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
title:
|
|
type: string
|
|
description: Title of the notification (default "Mail")
|
|
text:
|
|
type: string
|
|
description: Text of the notification
|
|
senders:
|
|
type: string
|
|
description: Only notify for these senders (separated by comma, space or semicolon)
|
|
senders_regex:
|
|
type: string
|
|
description: Only notify for senders matching this regular expression
|
|
evaluate_x_prio:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: 1 sends high-priority mail as high-priority notification (0 when not sent)
|
|
only_x_prio:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: 1 notifies for high-priority mails only (0 when not sent)
|
|
sound:
|
|
type: string
|
|
description: Pushover sound name (empty when not sent)
|
|
delete:
|
|
type: string
|
|
enum:
|
|
- "true"
|
|
description: '"true" removes the Pushover settings, other fields are ignored'
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
key: uQiRzpo4DXghDmr9QzzfQu27cmVRsG
|
|
token: azGDORePK8gMaC0QOYAMyEEuzJnyUi
|
|
active: 1
|
|
title: New mail
|
|
text: You've got mail
|
|
senders: boss@example.org
|
|
evaluate_x_prio: 1
|
|
only_x_prio: 0
|
|
sound: pushover
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/quarantine_notification:
|
|
post:
|
|
tags:
|
|
- Quarantine
|
|
summary: Set the quarantine notification interval of mailboxes
|
|
operationId: editQuarantineNotification
|
|
description: >-
|
|
How often the mailbox user gets a summary of quarantined mail. Needs
|
|
the user ACL `quarantine_notification`; a mailbox user may change only
|
|
its own. An invalid value answers `access_denied`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
required:
|
|
- quarantine_notification
|
|
properties:
|
|
quarantine_notification:
|
|
type: string
|
|
enum:
|
|
- never
|
|
- hourly
|
|
- daily
|
|
- weekly
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
quarantine_notification: daily
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/syncjob:
|
|
post:
|
|
summary: Update sync jobs
|
|
description: >-
|
|
Changes sync jobs; fields not sent keep their value, an empty `user1` or
|
|
`password1` keeps the stored one. The local mailbox cannot be changed.
|
|
Needs the `syncjobs` ACL and access to the mailbox of each job.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors as for add.
|
|
operationId: editSyncJobs
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: >-
|
|
Job ids, a list or a single id. An `id` inside `attr`
|
|
replaces `items`.
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
- type:
|
|
- integer
|
|
- string
|
|
attr:
|
|
allOf:
|
|
- $ref: "#/components/schemas/SyncJobAttributes"
|
|
- type: object
|
|
properties:
|
|
last_run:
|
|
description: Any value except null resets the last run time (the job is due again)
|
|
success:
|
|
description: Any value except null resets the result of the last run
|
|
prio:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: >-
|
|
Admins only: queue priority, higher runs first (see
|
|
`edit/syncjob/run_next`)
|
|
example:
|
|
items:
|
|
- 12
|
|
- 13
|
|
attr:
|
|
active: 0
|
|
mins_interval: 60
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/syncjob/run_next:
|
|
post:
|
|
summary: Run sync jobs next
|
|
description: >-
|
|
Moves sync jobs to the front of the queue so the runner starts them
|
|
next; their `last_run` and `success` are cleared.
|
|
|
|
|
|
Messages: `imapsync_run_next_done`; errors `imapsync_job_running`.
|
|
operationId: runSyncJobsNext
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
description: Job ids
|
|
type: array
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
attr:
|
|
description: Not used
|
|
type: object
|
|
example:
|
|
items:
|
|
- 12
|
|
attr: {}
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/syncjob_source:
|
|
post:
|
|
summary: Update sync sources
|
|
description: >-
|
|
Changes sync sources; fields not sent keep their value, an empty
|
|
`oauth_client_secret` keeps the stored one. Needs the `syncjobs` ACL and
|
|
edit rights: own sources, for domain admins also those of their
|
|
mailboxes. Changing the server or OAuth2 client drops stored tokens and,
|
|
like turning off `verify_cert`, needs access to every mailbox whose jobs
|
|
use the source.
|
|
|
|
|
|
Messages: `imapsync_source_modified`,
|
|
`imapsync_source_token_refresh_failed`; errors
|
|
`imapsync_source_used_by_others` and those of add.
|
|
operationId: editSyncJobSources
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: >-
|
|
Source ids, a list or a single id. An `id` inside `attr`
|
|
replaces `items`.
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
- type:
|
|
- integer
|
|
- string
|
|
attr:
|
|
$ref: "#/components/schemas/SyncJobSourceAttributes"
|
|
example:
|
|
items:
|
|
- 3
|
|
attr:
|
|
description: Migration finished in December
|
|
scope: user
|
|
users:
|
|
- alice@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/syncjob_source/refresh_token:
|
|
post:
|
|
summary: Refresh the token of a sync source
|
|
description: >-
|
|
Fetches a new OAuth2 token for a client_credentials source now; tokens
|
|
are otherwise refreshed before they expire. Needs the `syncjobs` ACL and
|
|
edit rights on the source.
|
|
|
|
|
|
Messages: `imapsync_source_token_refreshed`; errors
|
|
`imapsync_source_refresh_unsupported`,
|
|
`imapsync_source_token_refresh_failed`.
|
|
operationId: refreshSyncJobSourceToken
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
description: Source id (the first entry is used)
|
|
type: array
|
|
items:
|
|
type:
|
|
- integer
|
|
- string
|
|
attr:
|
|
description: Not used
|
|
type: object
|
|
example:
|
|
items:
|
|
- 5
|
|
attr: {}
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/imapsync_settings:
|
|
post:
|
|
summary: Update global sync job settings
|
|
description: >-
|
|
Sets how many sync jobs run at the same time and the bandwidth limit of
|
|
each sync job process; a lower `maxbytespersecond` of a job still
|
|
applies.
|
|
|
|
|
|
Messages: `max_parallel_saved`; errors `imapsync_max_parallel_invalid`,
|
|
`imapsync_max_kb_per_second_invalid`.
|
|
operationId: editSyncJobSettings
|
|
tags:
|
|
- Sync jobs
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Not used
|
|
attr:
|
|
type: object
|
|
required:
|
|
- max_parallel
|
|
properties:
|
|
max_parallel:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Sync jobs running at the same time, 1-32
|
|
minimum: 1
|
|
maximum: 32
|
|
max_kb_per_second:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: Bandwidth limit per sync job process in KB/s; 0, empty or not sent = unlimited
|
|
default: 0
|
|
minimum: 0
|
|
maximum: 10485760
|
|
example:
|
|
attr:
|
|
max_parallel: 4
|
|
max_kb_per_second: 2000
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/user-acl:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Set the ACL of mailboxes
|
|
operationId: editUserAcl
|
|
description: >-
|
|
Sets the user ACL (what the mailbox user may change in the UI): listed
|
|
ACLs on, all others off. Domain admins can change only ACLs they have
|
|
themselves. Answers `acl_saved`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
user_acl:
|
|
description: ACLs to switch on (a single string is one ACL); an empty list switches all off
|
|
oneOf:
|
|
- $ref: "#/components/schemas/UserAclName"
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/UserAclName"
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
user_acl:
|
|
- spam_alias
|
|
- tls_policy
|
|
- spam_score
|
|
- spam_policy
|
|
- delimiter_action
|
|
- eas_reset
|
|
- pushover
|
|
- quarantine
|
|
- quarantine_notification
|
|
- app_passwds
|
|
- pw_reset
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/alias/{id}:
|
|
get:
|
|
tags:
|
|
- Aliases
|
|
summary: Get aliases
|
|
operationId: getAliases
|
|
description: >-
|
|
`all` lists the aliases of the domains the caller manages, an ID or
|
|
address returns one alias. Mailbox addresses are not listed. `{}` if
|
|
there is none.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all`, or the ID or address of an alias"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of aliases (`all`) or one alias
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/Alias"
|
|
- $ref: "#/components/schemas/Alias"
|
|
examples:
|
|
all:
|
|
summary: get/alias/all
|
|
value:
|
|
- in_primary_domain: ""
|
|
id: 12
|
|
domain: example.org
|
|
public_comment: Sales team
|
|
private_comment: null
|
|
goto: anna@example.org,ben@example.org
|
|
address: sales@example.org
|
|
is_catch_all: 0
|
|
internal: 0
|
|
active: 1
|
|
active_int: 1
|
|
sogo_visible: 1
|
|
sogo_visible_int: 1
|
|
sender_allowed: 1
|
|
group_id: null
|
|
group_name: null
|
|
created: "2026-10-26 14:43:58"
|
|
modified: "2026-11-08 20:38:01"
|
|
- in_primary_domain: example.org
|
|
id: 20
|
|
domain: example.net
|
|
public_comment: ""
|
|
private_comment: ""
|
|
goto: null@localhost
|
|
address: "@example.net"
|
|
is_catch_all: 1
|
|
internal: 0
|
|
active: 1
|
|
active_int: 1
|
|
sogo_visible: 0
|
|
sogo_visible_int: 0
|
|
sender_allowed: 0
|
|
group_id: null
|
|
group_name: null
|
|
created: "2026-11-02 09:12:40"
|
|
modified: null
|
|
one:
|
|
summary: get/alias/12
|
|
value:
|
|
in_primary_domain: ""
|
|
id: 12
|
|
domain: example.org
|
|
public_comment: Sales team
|
|
private_comment: null
|
|
goto: anna@example.org,ben@example.org
|
|
address: sales@example.org
|
|
is_catch_all: 0
|
|
internal: 0
|
|
active: 1
|
|
active_int: 1
|
|
sogo_visible: 1
|
|
sogo_visible_int: 1
|
|
sender_allowed: 1
|
|
group_id: null
|
|
group_name: null
|
|
created: "2026-10-26 14:43:58"
|
|
modified: "2026-11-08 20:38:01"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/alias/all/{domains}:
|
|
get:
|
|
tags:
|
|
- Aliases
|
|
summary: Get the aliases of domains
|
|
operationId: getAliasesByDomain
|
|
description: >-
|
|
Lists the aliases of the named domains or alias domains, skipping
|
|
domains the caller does not manage. `{}` if there is none.
|
|
parameters:
|
|
- name: domains
|
|
in: path
|
|
required: true
|
|
description: Comma-separated domain names
|
|
schema:
|
|
type: string
|
|
example: example.org,example.net
|
|
responses:
|
|
"200":
|
|
description: The list of aliases
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Alias"
|
|
example:
|
|
- in_primary_domain: ""
|
|
id: 12
|
|
domain: example.org
|
|
public_comment: Sales team
|
|
private_comment: null
|
|
goto: anna@example.org,ben@example.org
|
|
address: sales@example.org
|
|
is_catch_all: 0
|
|
internal: 0
|
|
active: 1
|
|
active_int: 1
|
|
sogo_visible: 1
|
|
sogo_visible_int: 1
|
|
sender_allowed: 1
|
|
group_id: null
|
|
group_name: null
|
|
created: "2026-10-26 14:43:58"
|
|
modified: "2026-11-08 20:38:01"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/time_limited_aliases/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Get the time-limited aliases of a mailbox
|
|
operationId: getTimeLimitedAliases
|
|
description: >-
|
|
The valid or permanent time-limited aliases of the mailbox. `{}` if
|
|
none or no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: List of aliases
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TimeLimitedAlias"
|
|
example:
|
|
- address: kahd.osuwe@example.org
|
|
goto: john.doe@example.org
|
|
description: Online shop registration
|
|
validity: 1795699200
|
|
created: "2026-11-10 09:00:00"
|
|
modified: null
|
|
permanent: 0
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/time_limited_alias:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Update time-limited aliases
|
|
operationId: editTimeLimitedAlias
|
|
description: >-
|
|
Sets a new expiry (`validity` hours from now) or makes the aliases
|
|
permanent. Needs the user ACL `spam_alias`. Without `validity` or a
|
|
true `permanent` nothing changes.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Alias address or list of addresses
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
validity:
|
|
type: [integer, string]
|
|
description: Hours from now until the alias expires (not range-checked); ends a permanent state
|
|
permanent:
|
|
type: [boolean, integer, string]
|
|
description: true makes the alias permanent (wins over `validity`)
|
|
example:
|
|
items:
|
|
- kahd.osuwe@example.org
|
|
attr:
|
|
validity: 24
|
|
permanent: 0
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/time_limited_alias:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Delete time-limited aliases
|
|
operationId: deleteTimeLimitedAlias
|
|
description: >-
|
|
Deletes time-limited aliases. Needs the user ACL `spam_alias`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Alias addresses
|
|
items:
|
|
type: string
|
|
example:
|
|
- kahd.osuwe@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/pushover-test:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Verify the Pushover credentials of mailboxes
|
|
operationId: testPushover
|
|
description: >-
|
|
Checks the stored Pushover credentials of each mailbox with the
|
|
Pushover API; `attr` is not used. Same access as `edit/pushover`.
|
|
Answers "Pushover API OK (200): ..." or "Pushover API ERR (code): ...";
|
|
a mailbox without settings stops the call.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
description: Not used
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr: {}
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/delimiter_action:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Set the handling of tagged mail
|
|
operationId: editDelimiterAction
|
|
description: >-
|
|
Handling of mail to `user+tag@example.org`: move to the subfolder "tag"
|
|
(`subfolder`), add "[tag]" to the subject (`subject`) or nothing
|
|
(`none`, also for other values). Needs the user ACL `delimiter_action`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
tagged_mail_handler:
|
|
type: string
|
|
enum:
|
|
- subfolder
|
|
- subject
|
|
- none
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
tagged_mail_handler: subfolder
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/tls_policy:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Set the TLS policy of mailboxes
|
|
operationId: editTlsPolicy
|
|
description: >-
|
|
Enforces TLS for incoming and/or outgoing mail; fields not sent keep
|
|
their value. Needs the user ACL `tls_policy`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
tls_enforce_in:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: 1 accepts incoming mail only over TLS
|
|
tls_enforce_out:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: 1 sends outgoing mail only over TLS
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
tls_enforce_in: 1
|
|
tls_enforce_out: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/spam-score:
|
|
get:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Get the default spam score
|
|
operationId: getDefaultSpamScore
|
|
description: >-
|
|
The spam thresholds of the session user; for API keys the Rspamd
|
|
default (`5,15` if Rspamd is unreachable).
|
|
responses:
|
|
"200":
|
|
description: Thresholds
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SpamScore"
|
|
example:
|
|
score: "8,15"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/api-key/{id}:
|
|
get:
|
|
summary: Get API key
|
|
description: One API key with its value. A read-only API key gets `{}`.
|
|
operationId: getApiKey
|
|
tags:
|
|
- API Keys
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: ID of the API key
|
|
schema:
|
|
type: integer
|
|
example: 3
|
|
responses:
|
|
"200":
|
|
description: The API key, `{}` if there is none with this ID or for a read-only API key
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ApiKey"
|
|
example:
|
|
id: 3
|
|
description: provisioning
|
|
access: rw
|
|
api_key: 1B7E2C-94F0A3-6D5B18-C2E7F4-03A9D6
|
|
allow_from:
|
|
- 192.0.2.10
|
|
- 2001:db8::/64
|
|
skip_ip_check: 0
|
|
service: 0
|
|
active: 1
|
|
created: "2026-11-02 09:12:44"
|
|
modified: "2026-11-05 16:40:02"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/api-key/all:
|
|
get:
|
|
summary: Get API keys
|
|
description: >-
|
|
Lists all API keys with their values, service keys first. A read-only
|
|
API key gets `{}`.
|
|
operationId: getApiKeys
|
|
tags:
|
|
- API Keys
|
|
responses:
|
|
"200":
|
|
description: The API keys, `{}` if there are none or for a read-only API key
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/ApiKey"
|
|
example:
|
|
- id: 1
|
|
description: API_KEY
|
|
access: rw
|
|
api_key: 8F2D41-0C9A7B-5E3F12-AB46C0-77D1E9
|
|
allow_from:
|
|
- 192.0.2.0/24
|
|
skip_ip_check: 0
|
|
service: 1
|
|
active: 1
|
|
created: "2026-09-21 10:20:00"
|
|
modified: null
|
|
- id: 3
|
|
description: provisioning
|
|
access: rw
|
|
api_key: 1B7E2C-94F0A3-6D5B18-C2E7F4-03A9D6
|
|
allow_from:
|
|
- 192.0.2.10
|
|
- 2001:db8::/64
|
|
skip_ip_check: 0
|
|
service: 0
|
|
active: 1
|
|
created: "2026-11-02 09:12:44"
|
|
modified: "2026-11-05 16:40:02"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/app-passwd/all/{mailbox}:
|
|
get:
|
|
tags:
|
|
- App Passwords
|
|
summary: Get the app passwords of a mailbox
|
|
operationId: getAppPasswords
|
|
description: >-
|
|
The app passwords of the mailbox, with password hashes. `{}` if none or
|
|
no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: List of app passwords
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/AppPassword"
|
|
example:
|
|
- id: 23
|
|
name: Thunderbird
|
|
mailbox: john.doe@example.org
|
|
domain: example.org
|
|
password: "{BLF-CRYPT}$2y$10$..."
|
|
created: "2026-11-08 20:38:01"
|
|
modified: null
|
|
imap_access: 1
|
|
smtp_access: 1
|
|
dav_access: 0
|
|
eas_access: 0
|
|
pop3_access: 0
|
|
sieve_access: 1
|
|
active: 1
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/app-passwd/all:
|
|
get:
|
|
tags:
|
|
- App Passwords
|
|
summary: Get the app passwords of the logged-in mailbox
|
|
operationId: getOwnAppPasswords
|
|
description: >-
|
|
The app passwords of the logged-in mailbox user. API keys get `{}`; use
|
|
`get/app-passwd/all/{mailbox}`.
|
|
responses:
|
|
"200":
|
|
description: List of app passwords
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/AppPassword"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/app-passwd/{id}:
|
|
get:
|
|
tags:
|
|
- App Passwords
|
|
summary: Get an app password (broken)
|
|
operationId: getAppPassword
|
|
description: >-
|
|
Broken: always ends with an error and an empty body. Use
|
|
`get/app-passwd/all/{mailbox}`.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: App password ID
|
|
schema:
|
|
type: integer
|
|
example: 23
|
|
responses:
|
|
"200":
|
|
description: Empty body
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/app-passwd:
|
|
post:
|
|
tags:
|
|
- App Passwords
|
|
summary: Update app passwords
|
|
operationId: editAppPassword
|
|
description: >-
|
|
Changes app passwords by ID; fields not sent keep their value. Needs
|
|
the user ACL `app_passwds`.
|
|
|
|
|
|
Messages: `object_modified`; errors `app_passwd_id_invalid`,
|
|
`password_complexity`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: App password ID or list of IDs
|
|
oneOf:
|
|
- type: integer
|
|
- type: array
|
|
items:
|
|
type: integer
|
|
attr:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Mailbox the app passwords belong to (required for API keys)
|
|
app_name:
|
|
type: string
|
|
app_passwd:
|
|
type: string
|
|
format: password
|
|
description: New password; changed only together with `app_passwd2`
|
|
app_passwd2:
|
|
type: string
|
|
format: password
|
|
protocols:
|
|
description: Replaces the allowed protocols
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- imap_access
|
|
- smtp_access
|
|
- pop3_access
|
|
- sieve_access
|
|
- dav_access
|
|
- eas_access
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
example:
|
|
items:
|
|
- 23
|
|
attr:
|
|
username: john.doe@example.org
|
|
active: 0
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/bcc/{id}:
|
|
get:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Get BCC maps
|
|
operationId: getBccMaps
|
|
description: >-
|
|
`all` lists the BCC maps of the domains the caller manages, an ID
|
|
returns one map with an extra member `"0": null`. `{}` if there is
|
|
none.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a BCC map"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of BCC maps (`all`) or one BCC map
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/BccMap"
|
|
- $ref: "#/components/schemas/BccMap"
|
|
examples:
|
|
all:
|
|
summary: get/bcc/all
|
|
value:
|
|
- id: 3
|
|
local_dest: "@example.org"
|
|
bcc_dest: archive@example.com
|
|
active: 1
|
|
type: rcpt
|
|
created: "2026-11-03 10:15:22"
|
|
domain: example.org
|
|
modified: null
|
|
one:
|
|
summary: get/bcc/3
|
|
value:
|
|
id: 3
|
|
local_dest: "@example.org"
|
|
bcc_dest: archive@example.com
|
|
active: 1
|
|
type: rcpt
|
|
created: "2026-11-03 10:15:22"
|
|
domain: example.org
|
|
modified: null
|
|
"0": null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/dkim/{domain}:
|
|
get:
|
|
summary: Get the DKIM key of a domain
|
|
description: >-
|
|
The DKIM public key of a domain or alias domain and the TXT record for
|
|
`<selector>._domainkey.<domain>`. `privkey` is empty unless
|
|
`SHOW_DKIM_PRIV_KEYS` is enabled.
|
|
operationId: getDkimKey
|
|
tags:
|
|
- DKIM
|
|
parameters:
|
|
- name: domain
|
|
in: path
|
|
required: true
|
|
description: Domain or alias domain name
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
responses:
|
|
"200":
|
|
description: The DKIM key
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DkimKey"
|
|
example:
|
|
pubkey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxV3...IDAQAB
|
|
length: "2048"
|
|
dkim_txt: v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxV3...IDAQAB
|
|
dkim_selector: dkim
|
|
privkey: ""
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/dkim_import:
|
|
post:
|
|
summary: Import a DKIM key
|
|
description: >-
|
|
Imports an RSA private key as the DKIM key of a domain, which need not
|
|
exist in mailcow. Success answers `dkim_removed` and `dkim_added`.
|
|
|
|
|
|
Messages: errors `private_key_error`, `dkim_domain_or_sel_exists`.
|
|
operationId: importDkimKey
|
|
tags:
|
|
- DKIM
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
- private_key_file
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain name
|
|
dkim_selector:
|
|
type: string
|
|
default: dkim
|
|
description: Selector (letters, digits, `-`, `_`, `.`)
|
|
private_key_file:
|
|
type: string
|
|
description: The private key in PEM format (the text, not a file upload)
|
|
overwrite_existing:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Replace an existing key of the domain
|
|
example:
|
|
domain: example.org
|
|
dkim_selector: dkim2026
|
|
private_key_file: "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC...\n-----END PRIVATE KEY-----"
|
|
overwrite_existing: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/domain-admin/all:
|
|
get:
|
|
summary: Get domain administrators
|
|
description: Lists all domain administrators.
|
|
operationId: getDomainAdmins
|
|
tags:
|
|
- Domain admin
|
|
responses:
|
|
"200":
|
|
description: The domain administrators, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/DomainAdmin"
|
|
example:
|
|
- username: domainadmin1
|
|
tfa_active: 0
|
|
tfa_active_int: 0
|
|
active: 1
|
|
active_int: 1
|
|
created: "2026-09-21 10:24:48"
|
|
attributes:
|
|
force_tfa: "0"
|
|
force_pw_update: "0"
|
|
selected_domains:
|
|
- example.org
|
|
unselected_domains:
|
|
- example.com
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/domain-admin/{username}:
|
|
get:
|
|
summary: Get domain administrator
|
|
description: Details of one domain administrator.
|
|
operationId: getDomainAdmin
|
|
tags:
|
|
- Domain admin
|
|
parameters:
|
|
- name: username
|
|
in: path
|
|
required: true
|
|
description: Username of the domain administrator
|
|
schema:
|
|
type: string
|
|
example: domainadmin1
|
|
responses:
|
|
"200":
|
|
description: The domain administrator, `{}` if there is none of this name
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DomainAdmin"
|
|
example:
|
|
username: domainadmin1
|
|
tfa_active: 0
|
|
tfa_active_int: 0
|
|
active: 1
|
|
active_int: 1
|
|
created: "2026-09-21 10:24:48"
|
|
attributes:
|
|
force_tfa: "0"
|
|
force_pw_update: "0"
|
|
selected_domains:
|
|
- example.org
|
|
- example.com
|
|
unselected_domains: ""
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/domain/{id}:
|
|
get:
|
|
summary: Get domains
|
|
description: >-
|
|
`all` lists all domains (`{}` if none), a domain name returns that
|
|
domain, an alias domain name its target. Domain admins see only their
|
|
domains. Quotas are in bytes.
|
|
operationId: getDomains
|
|
tags:
|
|
- Domains
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or a domain name"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
- name: tags
|
|
in: query
|
|
required: false
|
|
description: >-
|
|
Only with `all`: comma-separated tag names, answers only the domains
|
|
with a tag that contains one of them
|
|
schema:
|
|
type: string
|
|
example: customer,premium
|
|
responses:
|
|
"200":
|
|
description: The list of domains (`all`) or one domain
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/Domain"
|
|
- $ref: "#/components/schemas/Domain"
|
|
example:
|
|
- max_new_mailbox_quota: 10632560640
|
|
def_new_mailbox_quota: 3221225472
|
|
quota_used_in_domain: "104857600"
|
|
bytes_total: "79324302"
|
|
msgs_total: "132"
|
|
mboxes_in_domain: 3
|
|
mboxes_left: 7
|
|
domain_name: example.org
|
|
domain_h_name: example.org
|
|
description: Example Org
|
|
max_num_aliases_for_domain: 400
|
|
max_num_mboxes_for_domain: 10
|
|
def_quota_for_mbox: 3221225472
|
|
max_quota_for_mbox: 10737418240
|
|
max_quota_for_domain: 10737418240
|
|
relayhost: "0"
|
|
backupmx: 0
|
|
backupmx_int: 0
|
|
gal: 1
|
|
gal_int: 1
|
|
rl:
|
|
value: "100"
|
|
frame: h
|
|
active: 1
|
|
active_int: 1
|
|
relay_all_recipients: 0
|
|
relay_all_recipients_int: 0
|
|
relay_unknown_only: 0
|
|
relay_unknown_only_int: 0
|
|
created: "2026-09-21 10:24:34"
|
|
modified: "2026-11-06 18:15:08"
|
|
aliases_in_domain: 1
|
|
aliases_left: 399
|
|
domain_admins: anna.admin
|
|
tags:
|
|
- customer
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/domain/template/{id}:
|
|
get:
|
|
summary: Get domain templates
|
|
description: >-
|
|
`all` lists the domain templates, an ID returns that template. Domain
|
|
admins may call it too. Quotas are in bytes.
|
|
operationId: getDomainTemplates
|
|
tags:
|
|
- Domains
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or a template ID"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of templates (`all`) or one template
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/DomainTemplate"
|
|
- $ref: "#/components/schemas/DomainTemplate"
|
|
example:
|
|
- id: 1
|
|
template: Default
|
|
type: domain
|
|
attributes:
|
|
tags: []
|
|
max_num_aliases_for_domain: 400
|
|
max_num_mboxes_for_domain: 10
|
|
def_quota_for_mbox: 3221225472
|
|
max_quota_for_mbox: 10737418240
|
|
max_quota_for_domain: 10737418240
|
|
rl_frame: s
|
|
rl_value: ""
|
|
active: 1
|
|
gal: 1
|
|
backupmx: 0
|
|
relay_all_recipients: 0
|
|
relay_unknown_only: 0
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
created: "2026-09-21 10:23:08"
|
|
modified: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/domain/template:
|
|
post:
|
|
summary: Add a domain template
|
|
description: >-
|
|
Adds a domain template (defaults for new domains). Quotas are sent in
|
|
MiB, returned in bytes. Fields not sent, and numbers and quotas sent as
|
|
0, get the defaults shown.
|
|
|
|
|
|
Messages: `template_added`; errors `template_name_invalid`,
|
|
`template_exists`.
|
|
operationId: addDomainTemplate
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/DomainTemplateInput"
|
|
- required:
|
|
- template
|
|
example:
|
|
template: Small business
|
|
max_num_aliases_for_domain: 400
|
|
max_num_mboxes_for_domain: 25
|
|
def_quota_for_mbox: 2048
|
|
max_quota_for_mbox: 5120
|
|
max_quota_for_domain: 51200
|
|
rl_value: 500
|
|
rl_frame: h
|
|
active: 1
|
|
gal: 1
|
|
backupmx: 0
|
|
relay_all_recipients: 0
|
|
relay_unknown_only: 0
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
tags:
|
|
- small
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/domain/template:
|
|
post:
|
|
summary: Edit domain templates
|
|
description: >-
|
|
Replaces domain templates. Fields not sent are reset: numbers and quotas
|
|
to 0, the rest to the defaults shown. Edit one template per call, with
|
|
several IDs all get the first one's name. Always answers
|
|
`template_modified`, also for unknown IDs.
|
|
operationId: editDomainTemplate
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Template ID or list of template IDs
|
|
oneOf:
|
|
- type: [integer, string]
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
attr:
|
|
$ref: "#/components/schemas/DomainTemplateInput"
|
|
example:
|
|
items:
|
|
- 2
|
|
attr:
|
|
template: Small business
|
|
max_num_aliases_for_domain: 400
|
|
max_num_mboxes_for_domain: 50
|
|
def_quota_for_mbox: 2048
|
|
max_quota_for_mbox: 5120
|
|
max_quota_for_domain: 102400
|
|
rl_value: 500
|
|
rl_frame: h
|
|
active: 1
|
|
gal: 1
|
|
backupmx: 0
|
|
relay_all_recipients: 0
|
|
relay_unknown_only: 0
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
tags:
|
|
- small
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/domain/template:
|
|
post:
|
|
summary: Delete a domain template
|
|
description: >-
|
|
Deletes a domain template; only the first ID of the list is used. The
|
|
`Default` template cannot be deleted. Always answers
|
|
`template_removed`.
|
|
operationId: deleteDomainTemplate
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Template IDs (only the first is used)
|
|
items:
|
|
type: [integer, string]
|
|
example:
|
|
- 2
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/search/domain:
|
|
post:
|
|
summary: Search domains (table of the UI)
|
|
description: >-
|
|
Paging, sorting and searching for the DataTables domain table of the UI.
|
|
Read-only API keys may use it, domain admins see only their domains.
|
|
|
|
|
|
Positions in `columns` and `order[].column`: 2 domain name, 3 aliases,
|
|
4 mailboxes, 5 domain quota, 6 storage (sort only), 7 default mailbox
|
|
quota, 8 max. mailbox quota, 10 relay domain, 14 tags (global search
|
|
only), 15 active; others mean the domain name. `columns` is required
|
|
with `search.value`.
|
|
|
|
|
|
Without `Content-Type: application/json` all domains are returned. SQL
|
|
errors answer `{"error": "..."}` with status 200.
|
|
operationId: searchDomains
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DomainSearchRequest"
|
|
example:
|
|
draw: 1
|
|
start: 0
|
|
length: 10
|
|
search:
|
|
value: example
|
|
order:
|
|
- column: 2
|
|
dir: asc
|
|
columns:
|
|
- data: ""
|
|
searchable: false
|
|
orderable: false
|
|
- data: chkbox
|
|
searchable: false
|
|
orderable: false
|
|
- data: domain_h_name
|
|
searchable: true
|
|
orderable: true
|
|
search:
|
|
value: ""
|
|
responses:
|
|
"200":
|
|
description: One page of domains, with the counts DataTables needs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DomainSearchResult"
|
|
example:
|
|
draw: 1
|
|
recordsTotal: 12
|
|
recordsFiltered: 1
|
|
data:
|
|
- max_new_mailbox_quota: 10632560640
|
|
def_new_mailbox_quota: 3221225472
|
|
quota_used_in_domain: "104857600"
|
|
bytes_total: "79324302"
|
|
msgs_total: "132"
|
|
mboxes_in_domain: 3
|
|
mboxes_left: 7
|
|
domain_name: example.org
|
|
domain_h_name: example.org
|
|
description: Example Org
|
|
max_num_aliases_for_domain: 400
|
|
max_num_mboxes_for_domain: 10
|
|
def_quota_for_mbox: 3221225472
|
|
max_quota_for_mbox: 10737418240
|
|
max_quota_for_domain: 10737418240
|
|
relayhost: "0"
|
|
backupmx: 0
|
|
backupmx_int: 0
|
|
gal: 1
|
|
gal_int: 1
|
|
rl: false
|
|
active: 1
|
|
active_int: 1
|
|
relay_all_recipients: 0
|
|
relay_all_recipients_int: 0
|
|
relay_unknown_only: 0
|
|
relay_unknown_only_int: 0
|
|
created: "2026-09-21 10:24:34"
|
|
modified: "2026-11-06 18:15:08"
|
|
aliases_in_domain: 1
|
|
aliases_left: 399
|
|
domain_admins: "-"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/alias-domain/{id}:
|
|
get:
|
|
summary: Get alias domains
|
|
description: >-
|
|
`all` lists all alias domains, a name returns that alias domain. Domain
|
|
admins see only those of their domains.
|
|
operationId: getAliasDomains
|
|
tags:
|
|
- Domains
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or an alias domain name"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of alias domains (`all`) or one alias domain
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/AliasDomain"
|
|
- $ref: "#/components/schemas/AliasDomain"
|
|
example:
|
|
- alias_domain: example.net
|
|
parent_is_backupmx: 0
|
|
target_domain: example.org
|
|
active: 1
|
|
active_int: 1
|
|
rl: false
|
|
created: "2026-10-02 08:12:45"
|
|
modified: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/alias-domain:
|
|
post:
|
|
summary: Add alias domains
|
|
description: >-
|
|
Adds alias domains: mail goes to the same local part in the target
|
|
domain, which must be accessible and no relay domain. Needs the ACL
|
|
`alias_domains`. Can also set the rate limit and create a DKIM key. An
|
|
invalid name ends the call without an answer.
|
|
|
|
|
|
Messages: `aliasd_added`; errors `alias_domain_invalid`,
|
|
`targetd_not_found`, `targetd_relay_domain`.
|
|
operationId: addAliasDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- alias_domain
|
|
- target_domain
|
|
properties:
|
|
alias_domain:
|
|
type: string
|
|
description: >-
|
|
Alias domain name; several are separated by spaces, commas,
|
|
semicolons or line breaks
|
|
target_domain:
|
|
type: string
|
|
description: The domain the alias domain points to
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Alias domain active (inactive when not sent)
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Rate limit, messages per `rl_frame`; empty or 0 = none
|
|
rl_frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
description: Rate limit time frame
|
|
dkim_selector:
|
|
type: string
|
|
description: Selector of the DKIM key that is created
|
|
key_size:
|
|
type: [integer, string]
|
|
description: >-
|
|
RSA size of the new DKIM key in bits; a key needs
|
|
`key_size` and `dkim_selector`
|
|
example:
|
|
alias_domain: example.net
|
|
target_domain: example.org
|
|
active: 1
|
|
rl_value: 100
|
|
rl_frame: h
|
|
dkim_selector: dkim
|
|
key_size: 2048
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/alias-domain:
|
|
post:
|
|
summary: Edit alias domains
|
|
description: >-
|
|
Changes alias domains; fields not sent keep their value. The new target
|
|
must be an accessible domain, not an alias domain.
|
|
|
|
|
|
Messages: `aliasd_modified`; errors `alias_domain_invalid`,
|
|
`target_domain_invalid`.
|
|
operationId: editAliasDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Alias domain name or list of alias domain names
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Alias domain active
|
|
target_domain:
|
|
type: string
|
|
description: New target domain
|
|
example:
|
|
items:
|
|
- example.net
|
|
attr:
|
|
active: 1
|
|
target_domain: example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/alias-domain:
|
|
post:
|
|
summary: Delete alias domains
|
|
description: >-
|
|
Deletes alias domains with their aliases, spam aliases and BCC maps.
|
|
The rate limit is kept.
|
|
|
|
|
|
Messages: `alias_domain_removed`; error `domain_invalid`.
|
|
operationId: deleteAliasDomain
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Alias domain names
|
|
items:
|
|
type: string
|
|
example:
|
|
- example.net
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/mta-sts:
|
|
post:
|
|
summary: Add an MTA-STS policy
|
|
description: >-
|
|
Adds the MTA-STS policy of a domain, published when active at
|
|
`https://mta-sts.<domain>/.well-known/mta-sts.txt`. The `_mta-sts` TXT
|
|
record ID is the change time (`YYYYMMDDhhmmss`). Policies of alias
|
|
domains are never published, they use their target's. A second policy
|
|
fails with a database error. There is no read route.
|
|
|
|
|
|
Messages: errors `version_invalid`, `mode_invalid`, `max_age_invalid`,
|
|
`mx_invalid`.
|
|
operationId: addMtaSts
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- domain
|
|
- version
|
|
- mode
|
|
- mx
|
|
- max_age
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain or alias domain
|
|
version:
|
|
type: string
|
|
enum: [stsv1, STSv1]
|
|
description: Policy version (case-insensitive)
|
|
mode:
|
|
type: string
|
|
enum: [enforce, testing, none]
|
|
description: >-
|
|
`enforce` rejects delivery without valid TLS, `testing`
|
|
only reports, `none` publishes without effect
|
|
mx:
|
|
type: string
|
|
description: Comma-separated MX host names, wildcards like `*.example.org` allowed
|
|
max_age:
|
|
type: [integer, string]
|
|
description: Seconds senders may cache the policy, 1 to 31536000
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: Policy published (inactive when not sent)
|
|
example:
|
|
domain: example.org
|
|
version: stsv1
|
|
mode: enforce
|
|
mx: mail.example.org,mx2.example.org
|
|
max_age: 86400
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/mta-sts:
|
|
post:
|
|
summary: Edit MTA-STS policies
|
|
description: >-
|
|
Changes MTA-STS policies; fields not sent keep their value, but
|
|
`version` is required. Changing `version`, `mode`, `mx` or `max_age`
|
|
gives a new policy ID. A domain without policy answers `access_denied`.
|
|
|
|
|
|
Messages: `object_modified`; errors `version_invalid`, `mode_invalid`,
|
|
`mx_invalid`.
|
|
operationId: editMtaSts
|
|
tags:
|
|
- Domains
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Domain name or list of domain names
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
required:
|
|
- version
|
|
properties:
|
|
version:
|
|
type: string
|
|
enum: [stsv1, STSv1]
|
|
description: Policy version
|
|
mode:
|
|
type: string
|
|
enum: [enforce, testing, none]
|
|
description: Policy mode
|
|
mx:
|
|
type: string
|
|
description: Comma-separated MX host names
|
|
max_age:
|
|
type: [integer, string]
|
|
description: Seconds senders may cache the policy, 1 to 31557600
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
description: Policy published
|
|
example:
|
|
items:
|
|
- example.org
|
|
attr:
|
|
version: stsv1
|
|
mode: testing
|
|
mx: mail.example.org
|
|
max_age: 604800
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/fail2ban:
|
|
get:
|
|
summary: Get Fail2Ban settings and bans
|
|
description: >-
|
|
Returns the Fail2Ban settings, regex filters, allow- and denylists and
|
|
the current bans.
|
|
operationId: getFail2Ban
|
|
tags:
|
|
- Fail2Ban
|
|
responses:
|
|
"200":
|
|
description: Settings and bans
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Fail2Ban"
|
|
example:
|
|
ban_time: 1800
|
|
ban_time_increment: true
|
|
max_ban_time: 86400
|
|
netban_ipv4: 32
|
|
netban_ipv6: 128
|
|
max_attempts: 10
|
|
retry_window: 600
|
|
banlist_id: a2c11baf-5770-47de-9c5e-575bd7bc9218
|
|
manage_external: 0
|
|
regex:
|
|
"1": "^mailcow UI: Invalid password for .+ by ([0-9a-f\\.:]+)$"
|
|
"2": "^Rspamd UI: Invalid password by ([0-9a-f\\.:]+)$"
|
|
whitelist: |-
|
|
192.0.2.0/24
|
|
mail.example.org
|
|
blacklist: 198.51.100.66/32
|
|
perm_bans:
|
|
- network: 198.51.100.66/32
|
|
ip: 198.51.100.66
|
|
active_bans:
|
|
- queued_for_unban: 0
|
|
network: 203.0.113.7/32
|
|
ip: 203.0.113.7
|
|
banned_until: 00h 27m 08s
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/fail2ban/banlist:
|
|
post:
|
|
summary: Renew the Fail2Ban banlist URL
|
|
description: >-
|
|
Gives the banlist URL `/f2b-banlist?id=<banlist_id>` a new random ID;
|
|
the old URL stops working. `items` must hold the current `banlist_id`,
|
|
else the status is 404. A Redis error gives status 500.
|
|
|
|
|
|
Messages: `f2b_banlist_refreshed`; errors `redis_error`.
|
|
operationId: refreshFail2BanBanlist
|
|
tags:
|
|
- Fail2Ban
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: The current banlist ID (single value or a list with it as first element)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
attr:
|
|
type: object
|
|
description: Not used
|
|
required:
|
|
- items
|
|
example:
|
|
items:
|
|
- a2c11baf-5770-47de-9c5e-575bd7bc9218
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
description: "`items` does not hold the current banlist ID"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaskResult"
|
|
example:
|
|
type: error
|
|
msg: Cannot edit item
|
|
/api/v1/get/logs/acme/{count}:
|
|
get:
|
|
summary: Get ACME logs (count or range)
|
|
description: Entries of the ACME (Let's Encrypt) log, newest first.
|
|
operationId: getAcmeLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/AcmeLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/api/{count}:
|
|
get:
|
|
summary: Get API logs (count or range)
|
|
description: API requests with their data (secrets replaced by `*`), newest first.
|
|
operationId: getApiLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ApiLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/autodiscover/{count}:
|
|
get:
|
|
summary: Get Autodiscover logs (count or range)
|
|
description: Autodiscover requests (Outlook, ActiveSync) with the offered service, newest first.
|
|
operationId: getAutodiscoverLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/AutodiscoverLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/dovecot/{count}:
|
|
get:
|
|
summary: Get Dovecot logs (count or range)
|
|
description: Entries of the Dovecot log (IMAP, POP3, Sieve, LMTP), newest first.
|
|
operationId: getDovecotLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/DovecotLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/netfilter/{count}:
|
|
get:
|
|
summary: Get netfilter logs (count or range)
|
|
description: Entries of netfilter (failed logins, bans), newest first.
|
|
operationId: getNetfilterLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/NetfilterLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/postfix/{count}:
|
|
get:
|
|
summary: Get Postfix logs (count or range)
|
|
description: Entries of the Postfix log (SMTP), newest first.
|
|
operationId: getPostfixLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/PostfixLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/ratelimited/{count}:
|
|
get:
|
|
summary: Get rate limit logs (count or range)
|
|
description: Messages rejected by a rate limit, newest first.
|
|
operationId: getRatelimitLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/RatelimitLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/rspamd-history/{count}:
|
|
get:
|
|
summary: Get Rspamd history (count or range)
|
|
description: Messages scanned by Rspamd, newest first.
|
|
operationId: getRspamdHistoryByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: >-
|
|
`N`: the newest N messages; `from-to` (from ≥ 1) counts from 0, so
|
|
`2-3` gives the third and fourth newest
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/RspamdHistory"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/sogo/{count}:
|
|
get:
|
|
summary: Get SOGo logs (count or range)
|
|
description: Entries of the SOGo log, newest first.
|
|
operationId: getSogoLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/SogoLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/watchdog/{count}:
|
|
get:
|
|
summary: Get watchdog logs (count or range)
|
|
description: Watchdog health checks, newest first.
|
|
operationId: getWatchdogLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WatchdogLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/acme:
|
|
get:
|
|
summary: Get ACME logs
|
|
description: The newest 1000 entries of the ACME (Let's Encrypt) log, newest first.
|
|
operationId: getAcmeLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/AcmeLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/api:
|
|
get:
|
|
summary: Get API logs
|
|
description: >-
|
|
The newest 1000 API requests with their data (secrets replaced by
|
|
`*`), newest first.
|
|
operationId: getApiLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ApiLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/autodiscover:
|
|
get:
|
|
summary: Get Autodiscover logs
|
|
description: >-
|
|
The newest 1000 Autodiscover requests (Outlook, ActiveSync) with the
|
|
offered service, newest first.
|
|
operationId: getAutodiscoverLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/AutodiscoverLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/cron:
|
|
get:
|
|
summary: Get cron logs
|
|
description: >-
|
|
The newest 1000 entries of the mailcow scheduled tasks (identity
|
|
provider sync, group shares, ...), newest first.
|
|
operationId: getCronLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/CronLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/cron/{count}:
|
|
get:
|
|
summary: Get cron logs (count or range)
|
|
description: Entries of the mailcow scheduled tasks, newest first.
|
|
operationId: getCronLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)"
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/CronLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/dovecot:
|
|
get:
|
|
summary: Get Dovecot logs
|
|
description: The newest 1000 entries of the Dovecot log (IMAP, POP3, Sieve, LMTP), newest first.
|
|
operationId: getDovecotLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/DovecotLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/netfilter:
|
|
get:
|
|
summary: Get netfilter logs
|
|
description: The newest 1000 entries of netfilter (failed logins, bans), newest first.
|
|
operationId: getNetfilterLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/NetfilterLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/postfix:
|
|
get:
|
|
summary: Get Postfix logs
|
|
description: The newest 1000 entries of the Postfix log (SMTP), newest first.
|
|
operationId: getPostfixLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/PostfixLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/ratelimited:
|
|
get:
|
|
summary: Get rate limit logs
|
|
description: The newest 1000 messages rejected by a rate limit, newest first.
|
|
operationId: getRatelimitLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/RatelimitLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/rspamd-history:
|
|
get:
|
|
summary: Get Rspamd history
|
|
description: The newest 1000 messages scanned by Rspamd, newest first.
|
|
operationId: getRspamdHistory
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/RspamdHistory"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/rspamd-stats:
|
|
get:
|
|
summary: Get Rspamd statistics
|
|
description: Rspamd statistics (scanned and learned messages, actions, Bayes).
|
|
operationId: getRspamdStats
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
description: The statistics, `{}` if Rspamd cannot be reached
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/RspamdStats"
|
|
example:
|
|
version: 3.12.1
|
|
config_id: ch8ha1o68oxb3xf9izngisz4wxuxgs86n9gg6yko7jtt4msu4bxhuunnoi4pk7an4y5htzjb1y9nwsxmkjhdu671ocb5b5ea1g38csb
|
|
uptime: 25891
|
|
read_only: false
|
|
scanned: 300
|
|
learned: 30
|
|
actions:
|
|
reject: 38
|
|
soft reject: 0
|
|
rewrite subject: 0
|
|
add header: 6
|
|
greylist: 1
|
|
no action: 255
|
|
scan_times:
|
|
- 0.340365
|
|
- 0.48114
|
|
spam_count: 44
|
|
ham_count: 256
|
|
connections: 24
|
|
control_connections: 700
|
|
total_learns: 29
|
|
statfiles:
|
|
- revision: 6
|
|
users: 1
|
|
used: 0
|
|
total: 0
|
|
size: 0
|
|
symbol: BAYES_SPAM
|
|
type: redis
|
|
languages: 0
|
|
class: spam
|
|
fuzzy_hashes:
|
|
mailcow: 0
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/sasl:
|
|
get:
|
|
summary: Get SASL logs
|
|
description: >-
|
|
The newest 1000 successful logins (IMAP, POP3, SMTP, SOGo, ...), one
|
|
entry per service, address and user, newest first.
|
|
operationId: getSaslLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/SaslLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/sasl/{count}:
|
|
get:
|
|
summary: Get SASL logs (count or range)
|
|
description: >-
|
|
Successful logins, one entry per service, address and user, newest
|
|
first.
|
|
operationId: getSaslLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: >-
|
|
`N`: the newest N entries; `from-to`: `to` entries starting at
|
|
`from` (newest = 1), so `2-3` gives entries 2 to 4
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/SaslLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/sogo:
|
|
get:
|
|
summary: Get SOGo logs
|
|
description: The newest 1000 entries of the SOGo log, newest first.
|
|
operationId: getSogoLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/SogoLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/ui:
|
|
get:
|
|
summary: Get mailcow UI logs
|
|
description: The newest 1000 messages of UI and API calls, newest first.
|
|
operationId: getUiLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/UiLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/ui/{count}:
|
|
get:
|
|
summary: Get mailcow UI logs (count or range)
|
|
description: Messages of UI and API calls, newest first.
|
|
operationId: getUiLogsByCount
|
|
tags:
|
|
- Logs
|
|
parameters:
|
|
- name: count
|
|
in: path
|
|
required: true
|
|
description: >-
|
|
`N`: the newest N entries; `from-to`: `to` entries starting at
|
|
`from` (newest = 1), so `2-3` gives entries 2 to 4
|
|
schema:
|
|
type: string
|
|
pattern: ^[0-9]+(-[0-9]+)?$
|
|
example: "50"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/UiLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/logs/watchdog:
|
|
get:
|
|
summary: Get watchdog logs
|
|
description: The newest 1000 watchdog health checks, newest first.
|
|
operationId: getWatchdogLogs
|
|
tags:
|
|
- Logs
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WatchdogLogs"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/{id}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get a mailbox
|
|
operationId: getMailbox
|
|
description: >-
|
|
One mailbox, `{}` if not found or no access. A mailbox user may read
|
|
its own.
|
|
|
|
|
|
With `tags`, `{id}` is a search term: the answer lists the mailboxes
|
|
whose address contains `{id}` and that have a matching tag.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "Mailbox address (with `tags`: part of the address, e.g. a domain)"
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
- $ref: "#/components/parameters/MailboxTagsQuery"
|
|
responses:
|
|
"200":
|
|
description: The mailbox; with `tags` a list of mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- $ref: "#/components/schemas/Mailbox"
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
examples:
|
|
mailbox:
|
|
$ref: "#/components/examples/MailboxDetails"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox-group/{id}:
|
|
get:
|
|
summary: Get mailbox group
|
|
description: >-
|
|
One group by id, visible as in `GET /api/v1/get/mailbox-group/all`.
|
|
operationId: getMailboxGroup
|
|
tags:
|
|
- Groups
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Group id
|
|
schema:
|
|
type: integer
|
|
example: 7
|
|
responses:
|
|
"200":
|
|
description: The group
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxGroup"
|
|
example:
|
|
id: 7
|
|
domain: example.org
|
|
name: Sales
|
|
description: Sales team
|
|
address: sales@example.org
|
|
sender_allowed: 1
|
|
sogo_visible: 0
|
|
internal: 1
|
|
template_id: 3
|
|
template: Staff
|
|
priority: 10
|
|
idp_ref: null
|
|
members:
|
|
- username: alice@example.org
|
|
source: manual
|
|
send_as:
|
|
- "@example.com"
|
|
imap_grants: []
|
|
sogo_grants: []
|
|
active: 1
|
|
created: "2026-10-25 12:00:00"
|
|
modified: null
|
|
can_edit: true
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox-group/member/{username}:
|
|
get:
|
|
summary: Get group memberships of a mailbox
|
|
description: >-
|
|
The groups of a mailbox with its effective template and send-as
|
|
addresses. Domain admins with the `mailbox_groups` ACL may read their
|
|
mailboxes and see only groups of their domains; users may read their
|
|
own.
|
|
operationId: getMailboxGroupMemberships
|
|
tags:
|
|
- Groups
|
|
parameters:
|
|
- name: username
|
|
in: path
|
|
required: true
|
|
description: Mailbox (case-insensitive)
|
|
schema:
|
|
type: string
|
|
example: alice@example.org
|
|
responses:
|
|
"200":
|
|
description: The memberships
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxGroupMemberships"
|
|
example:
|
|
groups:
|
|
- id: 7
|
|
domain: example.org
|
|
name: Sales
|
|
address: sales@example.org
|
|
sender_allowed: 1
|
|
active: 1
|
|
priority: 10
|
|
template: Staff
|
|
source: manual
|
|
template: Staff
|
|
send_as:
|
|
- orders@example.org
|
|
- sales@example.org
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox-group/all:
|
|
get:
|
|
summary: Get mailbox groups
|
|
description: >-
|
|
All groups the caller may see, ordered by domain and name. Domain admins
|
|
with the `mailbox_groups` ACL get the groups of their domains.
|
|
operationId: getMailboxGroups
|
|
tags:
|
|
- Groups
|
|
responses:
|
|
"200":
|
|
description: The groups
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailboxGroup"
|
|
example:
|
|
- id: 7
|
|
domain: example.org
|
|
name: Sales
|
|
description: Sales team
|
|
address: sales@example.org
|
|
sender_allowed: 1
|
|
sogo_visible: 0
|
|
internal: 0
|
|
template_id: 3
|
|
template: Staff
|
|
priority: 10
|
|
idp_ref: null
|
|
members:
|
|
- username: alice@example.org
|
|
source: manual
|
|
- username: bob@example.org
|
|
source: idp
|
|
send_as:
|
|
- orders@example.org
|
|
imap_grants:
|
|
- owner: shared@example.org
|
|
rights: write
|
|
subscribe: 1
|
|
state: applied
|
|
last_error: null
|
|
sogo_grants:
|
|
- owner: shared@example.org
|
|
type: Calendar
|
|
folder: personal
|
|
access: read
|
|
subscribe: 0
|
|
state: pending
|
|
last_error: null
|
|
active: 1
|
|
created: "2026-10-25 12:00:00"
|
|
modified: "2026-10-28 09:14:03"
|
|
can_edit: true
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox-group/all/{domains}:
|
|
get:
|
|
summary: Get mailbox groups of domains
|
|
description: >-
|
|
Like `GET /api/v1/get/mailbox-group/all`, limited to the given domains.
|
|
operationId: getMailboxGroupsOfDomains
|
|
tags:
|
|
- Groups
|
|
parameters:
|
|
- name: domains
|
|
in: path
|
|
required: true
|
|
description: One domain or a comma-separated list of domains
|
|
schema:
|
|
type: string
|
|
example: example.org,example.com
|
|
responses:
|
|
"200":
|
|
description: The groups of the domains
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailboxGroup"
|
|
example:
|
|
- id: 7
|
|
domain: example.org
|
|
name: Sales
|
|
description: ""
|
|
address: sales@example.org
|
|
sender_allowed: 1
|
|
sogo_visible: 1
|
|
internal: 0
|
|
template_id: null
|
|
template: null
|
|
priority: 0
|
|
idp_ref: null
|
|
members:
|
|
- username: alice@example.org
|
|
source: manual
|
|
send_as: []
|
|
imap_grants: []
|
|
sogo_grants: []
|
|
active: 1
|
|
created: "2026-10-25 12:00:00"
|
|
modified: null
|
|
can_edit: true
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/identity-provider/sync-status:
|
|
get:
|
|
summary: Get identity sync status
|
|
description: >-
|
|
Status of the identity sync: provider, mailbox counts and the last 10
|
|
runs. Runs with status `blocked` (stopped by `offboarding_limit`) or
|
|
`error` changed nothing.
|
|
operationId: getIdentitySyncStatus
|
|
tags:
|
|
- Identity Provider
|
|
responses:
|
|
"200":
|
|
description: The sync status
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/IdentitySyncStatus"
|
|
example:
|
|
provider: keycloak
|
|
can_sync: true
|
|
sync_enabled: true
|
|
counts:
|
|
accounts: 120
|
|
linked: 118
|
|
idp_disabled: 2
|
|
missing: 1
|
|
runs:
|
|
- id: 42
|
|
provider: keycloak
|
|
mode: run
|
|
status: ok
|
|
requested_by: ""
|
|
created: "2026-11-09 12:00:00"
|
|
started: "2026-11-09 12:00:01"
|
|
finished: "2026-11-09 12:00:03"
|
|
summary:
|
|
counts:
|
|
links: 0
|
|
creates: 1
|
|
deactivate: 1
|
|
restore: 0
|
|
release: 0
|
|
missing: 1
|
|
found: 0
|
|
updates: 3
|
|
group_creates: 0
|
|
group_renames: 0
|
|
memberships: 2
|
|
orphaned_groups: 0
|
|
conflicts: 0
|
|
membership_removals: 0
|
|
skipped: 0
|
|
errors: 0
|
|
details:
|
|
creates:
|
|
- new.user@example.org
|
|
deactivate:
|
|
- left.user@example.org
|
|
restore: []
|
|
missing:
|
|
- left.user@example.org
|
|
group_creates: []
|
|
conflicts: []
|
|
blocked: false
|
|
errors: []
|
|
mode: run
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/identity-link/{username}:
|
|
get:
|
|
summary: Get identity link of a mailbox
|
|
description: >-
|
|
The Identity Provider user a mailbox is linked to. Domain admins may
|
|
read their mailboxes. A never linked mailbox that the sync misses at the
|
|
provider has `missing_since` but no `external_id`.
|
|
operationId: getIdentityLink
|
|
tags:
|
|
- Identity Provider
|
|
parameters:
|
|
- name: username
|
|
in: path
|
|
required: true
|
|
description: Mailbox (case-insensitive)
|
|
schema:
|
|
type: string
|
|
example: alice@example.org
|
|
responses:
|
|
"200":
|
|
description: The link
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/IdentityLink"
|
|
example:
|
|
provider: keycloak
|
|
external_id: 8d5da28d-7541-428b-8356-a9704f73e7f4
|
|
idp_disabled: 0
|
|
missing_since: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailq/all:
|
|
get:
|
|
summary: Get the mail queue
|
|
description: >-
|
|
Returns the Postfix mail queue, at most 10000 entries.
|
|
operationId: getMailQueue
|
|
tags:
|
|
- Queue Manager
|
|
responses:
|
|
"200":
|
|
description: List of queued messages
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailQueueItem"
|
|
example:
|
|
- queue_name: deferred
|
|
queue_id: B98C6260CA1
|
|
arrival_time: 1762768034
|
|
message_size: 1848
|
|
forced_expire: false
|
|
sender: sender@example.org
|
|
recipients:
|
|
- "rcpt@example.com (connect to mx.example.com[192.0.2.25]:25: Connection timed out)"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/postcat/{qid}:
|
|
get:
|
|
summary: Get a queued message
|
|
description: >-
|
|
Returns a queued message as postcat prints it: envelope, headers and
|
|
body. The answer is plain text despite the JSON content type. An
|
|
unknown queue ID gives the error text of postcat.
|
|
operationId: getQueuedMessage
|
|
tags:
|
|
- Queue Manager
|
|
parameters:
|
|
- name: qid
|
|
in: path
|
|
required: true
|
|
description: Postfix queue ID
|
|
schema:
|
|
type: string
|
|
example: B98C6260CA1
|
|
responses:
|
|
"200":
|
|
description: The postcat output as plain text (despite the JSON content type)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: |
|
|
*** ENVELOPE RECORDS deferred/B/B98C6260CA1 ***
|
|
message_size: 1848 612 1 0 1848 0
|
|
message_arrival_time: Mon Nov 10 09:47:14 2026
|
|
create_time: Mon Nov 10 09:47:14 2026
|
|
named_attribute: rewrite_context=local
|
|
sender: sender@example.org
|
|
*** MESSAGE CONTENTS deferred/B/B98C6260CA1 ***
|
|
From: Sender <sender@example.org>
|
|
To: rcpt@example.com
|
|
Subject: Test
|
|
|
|
Hello
|
|
*** HEADER EXTRACTED deferred/B/B98C6260CA1 ***
|
|
original_recipient: rcpt@example.com
|
|
recipient: rcpt@example.com
|
|
*** MESSAGE FILE END deferred/B/B98C6260CA1 ***
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/oauth2-client/{id}:
|
|
get:
|
|
summary: Get OAuth2 client
|
|
description: One OAuth2 client with its secret.
|
|
operationId: getOAuth2Client
|
|
tags:
|
|
- oAuth Clients
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: ID of the client (`id`, not `client_id`)
|
|
schema:
|
|
type: integer
|
|
example: 1
|
|
responses:
|
|
"200":
|
|
description: The client, `{}` if there is none with this ID
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OAuth2Client"
|
|
example:
|
|
id: 1
|
|
client_id: 17c76aaa88c0
|
|
client_secret: 73fc668a88147e32a31ff80c
|
|
redirect_uri: https://app.example.org/oauth/callback
|
|
grant_types: null
|
|
scope: profile
|
|
user_id: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/oauth2-client/all:
|
|
get:
|
|
summary: Get OAuth2 clients
|
|
description: >-
|
|
Lists the clients of the mailcow OAuth2 server with their secrets.
|
|
operationId: getOAuth2Clients
|
|
tags:
|
|
- oAuth Clients
|
|
responses:
|
|
"200":
|
|
description: The clients, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/OAuth2Client"
|
|
example:
|
|
- id: 1
|
|
client_id: 17c76aaa88c0
|
|
client_secret: 73fc668a88147e32a31ff80c
|
|
redirect_uri: https://app.example.org/oauth/callback
|
|
grant_types: null
|
|
scope: profile
|
|
user_id: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/oauth2-client:
|
|
post:
|
|
summary: Edit OAuth2 clients
|
|
description: >-
|
|
Per client, `revoke_tokens` deletes its tokens, else `renew_secret`
|
|
sets a new secret, else `redirect_uri` is changed. The first two act
|
|
whenever present, even with value 0.
|
|
|
|
|
|
Messages: `object_modified`; error `Redirect/Callback URL cannot be
|
|
empty`.
|
|
operationId: editOAuth2Client
|
|
tags:
|
|
- oAuth Clients
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: ID of the client, or a list of IDs
|
|
oneOf:
|
|
- type: [integer, string]
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
redirect_uri:
|
|
type: string
|
|
description: New redirect URL; empty or missing keeps the current one
|
|
revoke_tokens:
|
|
type: [integer, string, boolean]
|
|
description: Present = delete the access and refresh tokens of the client
|
|
renew_secret:
|
|
type: [integer, string, boolean]
|
|
description: Present = generate a new client secret
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 1
|
|
attr:
|
|
redirect_uri: https://app.example.org/oauth/callback2
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/policy_bl_domain/{domain}:
|
|
get:
|
|
summary: Get the sender deny list of a domain
|
|
description: >-
|
|
The deny list (blacklist) entries of the domain and all its mailboxes;
|
|
`object` tells which.
|
|
operationId: getDomainBlacklist
|
|
tags:
|
|
- Domain antispam policies
|
|
parameters:
|
|
- name: domain
|
|
in: path
|
|
required: true
|
|
description: Domain name
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
responses:
|
|
"200":
|
|
description: The deny list entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/DomainPolicyEntry"
|
|
example:
|
|
- object: example.org
|
|
value: "*@spam.example.com"
|
|
prefid: 13
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/policy_wl_domain/{domain}:
|
|
get:
|
|
summary: Get the sender allow list of a domain
|
|
description: >-
|
|
The allow list (whitelist) entries of the domain and all its
|
|
mailboxes; `object` tells which.
|
|
operationId: getDomainWhitelist
|
|
tags:
|
|
- Domain antispam policies
|
|
parameters:
|
|
- name: domain
|
|
in: path
|
|
required: true
|
|
description: Domain name
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
responses:
|
|
"200":
|
|
description: The allow list entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/DomainPolicyEntry"
|
|
example:
|
|
- object: example.org
|
|
value: "*@partner.example.com"
|
|
prefid: 12
|
|
- object: anna@example.org
|
|
value: newsletter@example.net
|
|
prefid: 15
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/quarantine/all:
|
|
get:
|
|
summary: Get quarantined messages
|
|
description: >-
|
|
Returns the quarantined messages without content. Admins get every
|
|
item, domain admins those of their domains, mailbox users their own.
|
|
operationId: getQuarantine
|
|
tags:
|
|
- Quarantine
|
|
responses:
|
|
"200":
|
|
description: List of quarantine items
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/QuarantineItem"
|
|
example:
|
|
- id: 33
|
|
qid: 8224615004C1
|
|
subject: You have won
|
|
virus_flag: 0
|
|
score: 15.48
|
|
rcpt: john.doe@example.org
|
|
sender: bounces@send.example.com
|
|
action: reject
|
|
created: 1762768034
|
|
notified: 1
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/quarantine_category:
|
|
post:
|
|
tags:
|
|
- Quarantine
|
|
summary: Set the quarantine notification category of mailboxes
|
|
operationId: editQuarantineCategory
|
|
description: >-
|
|
Which quarantined mail the notifications list: rejected (`reject`),
|
|
sent to junk (`add_header`) or both (`all`). Needs the user ACL
|
|
`quarantine_category`; a mailbox user may change only its own. An
|
|
invalid value answers `access_denied`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
required:
|
|
- quarantine_category
|
|
properties:
|
|
quarantine_category:
|
|
type: string
|
|
enum:
|
|
- reject
|
|
- add_header
|
|
- all
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
quarantine_category: all
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/quarantine/{id}:
|
|
get:
|
|
summary: Get a quarantined message
|
|
description: >-
|
|
Returns one quarantine item with the raw message and the Rspamd
|
|
symbols. Domain admins and mailbox users only get their own items.
|
|
`[]` for an unknown ID.
|
|
operationId: getQuarantineItem
|
|
tags:
|
|
- Quarantine
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: ID of the quarantine item
|
|
schema:
|
|
type: string
|
|
example: "33"
|
|
responses:
|
|
"200":
|
|
description: The quarantine item
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/QuarantineItemDetails"
|
|
example:
|
|
id: 33
|
|
qid: 8224615004C1
|
|
subject: You have won
|
|
score: 15.48
|
|
ip: 198.51.100.23
|
|
action: reject
|
|
symbols: '[{"name":"BAYES_SPAM","score":5.1,"options":["99.99%"]},{"name":"RBL_SPAMHAUS_SBL","score":4.0}]'
|
|
fuzzy_hashes: "[]"
|
|
sender: bounces@send.example.com
|
|
rcpt: john.doe@example.org
|
|
msg: "Return-Path: <bounces@send.example.com>\r\nFrom: Prize <bounces@send.example.com>\r\nTo: john.doe@example.org\r\nSubject: You have won\r\n\r\nClick here\r\n"
|
|
domain: null
|
|
notified: 1
|
|
created: "2026-11-10 09:47:14"
|
|
user: unknown
|
|
qhash: 3f9d8c0b2a4e6f1d7c5b9a8e0f2d4c6b8a1e3f5d7c9b0a2e4f6d8c1b3a5e7f9d
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/quarantine:
|
|
post:
|
|
summary: Edit quarantine settings
|
|
description: >-
|
|
Saves the global quarantine settings. Fields not sent are reset; a
|
|
missing `retention_size` or `max_size` turns the quarantine off. The
|
|
current values cannot be read through the API.
|
|
|
|
|
|
Messages: `saved_settings`; errors `redis_error`.
|
|
operationId: editQuarantineSettings
|
|
tags:
|
|
- Quarantine
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Ignored
|
|
attr:
|
|
type: object
|
|
properties:
|
|
action:
|
|
type: string
|
|
const: settings
|
|
retention_size:
|
|
type: [integer, string]
|
|
description: Items kept per mailbox; 0 disables the quarantine
|
|
max_size:
|
|
type: [integer, string]
|
|
description: Maximum size in MiB of a quarantined message; 0 disables the quarantine
|
|
max_score:
|
|
type: [number, string]
|
|
description: No notification for messages with a higher spam score; empty = no limit
|
|
max_age:
|
|
type: [integer, string]
|
|
description: Days an item is kept; 0 or less becomes 365
|
|
release_format:
|
|
type: string
|
|
enum:
|
|
- raw
|
|
- attachment
|
|
default: raw
|
|
description: Deliver released messages as they are or as an attachment of a new message
|
|
exclude_domains:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Domains and alias domains whose mail is not quarantined
|
|
sender:
|
|
type: string
|
|
description: Sender of the notifications (invalid address = empty)
|
|
subject:
|
|
type: string
|
|
description: Subject of the notifications
|
|
bcc:
|
|
type: string
|
|
description: Address that gets a copy of every notification (invalid address = empty)
|
|
redirect:
|
|
type: string
|
|
description: Address that gets all notifications instead of the mailboxes (invalid address = empty)
|
|
html_tmpl:
|
|
type: string
|
|
description: HTML template of the notifications (empty = the default template)
|
|
required:
|
|
- action
|
|
required:
|
|
- attr
|
|
example:
|
|
items:
|
|
- self
|
|
attr:
|
|
action: settings
|
|
retention_size: "20"
|
|
max_size: "15"
|
|
max_score: ""
|
|
max_age: "365"
|
|
release_format: raw
|
|
exclude_domains:
|
|
- example.com
|
|
sender: quarantine@example.org
|
|
subject: Spam Quarantine Notification
|
|
bcc: ""
|
|
redirect: ""
|
|
html_tmpl: ""
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/recipient_map/{id}:
|
|
get:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Get recipient maps
|
|
operationId: getRecipientMaps
|
|
description: >-
|
|
`all` lists the recipient maps, an ID returns one map with an extra
|
|
member `"0": null`. `{}` if there is none or the caller is no
|
|
administrator.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a recipient map"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of recipient maps (`all`) or one recipient map
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/RecipientMap"
|
|
- $ref: "#/components/schemas/RecipientMap"
|
|
examples:
|
|
all:
|
|
summary: get/recipient_map/all
|
|
value:
|
|
- id: 1
|
|
recipient_map_old: jane.doe@example.org
|
|
recipient_map_new: jane.smith@example.org
|
|
active: 1
|
|
created: "2026-11-04 08:30:00"
|
|
modified: null
|
|
- id: 2
|
|
recipient_map_old: "@example.net"
|
|
recipient_map_new: "@example.org"
|
|
active: 0
|
|
created: "2026-11-04 08:31:12"
|
|
modified: "2026-11-05 17:02:45"
|
|
one:
|
|
summary: get/recipient_map/1
|
|
value:
|
|
id: 1
|
|
recipient_map_old: jane.doe@example.org
|
|
recipient_map_new: jane.smith@example.org
|
|
active: 1
|
|
created: "2026-11-04 08:30:00"
|
|
modified: null
|
|
"0": null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/bcc:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Update BCC maps
|
|
operationId: editBccMap
|
|
description: >-
|
|
Changes the BCC maps in `items`; fields not sent keep their value,
|
|
`local_dest` cannot be changed. Same callers as add/bcc. `type` is not
|
|
validated: send only `sender` or `rcpt`.
|
|
|
|
|
|
Messages: `bcc_edited`; errors `bcc_must_be_email`, `bcc_exists`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs of the BCC maps, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
bcc_dest:
|
|
type: string
|
|
description: E-mail address that gets the copies
|
|
type:
|
|
type: string
|
|
enum:
|
|
- sender
|
|
- rcpt
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 3
|
|
attr:
|
|
bcc_dest: journal@example.com
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/recipient_map:
|
|
post:
|
|
tags:
|
|
- Address Rewriting
|
|
summary: Update recipient maps
|
|
operationId: editRecipientMap
|
|
description: >-
|
|
Changes the recipient maps in `items`; fields not sent keep their
|
|
value. `recipient_map_entry_exists` stops the call.
|
|
|
|
|
|
Messages: `recipient_map_entry_saved`; errors
|
|
`invalid_recipient_map_old`, `invalid_recipient_map_new`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs of the recipient maps, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
recipient_map_old:
|
|
type: string
|
|
description: Original recipient, an e-mail address or a domain
|
|
recipient_map_new:
|
|
type: string
|
|
description: New recipient, an e-mail address or a domain
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 1
|
|
attr:
|
|
recipient_map_new: jane.smith@example.org
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/relayhost/{id}:
|
|
get:
|
|
tags:
|
|
- Routing
|
|
summary: Get sender-dependent transports
|
|
operationId: getRelayhosts
|
|
description: >-
|
|
`all` lists the sender-dependent transports, an ID returns one; the
|
|
password is in clear text. `{}` if there is none or the caller is no
|
|
administrator.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a sender-dependent transport"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of sender-dependent transports (`all`) or one entry
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/Relayhost"
|
|
- $ref: "#/components/schemas/Relayhost"
|
|
examples:
|
|
all:
|
|
summary: get/relayhost/all
|
|
value:
|
|
- id: 1
|
|
hostname: "[smtp.example.com]:587"
|
|
username: relay-user@example.com
|
|
password: Secret-Passphrase-42
|
|
active: 1
|
|
password_short: Sec...
|
|
used_by_domains: example.org, example.net
|
|
used_by_mailboxes: anna@example.com
|
|
one:
|
|
summary: get/relayhost/1
|
|
value:
|
|
id: 1
|
|
hostname: "[smtp.example.com]:587"
|
|
username: relay-user@example.com
|
|
password: Secret-Passphrase-42
|
|
active: 1
|
|
password_short: Sec...
|
|
used_by_domains: example.org, example.net
|
|
used_by_mailboxes: anna@example.com
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/resource/all:
|
|
get:
|
|
tags:
|
|
- Resources
|
|
summary: Get all resources
|
|
operationId: getResources
|
|
description: >-
|
|
All resources of the domains the caller manages, `{}` if none.
|
|
responses:
|
|
"200":
|
|
description: List of resources
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Resource"
|
|
example:
|
|
- name: MeetingRoom1@example.org
|
|
kind: location
|
|
multiple_bookings: 0
|
|
description: Meeting Room 1
|
|
active: 1
|
|
active_int: 1
|
|
domain: example.org
|
|
local_part: MeetingRoom1
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/resource/{id}:
|
|
get:
|
|
tags:
|
|
- Resources
|
|
summary: Get a resource
|
|
operationId: getResource
|
|
description: >-
|
|
One resource by address, `{}` if not found or no access.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Address of the resource
|
|
schema:
|
|
type: string
|
|
example: MeetingRoom1@example.org
|
|
responses:
|
|
"200":
|
|
description: The resource
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Resource"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/resource:
|
|
post:
|
|
tags:
|
|
- Resources
|
|
summary: Update resources
|
|
operationId: editResource
|
|
description: >-
|
|
Changes resources, also for domain admins; fields not sent keep their
|
|
value. The address does not change with the description.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Resource address or list of addresses
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
description:
|
|
type: string
|
|
description: Name shown in SOGo
|
|
kind:
|
|
type: string
|
|
enum:
|
|
- location
|
|
- group
|
|
- thing
|
|
multiple_bookings:
|
|
type: [integer, string]
|
|
description: 0 always free, -1 unlimited but busy when booked, n ≥ 1 at most n overlapping bookings
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
example:
|
|
items:
|
|
- MeetingRoom1@example.org
|
|
attr:
|
|
description: Meeting Room 1 (2nd floor)
|
|
multiple_bookings: -1
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/rl-mbox/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Ratelimits
|
|
summary: Get the rate limit of a mailbox
|
|
operationId: getMailboxRatelimit
|
|
description: >-
|
|
The rate limit set on the mailbox; `{}` if it has none (the domain
|
|
limit applies) or no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: The rate limit
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxRatelimit"
|
|
example:
|
|
value: "100"
|
|
frame: h
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/rl-domain/{domain}:
|
|
get:
|
|
summary: Get rate limits of domains
|
|
description: >-
|
|
Rate limit (outgoing messages per time frame) of a domain or alias
|
|
domain; `all` lists all that have one.
|
|
operationId: getDomainRatelimits
|
|
tags:
|
|
- Ratelimits
|
|
parameters:
|
|
- name: domain
|
|
in: path
|
|
required: true
|
|
description: "`all` or a domain or alias domain name"
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
responses:
|
|
"200":
|
|
description: The rate limit, or the list of rate limits (`all`)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- $ref: "#/components/schemas/DomainRatelimit"
|
|
- type: array
|
|
items:
|
|
allOf:
|
|
- $ref: "#/components/schemas/DomainRatelimit"
|
|
- type: object
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain or alias domain
|
|
example:
|
|
value: "100"
|
|
frame: h
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/rl-domain:
|
|
post:
|
|
summary: Set rate limits of domains
|
|
description: >-
|
|
Sets the rate limit of domains or alias domains. Needs the ACL
|
|
`ratelimit`. `rl_frame` is required also when removing the limit.
|
|
|
|
|
|
Messages: `rl_saved`; error `rl_timeframe`.
|
|
operationId: editDomainRatelimits
|
|
tags:
|
|
- Ratelimits
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Domain or alias domain name, or a list of them
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
required:
|
|
- rl_frame
|
|
properties:
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Messages per `rl_frame`; empty or 0 removes the limit
|
|
rl_frame:
|
|
type: string
|
|
enum: [s, m, h, d]
|
|
description: Time frame (second, minute, hour, day)
|
|
example:
|
|
items:
|
|
- example.org
|
|
attr:
|
|
rl_value: 100
|
|
rl_frame: h
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/rl-mbox/all:
|
|
get:
|
|
tags:
|
|
- Ratelimits
|
|
summary: Get the rate limits of all mailboxes
|
|
operationId: getMailboxRatelimits
|
|
description: >-
|
|
The rate limits set on single mailboxes the caller manages (no domain
|
|
limits). `{}` if none.
|
|
responses:
|
|
"200":
|
|
description: List of rate limits
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
allOf:
|
|
- $ref: "#/components/schemas/MailboxRatelimit"
|
|
- type: object
|
|
properties:
|
|
mailbox:
|
|
type: string
|
|
example:
|
|
- value: "100"
|
|
frame: h
|
|
mailbox: john.doe@example.org
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/rl-mbox:
|
|
post:
|
|
tags:
|
|
- Ratelimits
|
|
summary: Set the rate limit of mailboxes
|
|
operationId: editMailboxRatelimit
|
|
description: >-
|
|
Sets the rate limit of mailboxes: `rl_value` messages per `rl_frame`. 0
|
|
or empty removes it, but `rl_frame` must still be valid. Domain admins
|
|
need the ACL `ratelimit`. Answers `rl_saved` or `rl_timeframe`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
required:
|
|
- rl_frame
|
|
properties:
|
|
rl_value:
|
|
type: [integer, string]
|
|
description: Number of messages, 0 or empty removes the limit
|
|
rl_frame:
|
|
type: string
|
|
enum:
|
|
- s
|
|
- m
|
|
- h
|
|
- d
|
|
description: Per second, minute, hour or day
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
rl_value: 100
|
|
rl_frame: h
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/rlhash:
|
|
post:
|
|
tags:
|
|
- Ratelimits
|
|
summary: Reset a rate limit counter
|
|
operationId: deleteRatelimitHash
|
|
description: >-
|
|
Resets the counter of a rate-limited sender (`rl_hash` from
|
|
`get/logs/ratelimited`) so it can send again. Send one hash. Answers
|
|
`1` (not JSON) when deleted, else an empty body.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: The hash
|
|
items:
|
|
type: string
|
|
pattern: "^RL[0-9A-Za-z=]+$"
|
|
example:
|
|
- RLkfx5cv4sq1i3ehpkz5bgdhcq9u9gkzj
|
|
responses:
|
|
"200":
|
|
description: "`1` if deleted, else an empty body"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: integer
|
|
const: 1
|
|
example: 1
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/status/containers:
|
|
get:
|
|
summary: Get container status
|
|
description: State, start time and image of all mailcow containers (also stopped ones).
|
|
operationId: getContainerStatus
|
|
tags:
|
|
- Status
|
|
responses:
|
|
"200":
|
|
description: The containers, `null` if dockerapi cannot be reached
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties:
|
|
$ref: "#/components/schemas/ContainerStatus"
|
|
example:
|
|
dovecot-mailcow:
|
|
type: info
|
|
container: dovecot-mailcow
|
|
state: running
|
|
started_at: "2026-11-10T11:00:51.541059812Z"
|
|
image: ghcr.io/mailcow/dovecot:2.3.21.1-4
|
|
postfix-mailcow:
|
|
type: info
|
|
container: postfix-mailcow
|
|
state: running
|
|
started_at: "2026-11-10T11:00:51.292779901Z"
|
|
image: ghcr.io/mailcow/postfix:1.80
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/status/vmail:
|
|
get:
|
|
summary: Get mail storage status
|
|
description: Disk usage of the file system that holds the mail storage.
|
|
operationId: getVmailStatus
|
|
tags:
|
|
- Status
|
|
responses:
|
|
"200":
|
|
description: The disk usage (`df -H` values)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
type:
|
|
type: string
|
|
const: info
|
|
disk:
|
|
type: string
|
|
description: Device
|
|
used:
|
|
type: string
|
|
description: Used space
|
|
total:
|
|
type: string
|
|
description: Size of the file system
|
|
used_percent:
|
|
type: string
|
|
description: Used space in percent
|
|
example:
|
|
type: info
|
|
disk: /dev/sda1
|
|
used: 65G
|
|
total: 105G
|
|
used_percent: 66%
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/status/version:
|
|
get:
|
|
summary: Get mailcow version
|
|
description: The installed mailcow version, the release tag on master, else the short commit ID.
|
|
operationId: getVersion
|
|
tags:
|
|
- Status
|
|
responses:
|
|
"200":
|
|
description: The version
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
version:
|
|
type: [string, "null"]
|
|
description: Release tag or commit ID
|
|
example:
|
|
version: "2026-11"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/status/container/{id}:
|
|
get:
|
|
summary: Get container statistics
|
|
description: >-
|
|
Up to three Docker stats snapshots of one container, about five
|
|
seconds apart. Needs the full container ID, which the API does not
|
|
list; an unknown ID answers after 60 seconds with an error string.
|
|
operationId: getContainerStats
|
|
tags:
|
|
- Status
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Full Docker container ID
|
|
schema:
|
|
type: string
|
|
example: 5d0f3cbb2a6e4f6c8e0e1c3b9a7d2f41b6c5e8a9d0f1e2c3b4a5968778695a4b
|
|
responses:
|
|
"200":
|
|
description: >-
|
|
Docker stats objects (see the Docker Engine API, `ContainerStats`),
|
|
oldest first; `false` without ID
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: object
|
|
description: One Docker stats snapshot
|
|
properties:
|
|
read:
|
|
type: string
|
|
description: Time of the snapshot
|
|
name:
|
|
type: string
|
|
id:
|
|
type: string
|
|
cpu_stats:
|
|
type: object
|
|
precpu_stats:
|
|
type: object
|
|
memory_stats:
|
|
type: object
|
|
blkio_stats:
|
|
type: object
|
|
networks:
|
|
type: object
|
|
pids_stats:
|
|
type: object
|
|
additionalProperties: true
|
|
example:
|
|
- read: "2026-11-10T19:20:01.123456789Z"
|
|
name: /mailcowdockerized-dovecot-mailcow-1
|
|
id: 5d0f3cbb2a6e4f6c8e0e1c3b9a7d2f41b6c5e8a9d0f1e2c3b4a5968778695a4b
|
|
pids_stats:
|
|
current: 38
|
|
memory_stats:
|
|
usage: 104857600
|
|
limit: 12541669376
|
|
blkio_stats:
|
|
io_service_bytes_recursive:
|
|
- major: 8
|
|
minor: 0
|
|
op: read
|
|
value: 1052672
|
|
- major: 8
|
|
minor: 0
|
|
op: write
|
|
value: 40960
|
|
networks:
|
|
eth0:
|
|
rx_bytes: 2621440
|
|
tx_bytes: 1048576
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/status/host:
|
|
get:
|
|
summary: Get host statistics
|
|
description: CPU, memory, uptime and architecture of the Docker host.
|
|
operationId: getHostStatus
|
|
tags:
|
|
- Status
|
|
responses:
|
|
"200":
|
|
description: The host statistics
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HostStats"
|
|
example:
|
|
cpu:
|
|
cores: 4
|
|
usage: 6
|
|
memory:
|
|
total: 12541669376
|
|
usage: 62.5
|
|
swap:
|
|
- 1022357504
|
|
- 512716800
|
|
- 509640704
|
|
- 50.2
|
|
- 1392812032
|
|
- 3864260608
|
|
uptime: 703800.5492310524
|
|
system_time: "10.11.2026 19:13:07"
|
|
architecture: x86_64
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/status/host/ip:
|
|
get:
|
|
summary: Get public IP addresses
|
|
description: >-
|
|
The public IPv4 and IPv6 address of the server. Asks
|
|
ipv4.mailcow.email and ipv6.mailcow.email on every call, even with the
|
|
IP check off.
|
|
operationId: getHostIps
|
|
tags:
|
|
- Status
|
|
responses:
|
|
"200":
|
|
description: The addresses, `false` for an address that could not be determined
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
ipv4:
|
|
type: [string, boolean]
|
|
description: Public IPv4 address
|
|
ipv6:
|
|
type: [string, boolean]
|
|
description: Public IPv6 address
|
|
example:
|
|
ipv4: 198.51.100.25
|
|
ipv6: 2001:db8::25
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjobs/all/no_log:
|
|
get:
|
|
summary: Get all sync jobs without logs
|
|
description: >-
|
|
Like `GET /api/v1/get/syncjobs/all`, with an empty `log`.
|
|
operationId: getSyncJobsWithoutLog
|
|
tags:
|
|
- Sync jobs
|
|
responses:
|
|
"200":
|
|
description: The sync jobs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyncJob"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjob_source/{id}:
|
|
get:
|
|
summary: Get sync source
|
|
description: >-
|
|
One sync source by id, visible as in `GET /api/v1/get/syncjob_source/all`.
|
|
operationId: getSyncJobSource
|
|
tags:
|
|
- Sync jobs
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Source id
|
|
schema:
|
|
type: integer
|
|
example: 4
|
|
responses:
|
|
"200":
|
|
description: The sync source
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SyncJobSource"
|
|
example:
|
|
id: 4
|
|
name: Google Workspace
|
|
description: ""
|
|
created_by: admin
|
|
scope: all
|
|
host1: imap.gmail.com
|
|
port1: 993
|
|
enc1: SSL
|
|
verify_cert: 1
|
|
auth_type: XOAUTH2
|
|
oauth_flow: authorization_code
|
|
oauth_token_endpoint: https://oauth2.googleapis.com/token
|
|
oauth_authorize_endpoint: https://accounts.google.com/o/oauth2/v2/auth
|
|
oauth_userinfo_endpoint: null
|
|
oauth_client_id: 1234567890-example.apps.googleusercontent.com
|
|
oauth_scope: https://mail.google.com/ openid email
|
|
oauth_extra_params: '{"access_type":"offline","prompt":"consent"}'
|
|
oauth_token_expires: null
|
|
oauth_last_refresh_error: null
|
|
oauth_last_refresh_attempt: null
|
|
created: "2026-11-01 10:00:00"
|
|
modified: null
|
|
active: 1
|
|
domains: []
|
|
users: []
|
|
can_edit: true
|
|
host: imap.gmail.com
|
|
port: 993
|
|
enc: SSL
|
|
has_client_secret: true
|
|
has_access_token: false
|
|
oauth_redirect_uri: https://mail.example.org/syncjob-oauth
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjob_options:
|
|
get:
|
|
summary: Get allowed custom imapsync options
|
|
description: >-
|
|
The imapsync options allowed in `custom_params`, with their rule: `true`
|
|
needs a value, `false` takes none, a string is a regular expression the
|
|
whole value must match. Options that run code, use local files or print
|
|
secrets are never allowed. Every logged-in user may read it.
|
|
operationId: getSyncJobOptions
|
|
tags:
|
|
- Sync jobs
|
|
responses:
|
|
"200":
|
|
description: Option name => rule
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties:
|
|
type:
|
|
- boolean
|
|
- string
|
|
example:
|
|
authmd51: false
|
|
debugssl: true
|
|
folder: true
|
|
maxsize: true
|
|
syncinternaldates: false
|
|
sslargs1: "^SSL_verify_mode=[01]$"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/imapsync_settings:
|
|
get:
|
|
summary: Get global sync job settings
|
|
description: >-
|
|
Settings of the sync job runner.
|
|
operationId: getSyncJobSettings
|
|
tags:
|
|
- Sync jobs
|
|
responses:
|
|
"200":
|
|
description: The settings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SyncJobSettings"
|
|
example:
|
|
max_parallel: 3
|
|
max_bytes_per_second: 2048000
|
|
max_kb_per_second: 2000
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjobs/all:
|
|
get:
|
|
summary: Get all sync jobs
|
|
description: >-
|
|
All sync jobs with their logs, in queue order. Admins also get jobs of
|
|
deleted mailboxes, domain admins the jobs of their mailboxes; users get
|
|
none, see `GET /api/v1/get/syncjobs/{mailbox}`.
|
|
operationId: getSyncJobs
|
|
tags:
|
|
- Sync jobs
|
|
responses:
|
|
"200":
|
|
description: The sync jobs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyncJob"
|
|
example:
|
|
- id: 12
|
|
user2: alice@example.org
|
|
regextrans2: ""
|
|
authmd51: 0
|
|
domain2: ""
|
|
subfolder2: Imported
|
|
user1: alice@old-provider.example.com
|
|
exclude: "(?i)spam|(?i)junk"
|
|
maxage: 0
|
|
mins_interval: 20
|
|
maxbytespersecond: "0"
|
|
delete2duplicates: 1
|
|
delete1: 0
|
|
delete2: 0
|
|
automap: 1
|
|
skipcrossduplicates: 0
|
|
custom_params: '[{"o":"folder","v":"INBOX"}]'
|
|
timeout1: 600
|
|
timeout2: 600
|
|
subscribeall: 1
|
|
dry: 0
|
|
is_running: 0
|
|
last_run: "2026-11-09 08:20:01"
|
|
success: 1
|
|
exit_status: EX_OK
|
|
created: "2026-11-03 09:40:09"
|
|
modified: "2026-11-03 09:42:21"
|
|
active: 1
|
|
source_id: 3
|
|
custom_params_legacy: null
|
|
prio: 0
|
|
source_name: Old provider
|
|
source_description: Migration from the old provider
|
|
source_host: imap.example.com
|
|
source_port: 993
|
|
source_enc: SSL
|
|
source_auth_type: PLAIN
|
|
source_created_by: API
|
|
source_scope: domain
|
|
source_oauth_flow: client_credentials
|
|
source_active: 1
|
|
source_oauth_token_expires: null
|
|
source_oauth_last_refresh_error: null
|
|
user_token_expires: null
|
|
user_token_error: null
|
|
user_token_exists: 0
|
|
log: "Transfer started at Mon Nov 9 08:20:02 2026\n..."
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjobs/{mailbox}:
|
|
get:
|
|
summary: Get sync jobs of a mailbox
|
|
description: >-
|
|
The sync jobs of a local mailbox with their logs, in queue order.
|
|
Domain admins may read their mailboxes, users their own. A value that is
|
|
no email address returns the caller's own jobs.
|
|
operationId: getMailboxSyncJobs
|
|
tags:
|
|
- Sync jobs
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Local mailbox (`user2` of the jobs)
|
|
schema:
|
|
type: string
|
|
example: alice@example.org
|
|
responses:
|
|
"200":
|
|
description: The sync jobs of the mailbox
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyncJob"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjobs/{mailbox}/no_log:
|
|
get:
|
|
summary: Get sync jobs of a mailbox without logs
|
|
description: >-
|
|
Like `GET /api/v1/get/syncjobs/{mailbox}`, with an empty `log`.
|
|
operationId: getMailboxSyncJobsWithoutLog
|
|
tags:
|
|
- Sync jobs
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Local mailbox (`user2` of the jobs)
|
|
schema:
|
|
type: string
|
|
example: alice@example.org
|
|
responses:
|
|
"200":
|
|
description: The sync jobs of the mailbox
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyncJob"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/syncjob_source/all:
|
|
get:
|
|
summary: Get sync sources
|
|
description: >-
|
|
The sync sources the caller may see, ordered by name. Domain admins see
|
|
their own, `all` sources and those for their domains or mailboxes or
|
|
created by their mailboxes; users their own, `all` sources and those
|
|
for them or their domain.
|
|
operationId: getSyncJobSources
|
|
tags:
|
|
- Sync jobs
|
|
responses:
|
|
"200":
|
|
description: The sync sources
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SyncJobSource"
|
|
example:
|
|
- id: 3
|
|
name: Old provider
|
|
description: Migration from the old provider
|
|
created_by: API
|
|
scope: domain
|
|
host1: imap.example.com
|
|
port1: 993
|
|
enc1: SSL
|
|
verify_cert: 1
|
|
auth_type: PLAIN
|
|
oauth_flow: client_credentials
|
|
oauth_token_endpoint: null
|
|
oauth_authorize_endpoint: null
|
|
oauth_userinfo_endpoint: null
|
|
oauth_client_id: null
|
|
oauth_scope: null
|
|
oauth_extra_params: null
|
|
oauth_token_expires: null
|
|
oauth_last_refresh_error: null
|
|
oauth_last_refresh_attempt: null
|
|
created: "2026-11-03 09:42:21"
|
|
modified: null
|
|
active: 1
|
|
domains:
|
|
- example.org
|
|
users: []
|
|
can_edit: true
|
|
host: imap.example.com
|
|
port: 993
|
|
enc: SSL
|
|
has_client_secret: false
|
|
has_access_token: false
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/tls-policy-map/{id}:
|
|
get:
|
|
tags:
|
|
- Outgoing TLS Policy Map Overrides
|
|
summary: Get TLS policy maps
|
|
operationId: getTlsPolicyMaps
|
|
description: >-
|
|
`all` lists the TLS policy maps, an ID returns one map with an extra
|
|
member `"0": null`. `{}` if there is none or the caller is no
|
|
administrator.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a TLS policy map"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of TLS policy maps (`all`) or one TLS policy map
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/TlsPolicyMap"
|
|
- $ref: "#/components/schemas/TlsPolicyMap"
|
|
examples:
|
|
all:
|
|
summary: get/tls-policy-map/all
|
|
value:
|
|
- id: 2
|
|
dest: example.com
|
|
policy: encrypt
|
|
parameters: protocols=>=TLSv1.2
|
|
active: 1
|
|
created: "2026-11-06 12:00:31"
|
|
modified: null
|
|
one:
|
|
summary: get/tls-policy-map/2
|
|
value:
|
|
id: 2
|
|
dest: example.com
|
|
policy: encrypt
|
|
parameters: protocols=>=TLSv1.2
|
|
active: 1
|
|
created: "2026-11-06 12:00:31"
|
|
modified: null
|
|
"0": null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/tls-policy-map:
|
|
post:
|
|
tags:
|
|
- Outgoing TLS Policy Map Overrides
|
|
summary: Update TLS policy maps
|
|
operationId: editTlsPolicyMap
|
|
description: >-
|
|
Changes the TLS policy maps in `items`; fields not sent keep their
|
|
value. An error stops the call; an existing destination answers
|
|
`recipient_map_entry_exists`.
|
|
|
|
|
|
Messages: `tls_policy_map_entry_saved`; errors
|
|
`tls_policy_map_dest_invalid`, `tls_policy_map_parameter_invalid`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs of the TLS policy maps, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
dest:
|
|
type: string
|
|
description: Destination, e.g. `example.org` or `[mail.example.org]:25`
|
|
policy:
|
|
type: string
|
|
enum:
|
|
- none
|
|
- may
|
|
- encrypt
|
|
- dane
|
|
- dane-only
|
|
- fingerprint
|
|
- verify
|
|
- secure
|
|
parameters:
|
|
type: string
|
|
description: Empty or space-separated `name=value` attributes
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 2
|
|
attr:
|
|
policy: dane
|
|
parameters: ""
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/transport/{id}:
|
|
get:
|
|
tags:
|
|
- Routing
|
|
summary: Get transport maps
|
|
operationId: getTransports
|
|
description: >-
|
|
`all` lists the transport maps, an ID returns one; the password is in
|
|
clear text. `{}` if there is none or the caller is no administrator.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a transport map"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The list of transport maps (`all`) or one entry
|
|
content:
|
|
application/json:
|
|
schema:
|
|
anyOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/Transport"
|
|
- $ref: "#/components/schemas/Transport"
|
|
examples:
|
|
all:
|
|
summary: get/transport/all
|
|
value:
|
|
- id: 4
|
|
is_mx_based: 0
|
|
destination: example.com
|
|
nexthop: "[mx.example.com]:25"
|
|
username: ""
|
|
password: ""
|
|
active: 1
|
|
password_short: "..."
|
|
- id: 5
|
|
is_mx_based: 1
|
|
destination: .*\.google\.com
|
|
nexthop: "[smtp.example.net]:587"
|
|
username: relay-user@example.net
|
|
password: Secret-Passphrase-42
|
|
active: 1
|
|
password_short: Sec...
|
|
one:
|
|
summary: get/transport/4
|
|
value:
|
|
id: 4
|
|
is_mx_based: 0
|
|
destination: example.com
|
|
nexthop: "[mx.example.com]:25"
|
|
username: ""
|
|
password: ""
|
|
active: 1
|
|
password_short: "..."
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/relayhost:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Update sender-dependent transports
|
|
operationId: editRelayhost
|
|
description: >-
|
|
Changes the sender-dependent transports in `items`; fields not sent
|
|
and an empty `hostname` keep their value.
|
|
|
|
|
|
Messages: `object_modified`; errors `relayhost_invalid`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs of the sender-dependent transports, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
description: Next hop, e.g. `[smtp.example.com]:587`
|
|
username:
|
|
type: string
|
|
description: SMTP user name, empty for no authentication
|
|
password:
|
|
type: string
|
|
description: SMTP password
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 1
|
|
attr:
|
|
password: New-Secret-Passphrase-43
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/transport:
|
|
post:
|
|
tags:
|
|
- Routing
|
|
summary: Update transport maps
|
|
operationId: editTransport
|
|
description: >-
|
|
Changes the transport maps in `items`; fields not sent keep their
|
|
value. An empty `username` also clears the password; credentials apply
|
|
to all entries of the next hop. Destination and next-hop errors stop
|
|
the call.
|
|
|
|
|
|
Messages: `object_modified`; errors `relayhost_invalid`,
|
|
`transport_dest_exists`, `invalid_destination`, `next_hop_interferes`.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: IDs of the transport maps, a single value or a list
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
destination:
|
|
type: string
|
|
description: One destination (see add/transport)
|
|
nexthop:
|
|
type: string
|
|
description: Next hop, e.g. `[mx.example.com]:25`
|
|
username:
|
|
type: string
|
|
description: SMTP user name; empty removes the credentials
|
|
password:
|
|
type: string
|
|
description: SMTP password
|
|
is_mx_based:
|
|
type: [boolean, integer, string]
|
|
description: 1 = `destination` is a regular expression for MX names
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = active, 0 = inactive
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 4
|
|
attr:
|
|
nexthop: "[mx2.example.com]:25"
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/cors:
|
|
post:
|
|
summary: Edit CORS settings
|
|
description: >-
|
|
Sets the origins and methods allowed to call the API from a browser. A
|
|
missing value is reset to its default.
|
|
|
|
|
|
Messages: `cors_headers_edited`; errors `cors_invalid_origin`,
|
|
`cors_invalid_method`.
|
|
operationId: editCors
|
|
tags:
|
|
- Cross-Origin Resource Sharing (CORS)
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
allowed_origins:
|
|
description: >-
|
|
`scheme://host[:port]` (http/https, no path) or `*`; a
|
|
list or one origin per line. Default: the mailcow URL.
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
- type: string
|
|
allowed_methods:
|
|
description: >-
|
|
Uppercase; a list or a string with single separators
|
|
(`GET,POST`, not `GET, POST`). Default: all four.
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: string
|
|
enum:
|
|
- GET
|
|
- POST
|
|
- PUT
|
|
- DELETE
|
|
- type: string
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
allowed_origins:
|
|
- https://app.example.org
|
|
- https://admin.example.com:8443
|
|
allowed_methods:
|
|
- GET
|
|
- POST
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/spam-score/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Get the spam score of a mailbox
|
|
operationId: getSpamScore
|
|
description: >-
|
|
The spam thresholds of the mailbox, its own or the server default. `{}`
|
|
without access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: Thresholds
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SpamScore"
|
|
example:
|
|
score: "6,12"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/spam-score:
|
|
post:
|
|
tags:
|
|
- Mailbox user settings
|
|
summary: Set the spam score of mailboxes
|
|
operationId: editSpamScore
|
|
description: >-
|
|
Sets the spam thresholds of the mailboxes: from the first value mail
|
|
goes to junk, from the second it is rejected. `default` removes the own
|
|
values. Needs the user ACL `spam_score`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
attr:
|
|
type: object
|
|
required:
|
|
- spam_score
|
|
properties:
|
|
spam_score:
|
|
type: string
|
|
description: '"low,high" (numbers) or "default"'
|
|
examples:
|
|
- "6,12"
|
|
- default
|
|
example:
|
|
items:
|
|
- john.doe@example.org
|
|
attr:
|
|
spam_score: "6,12"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/mailbox/template:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Create a mailbox template
|
|
operationId: addMailboxTemplate
|
|
description: >-
|
|
Saves a named set of mailbox settings that `add/mailbox` uses as
|
|
defaults. Without `acl` it grants no user ACL.
|
|
|
|
|
|
Messages: `template_added`; errors `template_exists`,
|
|
`quarantine_category_invalid`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- type: object
|
|
required:
|
|
- template
|
|
properties:
|
|
template:
|
|
type: string
|
|
description: Name of the template
|
|
- $ref: "#/components/schemas/MailboxTemplateInput"
|
|
example:
|
|
template: Sales
|
|
quota: 2048
|
|
tags:
|
|
- sales
|
|
quarantine_notification: daily
|
|
quarantine_category: reject
|
|
rl_value: 100
|
|
rl_frame: h
|
|
active: 1
|
|
protocol_access:
|
|
- imap
|
|
- smtp
|
|
- sieve
|
|
acl:
|
|
- spam_alias
|
|
- spam_score
|
|
- app_passwds
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/mailbox/all:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get all mailboxes
|
|
operationId: getMailboxes
|
|
description: >-
|
|
All mailboxes of the domains the caller manages, without resources.
|
|
`{}` if none.
|
|
parameters:
|
|
- $ref: "#/components/parameters/MailboxTagsQuery"
|
|
responses:
|
|
"200":
|
|
description: List of mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
examples:
|
|
mailboxes:
|
|
$ref: "#/components/examples/MailboxList"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/all/{domains}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get the mailboxes of domains
|
|
operationId: getMailboxesOfDomains
|
|
description: >-
|
|
Like `get/mailbox/all` for the given domains. Caution: an unknown or
|
|
foreign domain adds all mailboxes the caller manages.
|
|
parameters:
|
|
- name: domains
|
|
in: path
|
|
required: true
|
|
description: Domain name or comma-separated list of domain names
|
|
schema:
|
|
type: string
|
|
example: example.org
|
|
- $ref: "#/components/parameters/MailboxTagsQuery"
|
|
responses:
|
|
"200":
|
|
description: List of mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/reduced:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get all mailboxes (reduced details)
|
|
operationId: getMailboxesReduced
|
|
description: >-
|
|
Like `get/mailbox/all` without the costly fields named in `Mailbox`;
|
|
faster on large installations.
|
|
parameters:
|
|
- $ref: "#/components/parameters/MailboxTagsQuery"
|
|
responses:
|
|
"200":
|
|
description: List of mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/reduced/{domains}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get the mailboxes of domains (reduced details)
|
|
operationId: getMailboxesReducedOfDomains
|
|
description: >-
|
|
Like `get/mailbox/reduced` for the given domains; an unknown domain
|
|
adds all mailboxes the caller manages.
|
|
parameters:
|
|
- name: domains
|
|
in: path
|
|
required: true
|
|
description: Domain name or comma-separated list of domain names
|
|
schema:
|
|
type: string
|
|
example: example.org,example.com
|
|
- $ref: "#/components/parameters/MailboxTagsQuery"
|
|
responses:
|
|
"200":
|
|
description: List of mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/template/all:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get all mailbox templates
|
|
operationId: getMailboxTemplates
|
|
description: >-
|
|
All mailbox templates, also for domain admins. `{}` if none.
|
|
responses:
|
|
"200":
|
|
description: List of templates
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailboxTemplate"
|
|
example:
|
|
- id: 2
|
|
template: Default
|
|
type: mailbox
|
|
attributes:
|
|
tags: []
|
|
quota: 0
|
|
quarantine_notification: hourly
|
|
quarantine_category: reject
|
|
rl_frame: s
|
|
rl_value: ""
|
|
force_pw_update: 0
|
|
force_tfa: 0
|
|
sogo_access: 1
|
|
active: 1
|
|
tls_enforce_in: 0
|
|
tls_enforce_out: 0
|
|
imap_access: 1
|
|
pop3_access: 1
|
|
smtp_access: 1
|
|
sieve_access: 1
|
|
eas_access: 1
|
|
dav_access: 1
|
|
acl_spam_alias: 1
|
|
acl_tls_policy: 1
|
|
acl_spam_score: 1
|
|
acl_spam_policy: 1
|
|
acl_delimiter_action: 1
|
|
acl_syncjobs: 0
|
|
acl_eas_reset: 1
|
|
acl_sogo_profile_reset: 0
|
|
acl_pushover: 1
|
|
acl_quarantine: 1
|
|
acl_quarantine_attachments: 1
|
|
acl_quarantine_notification: 1
|
|
acl_quarantine_category: 1
|
|
acl_app_passwds: 1
|
|
created: "2026-09-21 10:23:08"
|
|
modified: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/mailbox/template/{id}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get a mailbox template
|
|
operationId: getMailboxTemplate
|
|
description: >-
|
|
One mailbox template by ID, also for domain admins. `{}` if not found.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Template ID
|
|
schema:
|
|
type: integer
|
|
example: 2
|
|
responses:
|
|
"200":
|
|
description: The template
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxTemplate"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/mailbox/template:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Update mailbox templates
|
|
operationId: editMailboxTemplate
|
|
description: >-
|
|
Changes mailbox templates and passes the change on to mailboxes that
|
|
use them as group template. `Default` keeps its name. Send the complete
|
|
template: fields not sent are reset (`quota` to 0, protocol and ACL
|
|
settings lost), and `quarantine_category` is required.
|
|
|
|
|
|
Messages: `template_modified`; errors `template_id_invalid`,
|
|
`quarantine_category_invalid`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Template ID or list of template IDs
|
|
oneOf:
|
|
- type: integer
|
|
- type: array
|
|
items:
|
|
type: integer
|
|
attr:
|
|
allOf:
|
|
- type: object
|
|
properties:
|
|
template:
|
|
type: string
|
|
description: New name of the template (not for "Default")
|
|
- $ref: "#/components/schemas/MailboxTemplateInput"
|
|
example:
|
|
items:
|
|
- 3
|
|
attr:
|
|
template: Sales
|
|
quota: 4096
|
|
tags:
|
|
- sales
|
|
tagged_mail_handler: subfolder
|
|
quarantine_notification: daily
|
|
quarantine_category: reject
|
|
rl_value: 100
|
|
rl_frame: h
|
|
force_pw_update: 0
|
|
force_tfa: 0
|
|
sogo_access: 1
|
|
active: 1
|
|
tls_enforce_in: 0
|
|
tls_enforce_out: 1
|
|
protocol_access:
|
|
- imap
|
|
- smtp
|
|
- sieve
|
|
- dav
|
|
acl:
|
|
- spam_alias
|
|
- spam_score
|
|
- delimiter_action
|
|
- app_passwds
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/rename-mbox:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Rename a mailbox
|
|
operationId: renameMailbox
|
|
description: >-
|
|
Renames `old_local_part@domain` to `new_local_part@domain`, including
|
|
maildir, aliases and SOGo account. The mailbox is named in `attr`, not
|
|
`items`, and must be active (1 or 2). Also for domain admins. Answers
|
|
`mailbox_renamed`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Not used
|
|
attr:
|
|
type: object
|
|
required:
|
|
- domain
|
|
- old_local_part
|
|
- new_local_part
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain of the mailbox
|
|
old_local_part:
|
|
type: string
|
|
description: Current local part
|
|
new_local_part:
|
|
type: string
|
|
description: New local part
|
|
create_alias:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
description: 1 creates an alias from the old to the new address
|
|
example:
|
|
items: []
|
|
attr:
|
|
domain: example.org
|
|
old_local_part: john.doe
|
|
new_local_part: john
|
|
create_alias: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/mailbox/template:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Delete mailbox templates
|
|
operationId: deleteMailboxTemplate
|
|
description: >-
|
|
Deletes mailbox templates by ID; `Default` is kept silently. Answers
|
|
`template_removed`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Template IDs
|
|
items:
|
|
type: integer
|
|
example:
|
|
- 3
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/last-login/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get the last logins of a mailbox
|
|
operationId: getLastLogin
|
|
description: >-
|
|
Logins of the mailbox in the last 7 days (`sasl`, the latest per
|
|
address, service and app password) and its previous UI login (`ui`,
|
|
only for admins and the mailbox user itself).
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: Logins
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LastLogin"
|
|
example:
|
|
ui:
|
|
remote: 198.51.100.23
|
|
time: 1793011200
|
|
sasl:
|
|
- real_rip: 198.51.100.23
|
|
datetime: "2026-11-09 08:12:44"
|
|
service: imap
|
|
app_password: 23
|
|
app_password_name: Thunderbird
|
|
location: DE
|
|
- real_rip: Web/EAS/Internal (172.22.1.248)
|
|
datetime: "2026-11-08 17:03:10"
|
|
service: SOGO
|
|
app_password: 0
|
|
app_password_name: null
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/last-login/{mailbox}/{days}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get the last logins of a mailbox for a period
|
|
operationId: getLastLoginDays
|
|
description: >-
|
|
Like `get/last-login/{mailbox}` for the last `{days}` days; values
|
|
below 1 mean 7.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
- name: days
|
|
in: path
|
|
required: true
|
|
description: Number of days
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
example: 30
|
|
responses:
|
|
"200":
|
|
description: Logins
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LastLogin"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/reset-last-login/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Clear the login history of a mailbox
|
|
operationId: resetLastLogin
|
|
description: >-
|
|
Deletes the login history of the mailbox. A `get` route that changes
|
|
data: read-only API keys can call it. Always answers `true`.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: Done
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: boolean
|
|
example: true
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/delete/eas_cache:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Reset the ActiveSync devices of mailboxes
|
|
operationId: deleteEasCache
|
|
description: >-
|
|
Deletes the ActiveSync device cache of the mailboxes, so devices sync
|
|
from scratch. Needs the user ACL `eas_reset`; a mailbox user may reset
|
|
only its own.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
example:
|
|
- john.doe@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/sogo_profile:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Reset the SOGo profile of mailboxes
|
|
operationId: deleteSogoProfile
|
|
description: >-
|
|
Deletes the SOGo data of the mailboxes: profile, settings, calendars
|
|
and address books. Needs the user ACL `sogo_profile_reset`; a mailbox
|
|
user may reset only its own.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxItems"
|
|
example:
|
|
- john.doe@example.org
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/bcc-destination-options:
|
|
get:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Get the possible BCC map destinations
|
|
operationId: getBccDestinationOptions
|
|
description: >-
|
|
What a BCC map can be bound to: the caller's domains, their mailboxes
|
|
with their aliases, and alias domains. Empty keys are left out.
|
|
responses:
|
|
"200":
|
|
description: Domains, mailboxes with their addresses, alias domains
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
domains:
|
|
type: array
|
|
items:
|
|
type: string
|
|
mailboxes:
|
|
type: object
|
|
description: Mailbox address → the mailbox and its aliases
|
|
additionalProperties:
|
|
type: array
|
|
items:
|
|
type: string
|
|
alias_domains:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
domains:
|
|
- example.org
|
|
mailboxes:
|
|
john.doe@example.org:
|
|
- john.doe@example.org
|
|
- sales@example.org
|
|
jane.roe@example.org:
|
|
- jane.roe@example.org
|
|
alias_domains:
|
|
- example.net
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/search/mailbox:
|
|
post:
|
|
tags:
|
|
- Mailboxes
|
|
summary: Search mailboxes page by page
|
|
operationId: searchMailboxes
|
|
description: >-
|
|
Server-side search behind the UI mailbox table (DataTables format) over
|
|
the mailboxes the caller manages. Read-only API keys may use it;
|
|
mailbox users get `403`.
|
|
|
|
|
|
Columns: 2 address, 3 quota, 4 last mail login, 5 last password change,
|
|
6 quota in use, 7 name, 20 messages, 23 tags, 24 active. Send 4, 5, 6
|
|
and 20 as not searchable and 23 as not orderable, else the query fails.
|
|
`recordsTotal` equals `recordsFiltered`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MailboxSearchRequest"
|
|
example:
|
|
draw: 1
|
|
start: 0
|
|
length: 25
|
|
search:
|
|
value: john
|
|
order:
|
|
- column: 2
|
|
dir: asc
|
|
columns:
|
|
- searchable: false
|
|
orderable: false
|
|
- searchable: false
|
|
orderable: false
|
|
- data: username
|
|
searchable: true
|
|
orderable: true
|
|
- searchable: false
|
|
orderable: true
|
|
- searchable: false
|
|
orderable: true
|
|
- searchable: false
|
|
orderable: true
|
|
- searchable: false
|
|
orderable: true
|
|
- data: name
|
|
searchable: true
|
|
orderable: true
|
|
responses:
|
|
"200":
|
|
description: >-
|
|
One page of mailboxes. A failing database query answers
|
|
`{"error": "An SQL error occurred: ..."}` instead.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- $ref: "#/components/schemas/MailboxSearchResult"
|
|
- type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
examples:
|
|
page:
|
|
$ref: "#/components/examples/MailboxSearchPage"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
description: The caller is a mailbox user or not logged in
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
example:
|
|
type: error
|
|
msg: Insufficient permissions
|
|
/api/v1/edit/identity-provider:
|
|
post:
|
|
summary: Configure the Identity Provider
|
|
description: >-
|
|
Saves the Identity Provider configuration (Keycloak, generic OpenID
|
|
Connect or LDAP). Send the complete configuration including the secrets:
|
|
settings not sent are reset to their defaults. Changing the LDAP
|
|
`id_attribute` drops the stored links; mailboxes are matched by email
|
|
again.
|
|
|
|
|
|
Messages: `object_modified`; errors `required_data_missing`,
|
|
`invalid_authsource`, `authsource_in_use`.
|
|
operationId: editIdentityProvider
|
|
tags:
|
|
- Identity Provider
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Not used
|
|
attr:
|
|
$ref: "#/components/schemas/IdentityProviderAttributes"
|
|
examples:
|
|
keycloak:
|
|
value:
|
|
attr:
|
|
authsource: keycloak
|
|
server_url: https://auth.example.org
|
|
realm: mailcow
|
|
client_id: mailcow
|
|
client_secret: client-secret-value
|
|
redirect_url: https://mail.example.org
|
|
redirect_url_extra:
|
|
- https://webmail.example.org
|
|
version: 26.1.3
|
|
login_provisioning: 1
|
|
mailpassword_flow: 0
|
|
periodic_sync: 1
|
|
import_users: 1
|
|
sync_interval: 15
|
|
offboarding: 1
|
|
offboarding_limit: 10
|
|
group_sync: 1
|
|
group_autocreate: 1
|
|
group_paths: /mailcow/*
|
|
group_default_domain: example.org
|
|
default_template: Default
|
|
mappers:
|
|
- staff
|
|
templates:
|
|
- Staff
|
|
ldap:
|
|
value:
|
|
attr:
|
|
authsource: ldap
|
|
host: ldap1.example.org,ldap2.example.org
|
|
port: 636
|
|
use_ssl: 1
|
|
use_tls: 0
|
|
ignore_ssl_error: 0
|
|
basedn: dc=example,dc=org
|
|
binddn: cn=mailcow,ou=services,dc=example,dc=org
|
|
bindpass: bind-password
|
|
username_field: mail
|
|
filter: (objectClass=inetOrgPerson)
|
|
attribute_field: departmentNumber
|
|
login_provisioning: 1
|
|
periodic_sync: 1
|
|
import_users: 1
|
|
sync_interval: 30
|
|
group_sync: 1
|
|
group_filter: (objectClass=groupOfNames)
|
|
group_member_mode: member
|
|
group_member_attribute: member
|
|
default_template: Default
|
|
generic-oidc:
|
|
value:
|
|
attr:
|
|
authsource: generic-oidc
|
|
authorize_url: https://sso.example.org/application/o/authorize/
|
|
token_url: https://sso.example.org/application/o/token/
|
|
userinfo_url: https://sso.example.org/application/o/userinfo/
|
|
client_id: mailcow
|
|
client_secret: client-secret-value
|
|
redirect_url: https://mail.example.org
|
|
client_scopes: openid profile email mailcow_template
|
|
login_provisioning: 1
|
|
default_template: Default
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/identity-provider:
|
|
get:
|
|
summary: Get Identity Provider settings
|
|
description: >-
|
|
The stored Identity Provider settings, also those of providers
|
|
configured before. Read/write API keys get the secrets in plain text,
|
|
read-only keys `*`. Without a configuration it answers
|
|
`{"login_provisioning": 1}`.
|
|
operationId: getIdentityProvider
|
|
tags:
|
|
- Identity Provider
|
|
responses:
|
|
"200":
|
|
description: The settings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/IdentityProviderSettings"
|
|
example:
|
|
authsource: keycloak
|
|
server_url: https://auth.example.org
|
|
realm: mailcow
|
|
client_id: mailcow
|
|
client_secret: "*"
|
|
redirect_url: https://mail.example.org
|
|
redirect_url_extra:
|
|
- https://webmail.example.org
|
|
version: 26.1.3
|
|
mailpassword_flow: "0"
|
|
periodic_sync: "1"
|
|
import_users: "1"
|
|
sync_interval: "15"
|
|
ignore_ssl_error: false
|
|
login_provisioning: true
|
|
group_paths: /mailcow/*
|
|
offboarding: "1"
|
|
offboarding_limit: "10"
|
|
group_sync: "1"
|
|
group_autocreate: "1"
|
|
group_default_domain: example.org
|
|
default_template: Default
|
|
mappers:
|
|
- staff
|
|
templates:
|
|
- Staff
|
|
access_token: "*"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/identity-provider-test:
|
|
post:
|
|
summary: Test an Identity Provider connection
|
|
description: >-
|
|
Tests the connection data in `attr` without storing it; stored settings
|
|
are not used, so send the secrets too. Keycloak must issue a
|
|
client_credentials token and generic-oidc answer OPTIONS on `token_url`
|
|
(HTTP 200 within 7 s); LDAP must bind. The answer has no details, and a
|
|
missing or unknown `authsource` answers success without a test.
|
|
operationId: testIdentityProvider
|
|
tags:
|
|
- Identity Provider
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Not used
|
|
attr:
|
|
type: object
|
|
required:
|
|
- authsource
|
|
properties:
|
|
authsource:
|
|
type: string
|
|
enum:
|
|
- keycloak
|
|
- generic-oidc
|
|
- ldap
|
|
server_url:
|
|
type: string
|
|
description: Keycloak base URL
|
|
realm:
|
|
type: string
|
|
description: Keycloak realm
|
|
client_id:
|
|
type: string
|
|
description: Keycloak client id
|
|
client_secret:
|
|
type: string
|
|
description: Keycloak client secret
|
|
token_url:
|
|
type: string
|
|
description: generic-oidc token endpoint
|
|
ignore_ssl_error:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: Do not verify the TLS certificate
|
|
host:
|
|
type: string
|
|
description: LDAP host, or several separated by commas
|
|
port:
|
|
type:
|
|
- integer
|
|
- string
|
|
description: LDAP port
|
|
basedn:
|
|
type: string
|
|
binddn:
|
|
type: string
|
|
bindpass:
|
|
type: string
|
|
use_ssl:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: LDAPS
|
|
use_tls:
|
|
type:
|
|
- boolean
|
|
- integer
|
|
- string
|
|
description: StartTLS, ignored with `use_ssl`
|
|
example:
|
|
attr:
|
|
authsource: keycloak
|
|
server_url: https://auth.example.org
|
|
realm: mailcow
|
|
client_id: mailcow
|
|
client_secret: client-secret-value
|
|
ignore_ssl_error: 0
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/identity-provider:
|
|
post:
|
|
summary: Delete the Identity Provider configuration
|
|
description: >-
|
|
Deletes all Identity Provider settings, mailbox links and the sync
|
|
history. Refused while any mailbox uses an external provider. The body
|
|
must be valid JSON, e.g. `[]`.
|
|
|
|
|
|
Messages: `item_deleted`; errors `authsource_in_use`.
|
|
operationId: deleteIdentityProvider
|
|
tags:
|
|
- Identity Provider
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
description: Not used, any JSON value
|
|
example: []
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/filter:
|
|
post:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Create a Sieve filter
|
|
operationId: addFilter
|
|
description: >-
|
|
Adds a Sieve script to a mailbox. Needs the ACL `filters` (admins,
|
|
domain admins). Activating a filter deactivates the other filters of
|
|
the same type and mailbox.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors `sieve_error`, `no_user_defined`,
|
|
`script_empty`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- username
|
|
- script_data
|
|
- script_desc
|
|
- filter_type
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Mailbox of the filter
|
|
script_desc:
|
|
type: string
|
|
description: Description
|
|
script_data:
|
|
type: string
|
|
description: The Sieve script
|
|
filter_type:
|
|
type: string
|
|
enum:
|
|
- prefilter
|
|
- postfilter
|
|
description: Runs before (prefilter) or after (postfilter) the user's own filters
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
default: 0
|
|
example:
|
|
username: john.doe@example.org
|
|
script_desc: Move newsletters
|
|
script_data: |-
|
|
require "fileinto";
|
|
if header :contains "List-Id" "newsletter" {
|
|
fileinto "Newsletters";
|
|
}
|
|
filter_type: prefilter
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/filters/all:
|
|
get:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Get all Sieve filters
|
|
operationId: getFilters
|
|
description: >-
|
|
The Sieve filters of all mailboxes the caller manages, `{}` if none.
|
|
responses:
|
|
"200":
|
|
description: List of filters
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SieveFilter"
|
|
example:
|
|
- active: 1
|
|
id: 7
|
|
username: john.doe@example.org
|
|
filter_type: prefilter
|
|
script_data: |-
|
|
require "fileinto";
|
|
if header :contains "List-Id" "newsletter" {
|
|
fileinto "Newsletters";
|
|
}
|
|
script_desc: Move newsletters
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/filters/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Get the Sieve filters of a mailbox
|
|
operationId: getMailboxFilters
|
|
description: >-
|
|
The Sieve filters of the mailbox, `{}` if none or no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: List of filters
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SieveFilter"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/filter:
|
|
post:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Update Sieve filters
|
|
operationId: editFilter
|
|
description: >-
|
|
Changes filters by ID; fields not sent keep their value. Needs the ACL
|
|
`filters` (admins, domain admins). Activating a filter deactivates the
|
|
others of the same type and mailbox. An unknown ID answers
|
|
`access_denied`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- items
|
|
- attr
|
|
properties:
|
|
items:
|
|
description: Filter ID or list of IDs
|
|
oneOf:
|
|
- type: integer
|
|
- type: array
|
|
items:
|
|
type: integer
|
|
attr:
|
|
type: object
|
|
properties:
|
|
script_desc:
|
|
type: string
|
|
script_data:
|
|
type: string
|
|
filter_type:
|
|
type: string
|
|
enum:
|
|
- prefilter
|
|
- postfilter
|
|
active:
|
|
type: [integer, string]
|
|
enum: [0, 1, "0", "1"]
|
|
example:
|
|
items:
|
|
- 7
|
|
attr:
|
|
active: 0
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/filter:
|
|
post:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Delete Sieve filters
|
|
operationId: deleteFilter
|
|
description: >-
|
|
Deletes filters by ID; IDs that are not numeric are skipped. Needs the
|
|
ACL `filters` (admins, domain admins).
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Filter IDs
|
|
items:
|
|
type: integer
|
|
example:
|
|
- 7
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/active-user-sieve/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox filters
|
|
summary: Get the active Sieve script of a mailbox
|
|
operationId: getActiveUserSieve
|
|
description: >-
|
|
The Sieve script the user activated in a mail client or SOGo, as a list
|
|
with one string. `{}` if none or no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: The script as the only element of a list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
maxItems: 1
|
|
items:
|
|
type: string
|
|
example:
|
|
- |-
|
|
require ["fileinto"];
|
|
if header :contains "subject" "invoice" {
|
|
fileinto "Invoices";
|
|
}
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/mailbox-policy:
|
|
post:
|
|
tags:
|
|
- Mailbox antispam policies
|
|
summary: Add a sender to the allow or deny list of a mailbox
|
|
operationId: addMailboxPolicy
|
|
description: >-
|
|
Adds a sender to the allow list (`wl`, never spam) or deny list (`bl`,
|
|
rejected) of a mailbox. Needs the user ACL `spam_policy`.
|
|
|
|
|
|
Messages: `mailbox_modified`; errors `policy_list_from_invalid`,
|
|
`policy_list_from_exists`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- username
|
|
- object_list
|
|
- object_from
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Mailbox
|
|
object_list:
|
|
type: string
|
|
enum:
|
|
- wl
|
|
- bl
|
|
description: wl = allow list, bl = deny list
|
|
object_from:
|
|
type: string
|
|
description: "Sender address, domain or pattern; allowed: letters, digits, `@ _ . - *`"
|
|
example:
|
|
username: john.doe@example.org
|
|
object_list: bl
|
|
object_from: "*@spam.example.com"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/policy_wl_mailbox/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox antispam policies
|
|
summary: Get the allow list of a mailbox
|
|
operationId: getMailboxPolicyAllowList
|
|
description: >-
|
|
The allow list entries of the mailbox and of its domain (see `object`).
|
|
`{}` if none or no access.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: List of entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SpamPolicyEntry"
|
|
example:
|
|
- object: john.doe@example.org
|
|
value: "*@partner.example.com"
|
|
prefid: 12
|
|
- object: example.org
|
|
value: newsletter@example.net
|
|
prefid: 4
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/policy_bl_mailbox/{mailbox}:
|
|
get:
|
|
tags:
|
|
- Mailbox antispam policies
|
|
summary: Get the deny list of a mailbox
|
|
operationId: getMailboxPolicyDenyList
|
|
description: >-
|
|
Like `get/policy_wl_mailbox/{mailbox}` for the deny list.
|
|
parameters:
|
|
- name: mailbox
|
|
in: path
|
|
required: true
|
|
description: Mailbox address
|
|
schema:
|
|
type: string
|
|
example: john.doe@example.org
|
|
responses:
|
|
"200":
|
|
description: List of entries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SpamPolicyEntry"
|
|
example:
|
|
- object: john.doe@example.org
|
|
value: "*@spam.example.com"
|
|
prefid: 13
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/delete/mailbox-policy:
|
|
post:
|
|
tags:
|
|
- Mailbox antispam policies
|
|
summary: Delete allow or deny list entries of mailboxes
|
|
operationId: deleteMailboxPolicy
|
|
description: >-
|
|
Deletes allow or deny list entries of mailboxes by `prefid`. Needs the
|
|
user ACL `spam_policy`. Domain entries are refused; use
|
|
`delete/domain-policy`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: prefid values
|
|
items:
|
|
type: integer
|
|
example:
|
|
- 13
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/add/rsetting:
|
|
post:
|
|
summary: Add Rspamd settings rule
|
|
description: >-
|
|
Adds a rule to the Rspamd settings map. `content` is an Rspamd settings
|
|
entry; `GET /api/v1/get/presets/rspamd` has examples. Without `desc`
|
|
nothing is saved and the answer is empty.
|
|
|
|
|
|
Messages: `settings_map_added`; errors `map_content_empty`.
|
|
operationId: addRspamdSetting
|
|
tags:
|
|
- Rspamd
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/RspamdSettingAttributes"
|
|
example:
|
|
desc: Disable all but DKIM and rate limit for authenticated users
|
|
content: |-
|
|
priority = 10;
|
|
authenticated = yes;
|
|
apply "default" {
|
|
symbols_enabled = ["DKIM_SIGNED", "RATELIMITED", "RATELIMIT_UPDATE", "RATELIMIT_CHECK"];
|
|
}
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/rsetting/{id}:
|
|
get:
|
|
summary: Get Rspamd settings rules
|
|
description: >-
|
|
Returns one rule of the Rspamd settings map, or a list of all rules
|
|
with `all`.
|
|
operationId: getRspamdSettings
|
|
tags:
|
|
- Rspamd
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: "`all` or the ID of a rule"
|
|
schema:
|
|
type: string
|
|
example: all
|
|
responses:
|
|
"200":
|
|
description: The rule, or the list of rules for `all`
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/RspamdSetting"
|
|
- $ref: "#/components/schemas/RspamdSetting"
|
|
example:
|
|
- id: 1
|
|
desc: Disable Rspamd for example.org
|
|
content: |-
|
|
priority = 10;
|
|
rcpt = "/.*@example\.org$/";
|
|
from = "/.*/";
|
|
apply "default" {
|
|
MAILCOW_WHITE = -9999.0;
|
|
}
|
|
symbols [
|
|
"MAILCOW_WHITE"
|
|
]
|
|
active: 1
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/rsetting:
|
|
post:
|
|
summary: Edit Rspamd settings rules
|
|
description: >-
|
|
Changes rules of the Rspamd settings map. Fields not sent, and an empty
|
|
`desc` or `content`, keep the old value.
|
|
|
|
|
|
Messages: `object_modified`; errors `settings_map_invalid`.
|
|
operationId: editRspamdSetting
|
|
tags:
|
|
- Rspamd
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: ID or list of IDs of the rules
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
attr:
|
|
type: object
|
|
properties:
|
|
desc:
|
|
type: string
|
|
description: Short description (empty = keep)
|
|
content:
|
|
type: string
|
|
description: Rule content (empty = keep)
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = the rule is handed to Rspamd, 0 = inactive (not sent = keep)
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- 1
|
|
attr:
|
|
desc: Disable Rspamd for example.org
|
|
active: "0"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/rsetting:
|
|
post:
|
|
summary: Delete Rspamd settings rules
|
|
description: >-
|
|
Deletes rules of the Rspamd settings map. Answers
|
|
`settings_map_removed` for every ID, even unknown ones.
|
|
operationId: deleteRspamdSettings
|
|
tags:
|
|
- Rspamd
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
description: IDs of the rules (a single ID works too)
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
type: [integer, string]
|
|
- type: [integer, string]
|
|
example:
|
|
- 1
|
|
- 2
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/rspamd-map:
|
|
post:
|
|
summary: Edit Rspamd global regex maps
|
|
description: >-
|
|
Replaces the content of global Rspamd regex maps (Global filters in the
|
|
UI). One regular expression per line, `#` starts a comment; unlike the
|
|
UI, the API does not check the expressions. Each map takes about a
|
|
second.
|
|
|
|
|
|
Messages: `object_modified`; errors `global_map_invalid`,
|
|
`global_map_write_error`.
|
|
operationId: editRspamdMap
|
|
tags:
|
|
- Rspamd
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: File name or list of file names of the maps; all of them get the same content
|
|
oneOf:
|
|
- type: array
|
|
items:
|
|
$ref: "#/components/schemas/RspamdRegexMap"
|
|
- $ref: "#/components/schemas/RspamdRegexMap"
|
|
attr:
|
|
type: object
|
|
properties:
|
|
rspamd_map_data:
|
|
type: string
|
|
description: New content of the map (trimmed, replaces the whole file)
|
|
required:
|
|
- rspamd_map_data
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- global_smtp_from_blacklist.map
|
|
attr:
|
|
rspamd_map_data: |-
|
|
# Envelope senders to reject
|
|
/^spammer@example\.com$/i
|
|
/@spam\.example\.net$/i
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/rspamd/actions:
|
|
get:
|
|
summary: Get Rspamd action statistics
|
|
description: >-
|
|
Returns how many messages Rspamd handled with each action, as
|
|
`[action, count]` pairs. Greylisted messages count as `soft reject`.
|
|
`{}` when Rspamd does not answer.
|
|
operationId: getRspamdActions
|
|
tags:
|
|
- Rspamd
|
|
responses:
|
|
"200":
|
|
description: List of `[action, count]` pairs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: array
|
|
prefixItems:
|
|
- type: string
|
|
description: Rspamd action
|
|
- type: integer
|
|
description: Number of messages
|
|
minItems: 2
|
|
maxItems: 2
|
|
example:
|
|
- - reject
|
|
- 38
|
|
- - soft reject
|
|
- 1
|
|
- - rewrite subject
|
|
- 0
|
|
- - add header
|
|
- 6
|
|
- - no action
|
|
- 255
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/presets/{kind}:
|
|
get:
|
|
summary: Get Rspamd or Sieve presets
|
|
description: >-
|
|
Returns the example presets of the UI: `rspamd` for Rspamd settings
|
|
rules, `sieve` for Sieve filters. `headline` is in the session
|
|
language. Admins and domain admins.
|
|
operationId: getPresets
|
|
tags:
|
|
- Rspamd
|
|
- Global filters
|
|
parameters:
|
|
- name: kind
|
|
in: path
|
|
required: true
|
|
description: Kind of presets
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- rspamd
|
|
- sieve
|
|
example: rspamd
|
|
responses:
|
|
"200":
|
|
description: List of presets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Preset"
|
|
example:
|
|
- name: preset_1
|
|
headline: Disable all but DKIM and rate limit for authenticated users
|
|
content: |-
|
|
priority = 10;
|
|
authenticated = yes;
|
|
apply "default" {
|
|
symbols_enabled = ["BCC", "DKIM_SIGNED", "RATELIMITED", "RATELIMIT_UPDATE", "RATELIMIT_CHECK", "DYN_RL_CHECK", "HISTORY_SAVE", "MILTER_HEADERS", "ARC_SIGNED"];
|
|
}
|
|
- name: preset_4
|
|
headline: Disable Rspamd for a domain
|
|
content: |-
|
|
priority = 10;
|
|
rcpt = "/.*@example.org$/";
|
|
from = "/.*/";
|
|
apply "default" {
|
|
MAILCOW_WHITE = -9999.0;
|
|
}
|
|
symbols [
|
|
"MAILCOW_WHITE"
|
|
]
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/global-filter:
|
|
post:
|
|
summary: Save a global Sieve filter
|
|
description: >-
|
|
Replaces the global Sieve prefilter or postfilter and restarts Dovecot.
|
|
A script with errors is not saved.
|
|
|
|
|
|
Messages: `global_filter_written`, `dovecot_restart_success`; errors
|
|
`sieve_error`, `invalid_filter_type`, `global_filter_write_error`,
|
|
`dovecot_restart_failed`.
|
|
operationId: addGlobalFilter
|
|
tags:
|
|
- Global filters
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
filter_type:
|
|
type: string
|
|
enum:
|
|
- prefilter
|
|
- postfilter
|
|
description: Which global filter to replace
|
|
script_data:
|
|
type: string
|
|
description: The Sieve script (CRLF and CR line ends become LF)
|
|
required:
|
|
- filter_type
|
|
- script_data
|
|
example:
|
|
filter_type: postfilter
|
|
script_data: |-
|
|
require "fileinto";
|
|
if header :contains "X-Spam-Flag" "YES" {
|
|
fileinto "Junk";
|
|
}
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/global_filters/all:
|
|
get:
|
|
summary: Get the global Sieve filters
|
|
description: >-
|
|
Returns the global Sieve prefilter and postfilter.
|
|
operationId: getGlobalFilters
|
|
tags:
|
|
- Global filters
|
|
responses:
|
|
"200":
|
|
description: Both scripts
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/GlobalFilters"
|
|
example:
|
|
prefilter: |
|
|
# global_sieve_before script
|
|
# global_sieve_before -> user sieve_before (mailcow UI) -> user sieve_after (mailcow UI) -> global_sieve_after
|
|
postfilter: |-
|
|
# global_sieve_after script
|
|
require "fileinto";
|
|
|
|
if header :contains "X-Spam-Flag" "YES" {
|
|
fileinto "Junk";
|
|
}
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/global_filters/{filter_type}:
|
|
get:
|
|
summary: Get one global Sieve filter
|
|
description: >-
|
|
Returns the global Sieve prefilter or postfilter as a JSON string;
|
|
`{}` when the script is empty.
|
|
operationId: getGlobalFilter
|
|
tags:
|
|
- Global filters
|
|
parameters:
|
|
- name: filter_type
|
|
in: path
|
|
required: true
|
|
description: Which global filter
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- prefilter
|
|
- postfilter
|
|
example: prefilter
|
|
responses:
|
|
"200":
|
|
description: The Sieve script
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: |
|
|
# global_sieve_before script
|
|
# global_sieve_before -> user sieve_before (mailcow UI) -> user sieve_after (mailcow UI) -> global_sieve_after
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/quota_notification:
|
|
post:
|
|
summary: Edit quota notification settings
|
|
description: >-
|
|
Saves sender, subject and template of the mails users get when their
|
|
mailbox crosses 80 % and 95 % of its quota. Fields not sent become
|
|
empty. The current values cannot be read through the API.
|
|
|
|
|
|
Messages: `saved_settings`; errors `redis_error`.
|
|
operationId: editQuotaNotification
|
|
tags:
|
|
- Quota notifications
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Ignored
|
|
attr:
|
|
type: object
|
|
properties:
|
|
sender:
|
|
type: string
|
|
description: Sender address (invalid address = empty)
|
|
subject:
|
|
type: string
|
|
description: Subject
|
|
html_tmpl:
|
|
type: string
|
|
description: HTML template (empty = the default template)
|
|
required:
|
|
- attr
|
|
example:
|
|
items:
|
|
- quota_notification
|
|
attr:
|
|
sender: quota-warning@example.org
|
|
subject: Quota warning
|
|
html_tmpl: ""
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/quota_notification_bcc:
|
|
post:
|
|
summary: Edit quota notification BCC of a domain
|
|
description: >-
|
|
Sets the addresses that get a copy of every quota warning of a domain;
|
|
the list replaces the old one and cannot be read through the API.
|
|
Admins and domain admins of the domain. Invalid addresses are left out,
|
|
the others are saved.
|
|
|
|
|
|
Messages: `saved_settings`; errors `goto_invalid`, `redis_error`.
|
|
operationId: editQuotaNotificationBcc
|
|
tags:
|
|
- Quota notifications
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Ignored
|
|
attr:
|
|
type: object
|
|
properties:
|
|
domain:
|
|
type: string
|
|
description: Domain or alias domain
|
|
bcc_rcpt:
|
|
type: string
|
|
description: Addresses, separated by space, comma, semicolon or newline
|
|
active:
|
|
type: [boolean, integer, string]
|
|
description: 1 = send the copies; becomes 0 when no valid address is left
|
|
required:
|
|
- domain
|
|
required:
|
|
- attr
|
|
example:
|
|
items:
|
|
- quota_bcc
|
|
attr:
|
|
domain: example.org
|
|
bcc_rcpt: |-
|
|
postmaster@example.org
|
|
helpdesk@example.org
|
|
active: "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/admin/all:
|
|
get:
|
|
summary: Get administrators
|
|
description: Lists all administrators, without domain administrators and the API key account.
|
|
operationId: getAdmins
|
|
tags:
|
|
- Administrators
|
|
responses:
|
|
"200":
|
|
description: The administrators, `{}` if there are none
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Admin"
|
|
example:
|
|
- username: admin
|
|
tfa_active: 1
|
|
tfa_active_int: 1
|
|
active: 1
|
|
active_int: 1
|
|
created: "2026-09-21 10:23:08"
|
|
attributes:
|
|
force_tfa: "0"
|
|
force_pw_update: "0"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/admin/{username}:
|
|
get:
|
|
summary: Get administrator
|
|
description: Details of one administrator.
|
|
operationId: getAdmin
|
|
tags:
|
|
- Administrators
|
|
parameters:
|
|
- name: username
|
|
in: path
|
|
required: true
|
|
description: Username of the administrator
|
|
schema:
|
|
type: string
|
|
example: admin
|
|
responses:
|
|
"200":
|
|
description: The administrator, `{}` if there is no administrator of this name
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Admin"
|
|
example:
|
|
username: admin
|
|
tfa_active: 0
|
|
tfa_active_int: 0
|
|
active: 1
|
|
active_int: 1
|
|
created: "2026-09-21 10:23:08"
|
|
attributes:
|
|
force_tfa: "0"
|
|
force_pw_update: "0"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/add/admin:
|
|
post:
|
|
summary: Create administrator
|
|
description: >-
|
|
Creates an administrator. The username is stored in lowercase and must
|
|
not be in use by an administrator or domain administrator. Without
|
|
`active: 1` the account is disabled.
|
|
|
|
|
|
Messages: `admin_added`; errors `object_exists`, `password_complexity`,
|
|
`password_mismatch`.
|
|
operationId: addAdmin
|
|
tags:
|
|
- Administrators
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Username (letters, digits, `_`, `.`, `-`; stored in lowercase)
|
|
password:
|
|
type: string
|
|
description: Password, must match the password policy
|
|
password2:
|
|
type: string
|
|
description: The password again
|
|
active:
|
|
type: [integer, string, boolean]
|
|
description: 1 = the account can log in, 0 = disabled
|
|
default: 0
|
|
required:
|
|
- username
|
|
- password
|
|
- password2
|
|
example:
|
|
username: admin2
|
|
password: "Rand0m-Passw0rd!"
|
|
password2: "Rand0m-Passw0rd!"
|
|
active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/admin:
|
|
post:
|
|
summary: Edit administrators
|
|
description: >-
|
|
Changes administrators. Fields not sent keep their value, but
|
|
`force_tfa` and `force_pw_update` are reset to 0; an empty `password`
|
|
keeps the password. FIDO2 keys are not moved on rename. The last active
|
|
administrator cannot be deactivated.
|
|
|
|
|
|
Messages: `admin_modified`; errors `username_invalid`,
|
|
`password_mismatch`, `password_complexity`; warning `no_active_admin`.
|
|
operationId: editAdmin
|
|
tags:
|
|
- Administrators
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
description: Username of the administrator, or a list of usernames
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
attr:
|
|
type: object
|
|
properties:
|
|
active:
|
|
type: [integer, string, boolean]
|
|
description: 1 = active, 0 = disabled
|
|
username_new:
|
|
type: string
|
|
description: New username (letters, digits, `_`, `.`, `-`)
|
|
password:
|
|
type: string
|
|
description: New password; empty or missing keeps the password
|
|
password2:
|
|
type: string
|
|
description: The new password again
|
|
force_tfa:
|
|
type: [integer, string, boolean]
|
|
description: 1 = the administrator must set up two-factor authentication at the next login
|
|
default: 0
|
|
force_pw_update:
|
|
type: [integer, string, boolean]
|
|
description: 1 = the administrator must change the password at the next login
|
|
default: 0
|
|
disable_tfa:
|
|
type: [integer, string, boolean]
|
|
description: Present (any value) = turn off two-factor authentication
|
|
required:
|
|
- items
|
|
- attr
|
|
example:
|
|
items:
|
|
- admin2
|
|
attr:
|
|
active: 1
|
|
password: "N3w-Passw0rd!"
|
|
password2: "N3w-Passw0rd!"
|
|
force_pw_update: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/delete/admin:
|
|
post:
|
|
summary: Delete administrators
|
|
description: >-
|
|
Deletes administrators with their two-factor authentication and FIDO2
|
|
keys.
|
|
|
|
|
|
Messages: `admin_removed`; error `username_invalid`.
|
|
operationId: deleteAdmin
|
|
tags:
|
|
- Administrators
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
description: Usernames of the administrators
|
|
items:
|
|
type: string
|
|
example:
|
|
- admin2
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/get/passwordpolicy:
|
|
get:
|
|
summary: Get password policy
|
|
description: The password policy for mailboxes, administrators and domain administrators.
|
|
operationId: getPasswordPolicy
|
|
tags:
|
|
- Password policy
|
|
responses:
|
|
"200":
|
|
description: The policy
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PasswordPolicy"
|
|
example:
|
|
length: "8"
|
|
chars: "1"
|
|
special_chars: "0"
|
|
lowerupper: "1"
|
|
numbers: "1"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/get/passwordpolicy/html:
|
|
get:
|
|
summary: Get password policy as HTML
|
|
description: >-
|
|
The password policy as HTML snippet in the default language, as shown
|
|
below password fields.
|
|
operationId: getPasswordPolicyHtml
|
|
tags:
|
|
- Password policy
|
|
responses:
|
|
"200":
|
|
description: The HTML snippet as a JSON string
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: <p class="help-block small">- Minimum password length is 8<br>- Must contain at least one alphabetic character<br>- Must contain lowercase and uppercase characters<br>- Must contain at least one number</p>
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/api/v1/edit/passwordpolicy:
|
|
post:
|
|
summary: Edit password policy
|
|
description: >-
|
|
Changes the password policy; fields not sent keep their value. Existing
|
|
passwords are not checked again.
|
|
|
|
|
|
Messages: `password_policy_saved`.
|
|
operationId: editPasswordPolicy
|
|
tags:
|
|
- Password policy
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
length:
|
|
type: [integer, string]
|
|
description: Minimum length; values below 3 keep the current length
|
|
chars:
|
|
type: [integer, string, boolean]
|
|
description: 1 = at least one letter
|
|
lowerupper:
|
|
type: [integer, string, boolean]
|
|
description: 1 = lowercase and uppercase letters
|
|
special_chars:
|
|
type: [integer, string, boolean]
|
|
description: 1 = at least one character that is no letter or digit
|
|
numbers:
|
|
type: [integer, string, boolean]
|
|
description: 1 = at least one digit
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
length: 12
|
|
chars: 1
|
|
lowerupper: 1
|
|
special_chars: 0
|
|
numbers: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/reset-password-notification:
|
|
post:
|
|
summary: Edit password reset e-mail
|
|
description: >-
|
|
Sets the password reset e-mail sent to the recovery address of a
|
|
mailbox. Fields not sent are saved as empty. With both templates empty
|
|
the defaults are used; without sender and subject, password reset is
|
|
off.
|
|
|
|
|
|
Placeholders: `{{username}}`, `{{username2}}` (recovery address),
|
|
`{{date}}`, `{{token_lifetime}}` (minutes), `{{hostname}}`, `{{link}}`.
|
|
|
|
|
|
Messages: `saved_settings`.
|
|
operationId: editPasswordResetNotification
|
|
tags:
|
|
- Password policy
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
from:
|
|
type: string
|
|
description: Sender address; an invalid address is saved as empty
|
|
subject:
|
|
type: string
|
|
description: Subject
|
|
text_tmpl:
|
|
type: string
|
|
description: Plain text template
|
|
html_tmpl:
|
|
type: string
|
|
description: HTML template (the text template becomes its alternative part)
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
from: noreply@example.org
|
|
subject: Reset your password
|
|
text_tmpl: "Hello {{username}}, open {{link}} within {{token_lifetime}} minutes to set a new password."
|
|
html_tmpl: "<p>Hello {{username}},</p><p><a href=\"{{link}}\">Set a new password</a> within {{token_lifetime}} minutes.</p>"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/app_links:
|
|
post:
|
|
summary: Edit app links
|
|
description: >-
|
|
Replaces the custom links of the Apps menu, sent as four lists of equal
|
|
length. If the lengths differ, nothing is saved, but `app_links` is
|
|
reported anyway. Empty lists remove all custom links.
|
|
|
|
|
|
Messages: `app_links`.
|
|
operationId: editAppLinks
|
|
tags:
|
|
- UI customization
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
app:
|
|
type: array
|
|
description: Names of the links
|
|
items:
|
|
type: string
|
|
href:
|
|
type: array
|
|
description: URLs shown on the login page and to users without `user_href`
|
|
items:
|
|
type: string
|
|
user_href:
|
|
type: array
|
|
description: URLs for logged-in accounts (`%u` = username); empty = `href`
|
|
items:
|
|
type: string
|
|
hide:
|
|
type: array
|
|
description: Per link, `0` shows it on the login page, any other value (even `false`) hides it
|
|
items:
|
|
type: [string, integer, boolean]
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
app:
|
|
- Wiki
|
|
- Webmail (Roundcube)
|
|
href:
|
|
- https://wiki.example.org
|
|
- https://mail.example.org/rc/
|
|
user_href:
|
|
- https://wiki.example.org
|
|
- https://mail.example.org/rc/?_user=%u
|
|
hide:
|
|
- "0"
|
|
- "1"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/custom_login:
|
|
post:
|
|
summary: Edit login page options
|
|
description: >-
|
|
Sets the login page options. All four are replaced: a missing option
|
|
counts as 0.
|
|
|
|
|
|
Messages: `custom_login_modified`.
|
|
operationId: editCustomLogin
|
|
tags:
|
|
- UI customization
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
hide_user_quicklink:
|
|
type: [integer, string, boolean]
|
|
description: 1 = hide the link to the user login page
|
|
default: 0
|
|
hide_domainadmin_quicklink:
|
|
type: [integer, string, boolean]
|
|
description: 1 = hide the link to the domain administrator login page
|
|
default: 0
|
|
hide_admin_quicklink:
|
|
type: [integer, string, boolean]
|
|
description: 1 = hide the link to the administrator login page
|
|
default: 0
|
|
force_sso:
|
|
type: [integer, string, boolean]
|
|
description: 1 = show only the Single Sign-On button (needs an OIDC identity provider)
|
|
default: 0
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
hide_user_quicklink: 0
|
|
hide_domainadmin_quicklink: 1
|
|
hide_admin_quicklink: 1
|
|
force_sso: 0
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/ip_check:
|
|
post:
|
|
summary: Edit IP check
|
|
description: >-
|
|
Turns the dashboard IP check on or off, which asks ipv4.mailcow.email
|
|
and ipv6.mailcow.email for the public addresses.
|
|
|
|
|
|
Messages: `ip_check_opt_in_modified`.
|
|
operationId: editIpCheck
|
|
tags:
|
|
- UI customization
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
ip_check_opt_in:
|
|
type: [integer, string, boolean]
|
|
description: 1/true = enabled; anything else or missing = disabled
|
|
default: 0
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
ip_check_opt_in: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/ui_texts:
|
|
post:
|
|
summary: Edit UI texts
|
|
description: >-
|
|
Sets the texts of the mailcow UI. All values are replaced: a missing
|
|
one is saved as empty.
|
|
|
|
|
|
Messages: `ui_texts`.
|
|
operationId: editUiTexts
|
|
tags:
|
|
- UI customization
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
title_name:
|
|
type: string
|
|
description: Title of the browser window (plain text); empty = "<hostname> - mail UI"
|
|
main_name:
|
|
type: string
|
|
description: Name shown on the start page (plain text); empty = "<hostname> - mail UI"
|
|
apps_name:
|
|
type: string
|
|
description: Name of the "Apps" menu (plain text); empty = "Apps"
|
|
help_text:
|
|
type: string
|
|
description: Help text below the login form (HTML)
|
|
ui_footer:
|
|
type: string
|
|
description: Footer of every page (HTML)
|
|
ui_announcement_text:
|
|
type: string
|
|
description: Announcement for all logged-in accounts and on the login page (HTML)
|
|
ui_announcement_type:
|
|
type: string
|
|
enum:
|
|
- info
|
|
- warning
|
|
- danger
|
|
description: Style of the announcement; other values are saved as empty
|
|
ui_announcement_active:
|
|
type: [integer, string, boolean]
|
|
description: Not empty and not 0 = show the announcement
|
|
default: 0
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
title_name: Example Mail
|
|
main_name: Example Mail
|
|
apps_name: Apps
|
|
help_text: "Questions? Write to <a href=\"mailto:support@example.org\">support@example.org</a>."
|
|
ui_footer: "<a href=\"https://example.org/imprint\">Imprint</a>"
|
|
ui_announcement_text: Maintenance on Saturday from 8 to 10 am.
|
|
ui_announcement_type: warning
|
|
ui_announcement_active: 1
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
/api/v1/edit/ui_theme:
|
|
post:
|
|
summary: Edit UI theme
|
|
description: >-
|
|
Selects the UI theme by its folder name in `data/web/css/themes/`.
|
|
|
|
|
|
Messages: `ui_theme_modified`; error `ui_theme_invalid`.
|
|
operationId: editUiTheme
|
|
tags:
|
|
- UI customization
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
attr:
|
|
type: object
|
|
properties:
|
|
ui_theme:
|
|
description: Folder name of the theme, empty = default theme; of a list only the first entry counts
|
|
oneOf:
|
|
- type: string
|
|
- type: array
|
|
items:
|
|
type: string
|
|
required:
|
|
- attr
|
|
example:
|
|
attr:
|
|
ui_theme: servercow
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/WriteResult"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
tags:
|
|
- name: Domains
|
|
description: >-
|
|
Domains, alias domains, domain templates, MTA-STS policies and
|
|
domain-wide footers
|
|
- name: Domain antispam policies
|
|
description: Sender allow lists (whitelists) and deny lists (blacklists) of domains
|
|
- name: Mailboxes
|
|
description: Mailboxes, their templates, tags, ACLs and logins
|
|
- name: Aliases
|
|
description: You can manage aliases
|
|
- name: Sync jobs
|
|
description: Using Syncjobs you can sync your mails with other email servers
|
|
- name: Logs
|
|
description: Logs of the mailcow containers and the UI
|
|
- name: Queue Manager
|
|
description: Manage the postfix mail queue
|
|
- name: Quarantine
|
|
description: Check what emails went to quarantine
|
|
- name: Fail2Ban
|
|
description: Manage the Netfilter fail2ban options
|
|
- name: DKIM
|
|
description: Generate, import, copy and delete DKIM keys
|
|
- name: Domain admin
|
|
description: Domain administrators, their domains and ACLs
|
|
- name: Single Sign-On
|
|
description: Login tokens for domain administrators
|
|
- name: Address Rewriting
|
|
description: BCC maps and recipient maps
|
|
- name: Outgoing TLS Policy Map Overrides
|
|
description: TLS policies for outgoing connections to single destinations
|
|
- name: oAuth Clients
|
|
description: Clients that use mailcow as OAuth2 server
|
|
- name: API Keys
|
|
description: API keys; service keys from mailcow.conf are read-only
|
|
- name: Groups
|
|
description: Mailbox groups (distribution lists, send-as rights, templates)
|
|
- name: Routing
|
|
description: Sender-dependent transports (relay hosts) and transport maps for outgoing mail
|
|
- name: Resources
|
|
description: Bookable resources (rooms, equipment, groups) for SOGo
|
|
- name: App Passwords
|
|
description: Separate passwords of a mailbox for single clients and protocols
|
|
- name: Status
|
|
description: Containers, mail storage, host and version
|
|
- name: Ratelimits
|
|
description: Edit domain ratelimits
|
|
- name: Cross-Origin Resource Sharing (CORS)
|
|
description: Origins and methods that may call the API from a browser
|
|
- name: Identity Provider
|
|
description: >-
|
|
External Identity Provider (Keycloak, OpenID Connect, LDAP): settings,
|
|
identity sync and links of mailboxes
|
|
- name: Mailbox user settings
|
|
description: >-
|
|
Settings a mailbox user changes on its own page (with the matching user
|
|
ACL): time-limited aliases, spam score, TLS policy, tagged mail,
|
|
Pushover. API keys can change them for any mailbox and must name the
|
|
mailbox; a mailbox user only for its own.
|
|
- name: Mailbox filters
|
|
description: Sieve filters of mailboxes, managed by admins and domain admins
|
|
- name: Mailbox antispam policies
|
|
description: Sender allow and deny lists of mailboxes
|
|
- name: Forwarding Hosts
|
|
description: >-
|
|
Hosts whose incoming mail is accepted unconditionally, e.g. servers that
|
|
forward mail to mailcow
|
|
- name: Rspamd
|
|
description: Rspamd settings rules, global regex maps, presets and statistics
|
|
- name: Global filters
|
|
description: Global Sieve filters that run before and after the filters of the mailboxes, Sieve presets
|
|
- name: Quota notifications
|
|
description: Mails to users whose mailbox is nearly full
|
|
- name: Administrators
|
|
description: Administrator accounts
|
|
- name: Password policy
|
|
description: Password rules and the password reset e-mail
|
|
- name: UI customization
|
|
description: Texts, links, login page and theme of the mailcow UI
|