From 1a5095c0f43cdefef8f1a772ac3c7559d1dc9f99 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it <75116288+FreddleSpl0it@users.noreply.github.com> Date: Tue, 10 Nov 2026 20:25:51 +0100 Subject: [PATCH] [Web] API: shorter descriptions --- data/web/api/openapi.yaml | 2614 ++++++++++++++----------------------- 1 file changed, 971 insertions(+), 1643 deletions(-) diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml index 97bf903eb..7daa49d41 100644 --- a/data/web/api/openapi.yaml +++ b/data/web/api/openapi.yaml @@ -1,46 +1,33 @@ openapi: 3.1.0 info: description: >- - mailcow is complete e-mailing solution with advanced antispam, antivirus, - nice UI and API. + The API of mailcow, the mail server suite with antispam, antivirus and a + web UI. - In order to use this API you have to create a API key and add your IP - address to the whitelist of allowed IPs this can be done by logging into the - Mailcow UI using your admin account, then go to Configuration > Access > - Edit administrator details > API. There you will find a collapsed API menu. + **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. - There are two types of API keys - - The read only key can only be used for all get endpoints - - The read write key can be used for all endpoints + **Requests**: `get` routes use GET, all others POST with + `Content-Type: application/json`. - You can create as many keys of both types as you need. Service keys - defined 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. + - 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 - **Requests** - - - `get` routes use `GET`, all other routes use `POST` (else `405`). - - `add` routes take the new object as the JSON body. - - `edit` routes take `{"items": [...], "attr": {...}}`: `items` names the - objects to change, `attr` holds the values to set. - - `delete` routes take the JSON array of the objects to delete. - - Send `Content-Type: application/json`. A body that is no valid JSON - is answered with `400`. - - **Answers** - - - Write routes answer with the list of messages of the call (`type` - `success`, `danger`, `warning` or `info`; `msg` is a key of the mailcow - language files, alone or with its values). A call without messages - answers `{"type": "success", "msg": "Task completed"}` or - `{"type": "error", "msg": "Cannot add item"}`. The HTTP status is 200 - in both cases: check `type`. - - Read routes answer with the object or list, `{}` or `[]` when there is - nothing. - - Unknown routes answer `404` with `{"type": "error", "msg": "route not found"}`. + **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" @@ -226,9 +213,7 @@ components: description: Aliases that can still be added domain_admins: type: string - description: >- - Comma-separated domain admins, `-` if none; only for admins (and - API keys) + description: Comma-separated domain admins, `-` if none; admins only tags: type: array items: @@ -497,10 +482,10 @@ components: `search.value` of this entry filter that column searchable: type: [boolean, string] - description: Column takes part in the global search + description: Column takes part in the global search; must be set orderable: type: [boolean, string] - description: Column may be sorted by + description: Column may be sorted by; must be set search: type: object properties: @@ -533,12 +518,7 @@ components: type: string UserAclName: type: string - description: >- - A user ACL: what the mailbox user may do in the UI (time-limited - aliases, TLS policy, spam score, allow/deny lists, tagged mail, sync - jobs, ActiveSync and SOGo reset, Pushover, quarantine actions, - attachments, notification interval and category, app passwords, - password reset) + description: "A user ACL: something the mailbox user may do in the UI" enum: - spam_alias - tls_policy @@ -629,10 +609,9 @@ components: Mailbox: type: object description: >- - Details of a mailbox. `max_new_quota`, `spam_aliases`, - `pushover_active`, `rl`, `rl_scope`, `is_relayed` and `sender_acl` are - missing in the reduced form; `tags` is missing when the mailbox has no - tags. + 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 @@ -725,7 +704,7 @@ components: description: 1 if the domain is relayed (backup MX) sender_acl: type: array - description: Addresses and @domains the mailbox may send as (internal, set by `sender_acl`) + description: Internal addresses and @domains the mailbox may send as items: type: string tags: @@ -755,22 +734,18 @@ components: - generic-oidc - ldap default: mailcow - description: >- - Where the user logs in; an external source is accepted only if it is - the configured identity provider, else mailcow is used + description: Login source; an external one only if it is the configured identity provider, else mailcow password: type: string format: password - description: >- - Password (authsource mailcow), checked against the password policy; - may be left empty together with `password2` for a shared mailbox + 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 that provides the defaults (default the first template) + description: ID of the mailbox template for the defaults (default the first) quota: type: [integer, string] description: Quota in MiB, 0 = unlimited @@ -832,7 +807,7 @@ components: type: [integer, string] enum: [0, 1, "0", "1"] default: 0 - description: Shared mailbox without a login of its own; members of groups open it + description: Shared mailbox without a login of its own, opened by group members quarantine_notification: type: string enum: @@ -887,7 +862,7 @@ components: password: type: string format: password - description: New password (authsource mailcow only), checked against the password policy + description: New password (authsource mailcow), checked against the password policy password2: type: string format: password @@ -898,7 +873,7 @@ components: - keycloak - generic-oidc - ldap - description: An external source is accepted only if it is the configured identity provider + 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) @@ -944,7 +919,7 @@ components: type: array items: type: string - description: Tags to add (existing tags stay; remove them with `delete/mailbox/tag/{mailbox}`) + description: Tags to add; existing tags stay (remove with `delete/mailbox/tag/{mailbox}`) tagged_mail_handler: type: string enum: @@ -954,8 +929,7 @@ components: sender_acl: description: >- Replaces the internal addresses and @domains the mailbox may send - as; `*` (admins only) allows every address, `["default"]` removes - all + as; `*` (admins only) allows all, `["default"]` removes all oneOf: - type: string - type: array @@ -963,9 +937,7 @@ components: type: string extended_sender_acl: type: string - description: >- - Replaces the external sender addresses or domains (not hosted on - this server), separated by space, comma or semicolon + description: Replaces the external sender addresses or domains, separated by space, comma or semicolon attribute_hash: type: string description: Internal; cleared when not sent @@ -1055,12 +1027,7 @@ components: const: mailbox attributes: type: object - description: >- - The settings: quota in bytes, tags, tagged_mail_handler, - quarantine_notification, quarantine_category, rl_value, rl_frame, - the flags force_pw_update, force_tfa, sogo_access, active, - tls_enforce_in, tls_enforce_out, imap_access ... dav_access and one - acl_ flag per user ACL + description: The settings as in the example; quota in bytes, one `acl_` flag per user ACL additionalProperties: true created: type: string @@ -1156,7 +1123,7 @@ components: type: string validity: type: integer - description: Unix time of expiry (0 for permanent aliases set by an edit) + description: Unix time of expiry (0 when made permanent by an edit) created: type: string modified: @@ -1269,16 +1236,16 @@ components: - desc columns: type: array - description: Column n of the table is `columns[n]` + 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 a filter by - `search.value` of this column only a column number selects - the column, other values filter the address + 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 @@ -1833,19 +1800,9 @@ components: DomainAdminAcl: type: string description: >- - ACL of a domain administrator (default in brackets): `syncjobs` sync - jobs (on), `quarantine` quarantine (on), `login_as` log in as mailbox - user (on), `sogo_access` direct SOGo access of users (on), - `app_passwds` app passwords (on), `bcc_maps` BCC maps (on), `pushover` - Pushover (off), `filters` filters (on), `ratelimit` rate limits (on), - `spam_policy` spam policy (on), `extend_sender_acl` sender ACL with - external addresses (off), `unlimited_quota` unlimited mailbox quota - (off), `protocol_access` protocol access of mailboxes (on), - `smtp_ip_access` SMTP IP restrictions (on), `alias_domains` alias - domains (off), `mailbox_relayhost` relay host of mailboxes (on), - `domain_relayhost` relay host of domains (on), `domain_desc` domain - description (off), `alias_external_goto` aliases with external - destinations (on), `mailbox_groups` mailbox groups (on) + 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 @@ -1921,9 +1878,9 @@ components: description: "`ro`: read-only (get routes only), `rw`: read/write. Required for a new key." allow_from: description: >- - IP addresses and CIDR networks the key may be used from: a list or - a string separated by spaces, commas, semicolons or newlines. An - edit replaces the list. + 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 @@ -2344,9 +2301,8 @@ components: address: type: string description: >- - Distribution address in the domain of the group (must not be used - by a mailbox, alias or spam alias); empty = no address. Wins over - `local_part`. + 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 @@ -2356,9 +2312,7 @@ components: - string items: type: string - description: >- - Mailboxes (regular mailboxes, any domain the caller manages); - replaces the manual members the caller may access + description: Regular mailboxes; replaces the manual members the caller may access add_members: type: - array @@ -2380,9 +2334,8 @@ components: items: type: string description: >- - Replaces the addresses the members may send as: existing mailbox or - alias addresses (not the group address, see `sender_allowed`) or - `@domain` for a domain or alias domain + 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 @@ -2412,10 +2365,10 @@ components: default: 1 imap_grants: description: >- - Replaces the mailboxes the members may open (Dovecot ACL on every - folder, shown as Shared/); the caller needs access to every - owner. `subscribe` = a cron subscribes the folders for every member - once (within 15 minutes). A JSON string of the list is accepted too. + Replaces the mailboxes the members may open as Shared/; 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 @@ -2446,9 +2399,8 @@ components: sogo_grants: description: >- Replaces the SOGo folders shared with the members; the caller needs - access to every owner. Pending until the owner opened SOGo once. - `subscribe` = a cron subscribes every member once. A JSON string of - the list is accepted too. + 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 @@ -2501,9 +2453,8 @@ components: idp_ref: type: string description: >- - Admins only: id of the Identity Provider group whose members the - identity sync keeps in the group (max. 255 characters); empty = - none + Admins only: Identity Provider group id to sync the members from + (max. 255 characters); empty = none MailboxGroup: type: object properties: @@ -2589,7 +2540,7 @@ components: - 1 state: type: string - description: pending until Dovecot has the ACL, failed when setting it failed (retried by a cron) + description: failed = setting the ACL failed, retried later enum: - pending - applied @@ -2696,9 +2647,9 @@ components: 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; - on add they default to off. The former connection attributes `host1`, - `port1`, `enc1` and `authmech1` are ignored (see `source_id`). + `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: @@ -2758,12 +2709,9 @@ components: custom_params: type: array description: >- - Extra imapsync options, replaces the stored list; empty list, empty - string or null = none. Each option must be allowed by - `GET /api/v1/get/syncjob_options`: `true` needs a value, `false` - must have none, a string is the regular expression the value must - match. Max. 100 options, values max. 1000 characters, each value is - passed as one argument. + 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: @@ -3098,11 +3046,10 @@ components: description: XOAUTH2, required, max. 500 characters oauth_extra_params: description: >- - XOAUTH2, optional: extra OAuth2 parameters as JSON object with - scalar values, or as JSON text (max. 4000 characters); empty = - none. `prompt`, `access_type`, `login_hint`, `domain_hint` and `hd` - go to the sign-in URL, all others to the token request; they never - replace client id, secret, scope or grant fields. + 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 @@ -3429,10 +3376,9 @@ components: - string - boolean description: >- - (0/1) Keycloak, LDAP; users disabled at the provider, or missing in - two complete sync runs, get login disabled (mailbox active = 2, mail - is still received); only mailboxes disabled by the sync are enabled - again + (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: @@ -3486,11 +3432,8 @@ components: IdentityProviderSettings: type: object description: >- - Stored settings (see `IdentityProviderAttributes`). Values are strings - as stored, except `redirect_url_extra`, `mappers` and `templates` - (lists) and `use_ssl`, `use_tls`, `login_provisioning`, - `ignore_ssl_error` (booleans; `login_provisioning` is `1` when never - stored). Secrets are `*` for read-only API keys. + Stored settings (see `IdentityProviderAttributes`), mostly as strings. + Secrets are `*` for read-only API keys. properties: authsource: type: string @@ -3913,9 +3856,7 @@ components: name: tags in: query required: false - description: >- - Comma-separated tags: only mailboxes with a tag that contains one of - them (substring match) + description: "Comma-separated tags: only mailboxes with a tag containing one of them" schema: type: string example: sales,support @@ -4093,25 +4034,13 @@ paths: operationId: addAlias description: >- Creates an alias for every address in `address`, all with the same - destinations. Administrators and API keys may use every domain, domain - administrators their own domains. + 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. - Every address is checked on its own and gets its own message: - `alias_added` (address, new ID) on success, else `is_alias_or_mailbox`, - `domain_not_found`, `is_spam_alias`, `alias_invalid` or - `access_denied`. An address that is also one of the destinations is - skipped without message. `max_alias_exceeded` (the domain has no - aliases left) stops the call at that address. Nothing is created with - `comment_too_long`, `alias_empty`, `goto_empty` or when no destination - is valid (`goto_invalid`: no e-mail address or a resource; - `external_goto_denied`: not a mailcow domain while external - destinations are disabled by `ALIAS_DISABLE_EXTERNAL_DOMAINS` or by the - ACL of the domain administrator). - - - Flags that are left out 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: @@ -4121,32 +4050,26 @@ paths: address: type: string description: >- - Alias address, `@example.org` for a catch-all of the - domain. Several addresses can be separated by spaces, - commas, semicolons or line breaks. The domain must be a - mailcow domain or alias domain (IDN domains are stored in - punycode). + 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 `goto_null`, - `goto_spam` or `goto_ham` is 1; ignored then. + semicolons or line breaks; required unless a `goto_*` flag + is 1 goto_null: type: [boolean, integer, string] - description: >- - 1 = discard the mail silently (destination - `null@localhost`). Wins over `goto_spam` and `goto_ham`. + 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 (destination `spam@localhost`). - Wins over `goto_ham`. + 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 (destination `ham@localhost`) + description: 1 = learn the mail as ham default: 0 active: type: [boolean, integer, string] @@ -4154,15 +4077,11 @@ paths: default: 0 sogo_visible: type: [boolean, integer, string] - description: >- - 1 = the alias is a selectable sender in SOGo (aliases that - point to at least one local mailbox) + description: 1 = selectable sender in SOGo (aliases with a local mailbox as destination) default: 0 internal: type: [boolean, integer, string] - description: >- - 1 = internal alias: only reachable from its own domain and - the alias domains of it + description: 1 = only reachable from its own domain and its alias domains default: 0 sender_allowed: type: [boolean, integer, string] @@ -4170,11 +4089,11 @@ paths: default: 0 public_comment: type: string - description: Comment shown to the users, at most 160 characters + description: Comment shown to the users maxLength: 160 private_comment: type: string - description: Comment for administrators, at most 160 characters + description: Comment for administrators maxLength: 160 required: - address @@ -4200,14 +4119,13 @@ paths: summary: Create a time-limited alias operationId: addTimeLimitedAlias description: >- - Creates a random alias (e.g. `kahd.osuwe@example.org`) that delivers to - the mailbox until it expires. Needs the user ACL `spam_alias`. API keys - must send `username` (without it the session user "API" is used and - the call fails with `domain_invalid`); a mailbox user may leave it out - (own mailbox) and gets `access_denied` for other mailboxes. `domain` - must be the domain of the mailbox or one of its alias domains - (`domain_invalid`). Errors: `validity_missing` (validity out of range). - Success: `mailbox_modified`. + 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: @@ -4253,13 +4171,11 @@ paths: post: summary: Create API key description: >- - Creates an API key with a random value. The answer does not contain the - value: read it with `get/api-key/all`. Without `skip_ip_check` the key - needs at least one IP address or network in `allow_from`. + Creates an API key with a random value; read the value with + `get/api-key/all`. Without `skip_ip_check`, `allow_from` is required. - Success: `api_key_added` (with the description, else the ID). Errors: - `api_key_access_invalid`, `api_key_description_invalid`, + Messages: `api_key_added`; errors `api_key_access_invalid`, `api_key_network_invalid`, `ip_list_empty`. operationId: addApiKey tags: @@ -4293,12 +4209,12 @@ paths: summary: Create an app password operationId: addAppPassword description: >- - Adds an app password to a mailbox: a separate password for a client, - valid only for the protocols listed. Needs the user ACL `app_passwds`. - API keys must send `username` (without it the session user "API" is - used and the call fails with `access_denied`); a mailbox user may leave - it out (own mailbox). Errors: `access_denied`, `password_complexity`, - `password_mismatch`, `app_name_empty`. Success: `app_passwd_added`. + 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: @@ -4366,16 +4282,11 @@ paths: operationId: addBccMap description: >- Sends a hidden copy of the mail of a domain or address to `bcc_dest`. - Administrators, API keys and domain administrators with the BCC maps - ACL may call it (domain administrators for their domains). The local - destination is not informed when the copy cannot be delivered. + Domain administrators need the BCC maps ACL. Undeliverable copies are + not reported to the local destination. - Messages: `bcc_saved`; `invalid_bcc_map_type`, `bcc_empty`, - `bcc_must_be_email`, `bcc_exists` (same `local_dest` and `type`), - `access_denied` (no ACL, a domain or address the caller does not - manage, or an address that is no mailbox or alias). A `local_dest` that - is neither a domain nor an e-mail address answers `Cannot add item`. + Messages: `bcc_saved`; errors `bcc_must_be_email`, `bcc_exists`. requestBody: content: application/json: @@ -4384,14 +4295,10 @@ paths: properties: local_dest: type: string - description: >- - A mailcow domain (stored as `@example.org`, IDN in - punycode) or the address of a mailbox or alias + 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) + description: One e-mail address that gets the copies (use an alias for several) type: type: string enum: @@ -4424,11 +4331,11 @@ paths: post: summary: Generate DKIM keys description: >- - Generates an RSA DKIM key for each domain. Every domain must be a - domain or alias domain the caller has access to and must not have a - key yet. Success `dkim_added`, errors `dkim_domain_or_sel_invalid` - (invalid domain or selector, key exists, key generation failed), - `access_denied`. + 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 @@ -4453,7 +4360,7 @@ paths: description: Selector (letters, digits, `-`, `_`, `.`) key_size: type: [integer, string] - description: RSA key size in bits (the UI offers 1024, 2048, 3072, 4096) + description: RSA key size in bits example: domains: example.org, example.net dkim_selector: dkim @@ -4469,11 +4376,11 @@ paths: post: summary: Copy a DKIM key to other domains description: >- - Copies the DKIM key and selector of `from_domain` to the domains in - `to_domain`, replacing their keys. Admins only. The target names are - not checked. Success `dkim_duplicated` per target, errors - `access_denied`, `dkim_domain_or_sel_invalid` (`from_domain` has no - key). + 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 @@ -4513,23 +4420,14 @@ paths: post: summary: Add a domain description: >- - Adds a domain. Admins only (API keys are admins). Quotas are in MiB. - Values that are not sent come from the domain template given in - `template`, else from the first domain template (`Default`). - `relay_all_recipients` = 1 sets `backupmx`, `relay_unknown_only` = 1 - sets both. Besides the domain this sets the rate limit (`rl_value`, - `rl_frame`) and creates a DKIM key (`key_size`, `dkim_selector`; the - Default template creates a 2048 bit key with selector `dkim`), so the - answer can hold `rl_saved` and `dkim_added` (or - `domain_add_dkim_available` when a key exists already) before - `domain_added`. Errors: `access_denied`, - `mailbox_defquota_exceeds_mailbox_maxquota`, - `mailbox_quota_exceeds_domain_quota`, `defquota_empty`, - `maxquota_empty`, `domain_invalid`, `object_is_not_numeric`, - `domain_exists` (also for an alias domain of that name), - `domain_cannot_match_hostname`. SOGo knows the domain only after a - restart (`restart_sogo`); a failed restart answers - `domain_added_sogo_failed` (warning) although the domain was added. + 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 @@ -4550,9 +4448,7 @@ paths: description: Description, default the domain name template: type: [integer, string] - description: >- - ID of the domain template that gives the values not sent - (see get/domain/template/all); default the first template + description: ID of the domain template for fields not sent aliases: type: [integer, string] description: Max. number of aliases @@ -4575,8 +4471,7 @@ paths: gal: type: [integer, string] enum: [0, 1, "0", "1"] - description: >- - Global address list in SOGo (all objects of the domain) + description: Global address list in SOGo backupmx: type: [integer, string] enum: [0, 1, "0", "1"] @@ -4585,23 +4480,21 @@ paths: type: [integer, string] enum: [0, 1, "0", "1"] description: >- - Relay all recipients; else a mailbox is needed for every - recipient to relay. 1 sets `backupmx`. + 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 non-existing mailboxes only, existing mailboxes are - delivered locally. 1 sets `backupmx` and - `relay_all_recipients`. + 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; tags beyond the tagging limit - (`TAGGING_LIMIT`, 25) are dropped with the warning - `tag_limit_exceeded` + 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 @@ -4614,9 +4507,7 @@ paths: description: Selector of the DKIM key that is created key_size: type: [integer, string] - description: >- - RSA key size in bits of the DKIM key that is created (the - UI offers 1024, 2048, 3072, 4096); empty or 0 = no key + 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"] @@ -4653,19 +4544,15 @@ paths: post: summary: Create domain administrator description: >- - Creates a domain administrator, who manages mailboxes, aliases and - the other objects of the given domains. The username is converted to - lowercase; it may only contain letters, digits, `_`, `.` and `-` and - must not be used by a mailbox, an administrator or a domain - administrator. The new account gets the default ACLs (see - `edit/da-acl`). + 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. - Success: `domain_admin_added`. Errors: `domain_invalid` (no domain or an - unknown domain), `username_invalid`, `object_exists`, - `password_complexity`, `password_mismatch`. Unknown domains are skipped - with `domain_invalid`; if none of the domains exists, the account is not - created although `domain_admin_added` is reported too. + Messages: `domain_admin_added`; errors `domain_invalid`, + `object_exists`, `password_complexity`, `password_mismatch`. operationId: addDomainAdmin tags: - Domain admin @@ -4694,9 +4581,7 @@ paths: type: string active: type: [integer, string, boolean] - description: >- - 1 = the account can log in, 0 = disabled. Missing counts as - 0: send `1` for a usable account. + description: 1 = the account can log in, 0 = disabled default: 0 required: - username @@ -4722,15 +4607,12 @@ paths: post: summary: Issue domain administrator login token description: >- - Issues a one-time login token for a domain administrator. Opening - `https:///domainadmin/mailbox?sso_token=` in a - browser logs in as this domain administrator without password or - two-factor authentication. The token is valid for 30 seconds, can be - used once and only works for an active domain administrator. + Issues a one-time login token for an active domain administrator, valid + for 30 seconds. Opening `/domainadmin/mailbox?sso_token=` on the + mailcow host logs in without password or two-factor authentication. - Errors: `access_denied`, `object_doesnt_exist` (no domain - administrator of this name). + Messages: error `object_doesnt_exist`. operationId: issueDomainAdminSsoToken tags: - Single Sign-On @@ -4773,13 +4655,11 @@ paths: post: summary: Edit domain administrator ACLs description: >- - Sets the ACLs (permissions) of domain administrators: the ACLs in - `da_acl` are granted, all others are revoked. An empty or missing - `da_acl` revokes every ACL. + Grants the ACLs in `da_acl` and revokes all others; an empty or missing + `da_acl` revokes all. - One message per account. Success: `acl_saved`. Error: `Cannot - determine current ACL` (no domain administrator of this name). + Messages: `acl_saved`; error `Cannot determine current ACL`. operationId: editDomainAdminAcl tags: - Domain admin @@ -4841,21 +4721,15 @@ paths: post: summary: Edit domain administrators description: >- - Changes domain administrators. Attributes that are not sent keep their - value, except `force_tfa` and `force_pw_update`, which are set to 0 when - they are missing. `domains` replaces the list of domains; an empty or - missing list keeps it. The password is only changed when `password` is - not empty. Renaming an account moves its ACLs, two-factor - authentication and the sync job sources it created to the new name - (FIDO2 keys stay with the old name). + 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. - One message per account. Success: `domain_admin_modified`. Errors: - `access_denied` (no domain administrator of this name), - `domain_invalid`, `username_invalid` (invalid `username_new` or the - name of another domain administrator). A password that does not match - `password2` or the policy (`password_mismatch`, `password_complexity`) - stops the call, after the domains were already saved. + Messages: `domain_admin_modified`; errors `domain_invalid`, + `username_invalid`, `password_mismatch`, `password_complexity`. operationId: editDomainAdmin tags: - Domain admin @@ -4905,9 +4779,7 @@ paths: default: 0 disable_tfa: type: [integer, string, boolean] - description: >- - Present (with any value) = deactivate the two-factor - authentication of the account + description: Present (any value) = turn off two-factor authentication required: - items - attr @@ -4931,11 +4803,12 @@ paths: post: summary: Add a sender to a domain allow or deny list description: >- - Adds an entry to the allow list (`wl`) or deny list (`bl`) of a domain. - Needs the ACL `spam_policy` (API keys have it). Success - `domain_modified`, errors `access_denied` (also for an invalid domain or - list), `policy_list_from_invalid`, `policy_list_from_exists` (the sender - is on one of the lists already). + 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 @@ -4960,8 +4833,8 @@ paths: object_from: type: string description: >- - Sender address or pattern, `*` as wildcard (e.g. - `*@example.com`); letters, digits and `@ _ . - *` + Sender address or pattern with `*` as wildcard; letters, + digits and `@ _ . - *` example: domain: example.org object_list: wl @@ -4980,15 +4853,12 @@ paths: summary: Add forwarding hosts operationId: addForwardingHost description: >- - Adds hosts whose incoming mail is accepted unconditionally: no DNSBL - checks, no greylisting, spam is never rejected. A host or domain name - is resolved to the addresses of its SPF record, else its MX hosts, else - its A/AAAA records; every address becomes an entry with the name as - `source`. Administrators and API keys only. + 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` (the addresses), `invalid_host` - (nothing resolved), `access_denied`, `redis_error`. + Messages: `forwarding_host_added`; errors `invalid_host`. requestBody: content: application/json: @@ -5002,10 +4872,7 @@ paths: or domain name filter_spam: type: [boolean, integer, string] - description: >- - 1 = scan the mail of the hosts for spam (it can be filed - into the junk folder, never rejected); anything else = do - not scan it + description: 1 = scan the mail for spam (junk folder, never rejected); else not default: 0 required: - hostname @@ -5026,9 +4893,8 @@ paths: summary: Update forwarding hosts operationId: editForwardingHost description: >- - Turns the spam filter of forwarding hosts on or off. Administrators and - API keys only. Per host: `object_modified`, `access_denied` (unknown - host), `redis_error`. Without `keep_spam` the spam filter is turned on. + Turns the spam filter of forwarding hosts on or off; without + `keep_spam` it is turned on. requestBody: content: application/json: @@ -5049,9 +4915,7 @@ paths: properties: keep_spam: type: [boolean, integer, string] - description: >- - 1 = do not scan the mail of the host for spam; anything - else = scan it + description: 1 = do not scan the mail for spam; else scan it required: - items - attr @@ -5075,22 +4939,14 @@ paths: summary: Create a mailbox operationId: addMailbox description: >- - Creates the mailbox `local_part@domain` with its alias entry, quota - record and user ACL. Fields that are not sent take the values of the - mailbox template given in `template` (by default the first template, - "Default"). + 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. - Admins and domain admins (for their domains) may call it, mailbox users - get `access_denied`. Checks: valid address (`mailbox_invalid`), domain - exists (`domain_not_found`), address not in use by a mailbox, alias or - time-limited alias (`object_exists`, `is_alias`, `is_spam_alias`), - password policy (`password_complexity`, `password_mismatch`), mailbox - count and quota limits of the domain (`max_mailbox_exceeded`, - `mailbox_quota_exceeded`, `mailbox_quota_left_exceeded`), quota 0 - (unlimited) needs the `unlimited_quota` ACL (`unlimited_quota_acl`). - Success: `mailbox_added`. Tags after the 26th are dropped with the - warning `tag_limit_exceeded`. + Messages: `mailbox_added`; errors `object_exists`, `domain_not_found`, + `password_complexity`, `max_mailbox_exceeded`, + `mailbox_quota_exceeded`. requestBody: required: true content: @@ -5124,32 +4980,15 @@ paths: post: summary: Create mailbox group description: >- - Creates a mailbox group in a domain. With an address the group is a - distribution list: mail to the address goes to all members (the group - keeps an alias row for it that the alias API shows read-only, and it - counts against the alias limit of the domain; it is inactive while the - group is inactive or has no members). A group can also let - its members send as other addresses (`send_as`, `sender_allowed`), open - other mailboxes (`imap_grants`), see shared SOGo folders (`sogo_grants`) - and get a mailbox template (`template_id`). + 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. - Admins (every read/write API key) may create groups in every domain and - set `template_id`, `priority` and `idp_ref`; domain admins need the - `mailbox_groups` ACL and may only use their domains and mailboxes. - Members must be regular mailboxes (no resources). - - - Answers `group_added` plus warnings of the follow-up work - (`group_too_many_members` when a group with an address has more than - 1000 members, `group_template_failed`, `group_imap_grant_failed`, - `group_subscription_failed`, `group_sogo_init_failed`; failed steps - are retried by a cron). Errors (nothing is written): `domain_not_found`, - `access_denied`, `group_name_invalid`, `group_description_invalid`, - `object_exists` (name exists in the domain), `group_address_invalid`, - `is_alias_or_mailbox`, `max_alias_exceeded`, `group_member_invalid`, - `group_member_idp`, `group_send_as_invalid`, `group_grant_invalid`, - `template_id_invalid`, `group_priority_invalid`. + 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 @@ -5196,12 +5035,11 @@ paths: post: summary: Create OAuth2 client description: >- - Creates an OAuth2 client with a random client ID and secret and the - scope `profile`. The answer does not contain them: read them with + Creates an OAuth2 client with random ID and secret; read them with `get/oauth2-client/all`. The redirect URI is not validated. - Success: `Added client access`. + Messages: `Added client access`. operationId: addOAuth2Client tags: - oAuth Clients @@ -5233,13 +5071,13 @@ paths: summary: Create a recipient map operationId: addRecipientMap description: >- - Replaces the recipient address of mail before delivery: mail to - `recipient_map_old` goes to `recipient_map_new`. Administrators and API - keys only (other callers get `Cannot add item`). + Rewrites the recipient before delivery: mail to `recipient_map_old` + goes to `recipient_map_new`. - Messages: `recipient_map_entry_saved`; `invalid_recipient_map_old`, - `invalid_recipient_map_new`, `recipient_map_entry_exists`. + Messages: `recipient_map_entry_saved`; errors + `invalid_recipient_map_old`, `invalid_recipient_map_new`, + `recipient_map_entry_exists`. requestBody: content: application/json: @@ -5248,10 +5086,7 @@ paths: properties: recipient_map_old: type: string - description: >- - Original recipient: an e-mail address or a domain (stored - as `@example.org`, IDN in punycode; a leading `@` is - optional) + 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 @@ -5280,16 +5115,13 @@ paths: summary: Create a sender-dependent transport operationId: addRelayhost description: >- - Adds a relay host for outgoing mail. Domains and mailboxes use it when - their `relayhost` attribute is set to its ID (edit/domain, - edit/mailbox). The service is always `smtp:` (TLS when offered, no - SMTPS). The new entry is always active. Colons in `username` and - `password` are stored as `\:` (in the password as `\\:`); edit/relayhost - stores both unchanged. Administrators and API keys only. + 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` (without the host name), - `invalid_host` (empty `hostname`), `access_denied`, `mysql_error`. + Messages: `relayhost_added`; errors `invalid_host`. requestBody: content: application/json: @@ -5298,9 +5130,7 @@ paths: properties: hostname: type: string - description: >- - Next hop: `host`, `host:25`, `[host]:587`, `[192.0.2.1]` - or `[192.0.2.1]:25` + 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 @@ -5329,13 +5159,13 @@ paths: summary: Create a resource operationId: addResource description: >- - Creates a bookable resource (room, equipment, group) for SOGo. Its - address is made of the letters and digits of the description and the - domain (description "Meeting Room 1" → `MeetingRoom1@example.org`). - Admins and domain admins (for their domains). Errors: - `resource_invalid` (address or kind invalid), `description_invalid`, - `domain_invalid`, `access_denied`, `object_exists`, `is_alias`, - `is_spam_alias`, `domain_not_found`. Success: `resource_added`. + 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: @@ -5364,9 +5194,8 @@ paths: type: [integer, string] default: 0 description: >- - Booking rule: 0 always free (bookings are not limited and - do not block), -1 unlimited but shown as busy when booked, - n ≥ 1 at most n overlapping bookings; values below -1 mean -1 + 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"] @@ -5389,25 +5218,16 @@ paths: post: summary: Create sync job description: >- - Creates a sync job that copies the remote account `user1` of a sync - source into a local mailbox. Host, port, encryption and authentication - come from the source (`source_id`); the job only carries the remote - login. Needs the `syncjobs` ACL (admins and API keys have it); the - caller must have access to the local mailbox. An API key must name the - mailbox in `username` (`no_user_defined` otherwise), mailbox users - always create jobs for their own mailbox. + 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`. - Answers `mailbox_modified` with the local mailbox. Errors: - `access_denied` (no access to the mailbox, `mins_interval` missing or - not 1-43800, `exclude` no valid regular expression), `no_user_defined`, - `imapsync_user1_invalid`, `imapsync_source_unavailable` (source unknown, - invisible to the caller or inactive), `password_empty`, - `imapsync_source_oauth_connect_required` (XOAUTH2 authorization_code - source without a sign-in of the mailbox for `user1`), `object_exists` - (the mailbox already syncs `user1` from this source), - `imapsync_custom_params_format`, `imapsync_custom_param_invalid`, - `imapsync_custom_param_value`. Passwords are logged as `*`. + 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 @@ -5426,8 +5246,8 @@ paths: username: type: string description: >- - Local mailbox the job syncs into (`user2`); cannot be - changed later. Optional for mailbox users (own mailbox). + Local mailbox to sync into (`user2`), cannot be changed + later; users may leave it out - $ref: "#/components/schemas/SyncJobAttributes" example: username: alice@example.org @@ -5455,32 +5275,17 @@ paths: post: summary: Create sync source description: >- - Creates a reusable IMAP sync source: server, encryption and - authentication of a remote system that sync jobs use by `source_id`. - Password sources (PLAIN, LOGIN, CRAM-MD5) take the password from each - job, XOAUTH2 sources carry an OAuth2 client (client_credentials: one - token of the source for every mailbox of the tenant; authorization_code: - every mailbox owner signs in once in the mailcow UI). The creator is - stored in `created_by` (`API` for API keys); names are unique per - creator. Needs the `syncjobs` ACL. Only admins create `all` sources; - XOAUTH2 sources are created by admins and domain admins only. OAuth2 - endpoints must be https:// URLs with a valid host name; for sources - not created by a superadmin or an API key every resolved address must - also be public. + 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. - A client_credentials source fetches its token while it is saved: the - source is saved even when that fails, the answer then also has - `imapsync_source_token_refresh_failed`. Answers - `imapsync_source_added`. Errors (nothing is written): - `imapsync_source_name_invalid`, `imapsync_source_description_invalid`, - `imapsync_source_host_invalid`, `imapsync_source_port_invalid`, - `imapsync_source_enc_invalid`, `imapsync_source_auth_invalid`, - `imapsync_source_oauth_required`, `imapsync_source_oauth_invalid`, - `imapsync_source_oauth_endpoint_invalid`, - `imapsync_source_oauth_extra_invalid`, `imapsync_source_scope_empty`, - `access_denied` (scope or targets not allowed), `object_exists`. - Secrets are logged as `*`. + 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 @@ -5537,15 +5342,12 @@ paths: summary: Create a TLS policy map operationId: addTlsPolicyMap description: >- - Sets the TLS policy Postfix uses for outgoing connections to a - destination (`smtp_tls_policy_maps`). Administrators and API keys only - (other callers get `Cannot add item`). + Sets the TLS policy for outgoing connections to a destination. - Messages: `tls_policy_map_entry_saved`; `tls_policy_map_dest_invalid` - (empty, `.`, `*` or `@`), `tls_policy_map_parameter_invalid`, - `tls_policy_map_entry_exists`. The backend does not check `policy`; the - database only takes the listed values. + 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: @@ -5555,8 +5357,8 @@ paths: dest: type: string description: >- - Destination, e.g. `example.org`, `.example.org` (its - subdomains) or `[mail.example.org]:25`; IDN in punycode + Destination: a domain, `.example.org` for its subdomains or + a host like `[mail.example.org]:25` policy: type: string description: >- @@ -5573,9 +5375,7 @@ paths: - secure parameters: type: string - description: >- - Empty or space-separated `name=value` attributes, e.g. - `protocols=!SSLv2 ciphers=medium exclude=3DES` + description: Space-separated `name=value` attributes, may be empty default: "" active: type: [boolean, integer, string] @@ -5603,25 +5403,15 @@ paths: summary: Create transport maps operationId: addTransport description: >- - Routes mail for the destinations over a next hop. A transport map - entry overrules a sender-dependent transport. The service is always - `smtp:` (TLS when offered, no SMTPS); addresses matching `/localhost$/` - are always delivered locally. Administrators and API keys only. + 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. - One entry is created per destination. All entries with the same next - hop share one set of credentials: `username` and `password` are - written to every existing entry of `nexthop`. - - - Messages: `relayhost_added` (without names); `invalid_nexthop` - (empty), `invalid_nexthop_authenticated` (the next hop exists with - another user name), `next_hop_interferes`, `next_hop_interferes_any` - (`host` and `[host]:port` cannot be used side by side) stop the call; - `transport_dest_exists` and `invalid_destination` drop the - destination. The destinations are only checked when other transport - maps exist. Without any valid destination the answer is the messages - or `Cannot add item`. + Messages: `relayhost_added`; errors `transport_dest_exists`, + `invalid_destination`, `next_hop_interferes`, + `invalid_nexthop_authenticated`. requestBody: content: application/json: @@ -5631,16 +5421,13 @@ paths: destination: type: string description: >- - Destinations, separated by spaces, commas, semicolons or - line breaks: `example.org`, `.example.org` (its - subdomains), `*` or `box@example.org`. With `is_mx_based` - a regular expression matched against the MX name of the - recipient domain, e.g. `.*\.google\.com`. + 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 (put in - brackets automatically) + description: "`host`, `host:25`, `[host]:25` or an IP address (bracketed automatically)" username: type: string description: SMTP user name, empty for no authentication @@ -5681,10 +5468,11 @@ paths: summary: Delete aliases operationId: deleteAlias description: >- - Deletes the aliases and the send-as rights granted for their addresses - (`alias_removed` per alias). Unknown aliases and aliases of domains the - caller does not manage answer `access_denied`; distribution addresses - of mailbox groups `alias_group_managed`. + 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: @@ -5707,11 +5495,10 @@ paths: post: summary: Delete API keys description: >- - Deletes API keys. Service keys from mailcow.conf cannot be deleted here. + Deletes API keys. Service keys from mailcow.conf cannot be deleted. - One message per key. Success: `api_key_deleted`. Errors: - `access_denied` (no key with this ID), `api_key_service_locked`. + Messages: `api_key_deleted`; error `api_key_service_locked`. operationId: deleteApiKey tags: - API Keys @@ -5740,11 +5527,8 @@ paths: summary: Delete app passwords operationId: deleteAppPassword description: >- - Deletes app passwords by ID. Needs the user ACL `app_passwds` and - access to the owning mailbox (API keys: any). Messages: - `app_passwd_removed` per ID; the first unknown ID - (`app_passwd_id_invalid`) or foreign ID (`access_denied`) stops the - call. + Deletes app passwords by ID. Needs the user ACL `app_passwds`. The + first unknown or foreign ID stops the call. requestBody: required: true content: @@ -5771,9 +5555,11 @@ paths: summary: Delete BCC maps operationId: deleteBccMap description: >- - Deletes BCC maps by ID (`bcc_deleted` per map, `access_denied` for a - map of a domain the caller does not manage). A non-numeric ID stops the - call. Same callers as add/bcc. + Deletes BCC maps by ID. Same callers as add/bcc. A non-numeric ID stops + the call. + + + Messages: `bcc_deleted`. requestBody: content: application/json: @@ -5796,9 +5582,8 @@ paths: post: summary: Delete DKIM keys description: >- - Deletes the DKIM keys of domains. Admins only. Success `dkim_removed` - per domain (also when it had no key), errors `access_denied`, - `dkim_domain_or_sel_invalid`. + Deletes the DKIM keys of domains. Answers `dkim_removed` also for + domains without a key. operationId: deleteDkimKeys tags: - DKIM @@ -5824,13 +5609,12 @@ paths: post: summary: Delete domains description: >- - Deletes domains. Admins only. A domain that still has mailboxes or - resources is kept (`domain_not_empty`). With the domain go its aliases, - alias domains, domain admin assignments, BCC maps, MTA-STS policy, spam - policies, mailbox group data and rate limit; domain admins left without - any domain are deleted. Its mail storage is moved to the garbage - collector of Dovecot (a failure is a warning). The DKIM key is kept. Success `domain_removed`, errors `access_denied`, - `domain_invalid`. + 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 @@ -5857,12 +5641,10 @@ paths: summary: Delete domain administrators description: >- Deletes domain administrators with their ACLs, two-factor - authentication and FIDO2 keys; sync job sources they created are - released. The domains and their mailboxes stay. + authentication and FIDO2 keys. - One message per account. Success: `domain_admin_removed`. Error: - `username_invalid` (no domain administrator of this name). + Messages: `domain_admin_removed`; error `username_invalid`. operationId: deleteDomainAdmin tags: - Domain admin @@ -5888,10 +5670,12 @@ paths: post: summary: Delete entries of domain allow and deny lists description: >- - Deletes allow or deny list entries of domains by their `prefid` (see - get/policy_wl_domain and get/policy_bl_domain). Needs the ACL - `spam_policy`. Success `item_deleted` per entry, error `access_denied` - (non-numeric ID, entry of a mailbox or unknown entry). + 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 @@ -5921,8 +5705,8 @@ paths: summary: Delete forwarding hosts operationId: deleteForwardingHost description: >- - Removes forwarding hosts (`forwarding_host_removed` per host, also for - hosts that do not exist). Administrators and API keys only. + Removes forwarding hosts, answering `forwarding_host_removed` also for + hosts that do not exist. requestBody: content: application/json: @@ -5948,10 +5732,9 @@ paths: summary: Get forwarding hosts operationId: getForwardingHosts description: >- - `all` lists the forwarding hosts (administrators and API keys), a host - address returns that entry (every logged-in role). `{}` if there is - none. Networks (`198.51.100.0/24`) cannot be read one by one: the path - ends at the slash. + `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 @@ -5999,14 +5782,9 @@ paths: summary: Delete mailboxes operationId: deleteMailbox description: >- - Deletes mailboxes with everything that belongs to them: maildir (moved - to the garbage collector), aliases pointing only to them, ACLs, - quarantine, filters, policies, time-limited aliases, sync jobs, SOGo - data, BCC maps, OAuth tokens, 2FA keys, rate limit; the address is - removed from the targets of other aliases. Admins and domain admins - (for their domains); a mailbox user session passes the check for its - own mailbox and can delete it. Messages per mailbox: `mailbox_removed` - or `access_denied`; a warning if the maildir could not be moved. + 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: @@ -6026,11 +5804,12 @@ paths: post: summary: Delete mailbox groups description: >- - Deletes groups. The group alias, the send-as rights and the grants of - the group are removed; members keep their mailbox settings (another - group's template may become effective). Same permissions as edit. - Answers one message per id: `group_removed` or `access_denied` (unknown - id, id that is no number, no permission). + 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 @@ -6058,11 +5837,13 @@ paths: post: summary: Remove identity links description: >- - Admins only (every read/write API key). Removes the links of mailboxes - to their Identity Provider users; the next sync run or login links them - again by email. Use it to resolve conflicts, e.g. when an address was - given to another user of the provider. Answers `iam_link_removed` per - mailbox (also for mailboxes without a link), or `access_denied`. + 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 @@ -6087,15 +5868,12 @@ paths: post: summary: Delete queued messages description: >- - Deletes messages from the Postfix queue (`postsuper -d `; admins - only, an API key may). To empty the whole queue use `super_delete` of - `POST /api/v1/edit/mailq`. Queue IDs that are not hexadecimal are - skipped. + Deletes messages from the Postfix queue. To empty the whole queue use + `super_delete` of `POST /api/v1/edit/mailq`. - Messages: `queue_command_success`; `Error: command failed: ...` - (danger); `unknown` (danger) when the command gave no answer; - `access_denied` for non-admins. + Messages: `queue_command_success`; errors `Error: command failed: ...`, + `unknown`. operationId: deleteQueuedMessages tags: - Queue Manager @@ -6123,12 +5901,11 @@ paths: post: summary: Delete OAuth2 clients description: >- - Deletes OAuth2 clients. Tokens issued to them are not deleted (use - `revoke_tokens` of `edit/oauth2-client` first). + Deletes OAuth2 clients but not their tokens; revoke these first with + `revoke_tokens` of `edit/oauth2-client`. - Success: one `items_deleted` message for the whole call. Error: - `access_denied` for an ID that is no number. + Messages: `items_deleted`. operationId: deleteOAuth2Client tags: - oAuth Clients @@ -6154,14 +5931,10 @@ paths: post: summary: Delete quarantined messages description: >- - Deletes quarantine items without releasing or learning them. An API - key (admin) may delete every item, others only items of their - mailboxes or domains; the quarantine module must be allowed for the - caller. - - - Messages: `item_deleted` per item (for an admin also for IDs that do - not exist); `access_denied` (danger) for a non-numeric or foreign ID. + 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 @@ -6189,24 +5962,16 @@ paths: post: summary: Release or learn quarantined messages description: >- - Acts on quarantine items. An API key (admin) may act on every item, - others only on items of their mailboxes or domains; the quarantine - module must be allowed for the caller. + 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. - - `release` and `learnham` do the same: the message is delivered to - its recipient (through Postfix, as the original message or as an - attachment, see the release format of `POST /api/v1/edit/quarantine`), - deleted from the quarantine and learned as ham by Rspamd. - - `learnspam` deletes the item and learns the message as spam. - - Messages: `item_released` and `learned_ham`, or `qlearn_spam`, per - item; `access_denied` (danger) for a non-numeric, unknown or foreign - ID; `release_send_failed` (warning); `ham_learn_error`, - `spam_learn_error` (danger); `fuzzy_learn_error` (warning). When - Postfix cannot be reached or answers with an unexpected SMTP code, the - remaining items are not processed. An unknown `action` does nothing - and is answered with `Task completed`. + Messages: `item_released`, `learned_ham`, `qlearn_spam`; errors + `release_send_failed`, `ham_learn_error`, `spam_learn_error`. operationId: editQuarantineItems tags: - Quarantine @@ -6257,9 +6022,8 @@ paths: summary: Delete recipient maps operationId: deleteRecipientMap description: >- - Deletes recipient maps by ID (`recipient_map_entry_deleted` per ID, - also for IDs that do not exist). A non-numeric ID stops the call. - Administrators and API keys only. + 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: @@ -6284,10 +6048,10 @@ paths: summary: Delete sender-dependent transports operationId: deleteRelayhost description: >- - Deletes sender-dependent transports by ID (`relayhost_removed` per ID, - also for IDs that do not exist). Domains that used one fall back to the - default route (`relayhost` 0); the `relayhost` attribute of mailboxes - is not reset. Administrators and API keys only. + 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: @@ -6312,9 +6076,7 @@ paths: summary: Delete resources operationId: deleteResource description: >- - Deletes resources and their SOGo data. Admins and domain admins (for - their domains). Messages per resource: `resource_removed` or - `access_denied`. + Deletes resources and their SOGo data, also for domain admins. requestBody: required: true content: @@ -6337,11 +6099,12 @@ paths: post: summary: Delete sync jobs description: >- - Deletes sync jobs. Needs the `syncjobs` ACL and access to the local - mailbox of each job (admins and API keys: every job). The OAuth2 token - of the job's remote account is deleted when no other job uses it. - Answers one message per id: `deleted_syncjob` with the id as sent, or - `access_denied` (unknown job, id that is no number, no access). + 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 @@ -6369,10 +6132,11 @@ paths: post: summary: Delete sync sources description: >- - Deletes sync sources that no sync job uses (ids that are no number are - skipped). Needs the `syncjobs` ACL and edit rights on the source. - Answers one message per id: `imapsync_source_deleted`, or - `imapsync_source_in_use`, `access_denied` (unknown id, no edit rights). + 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 @@ -6402,9 +6166,8 @@ paths: summary: Delete TLS policy maps operationId: deleteTlsPolicyMap description: >- - Deletes TLS policy maps by ID (`tls_policy_map_entry_deleted` per ID, - also for IDs that do not exist). A non-numeric ID stops the call. - Administrators and API keys only. + 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: @@ -6429,8 +6192,8 @@ paths: summary: Delete transport maps operationId: deleteTransport description: >- - Deletes transport maps by ID (`relayhost_removed` per ID, also for IDs - that do not exist). Administrators and API keys only. + Deletes transport maps by ID, answering `relayhost_removed` also for + IDs that do not exist. requestBody: content: application/json: @@ -6455,9 +6218,8 @@ paths: summary: Remove tags from a mailbox operationId: deleteMailboxTags description: >- - Removes the given tags from the mailbox. Admins and domain admins (for - their domains); `access_denied` otherwise. Answers `mailbox_modified`, - or "Cannot delete item" when no tag was sent. + Removes tags from the mailbox, also for domain admins. Answers "Cannot + delete item" when no tag was sent. parameters: - name: mailbox in: path @@ -6489,10 +6251,8 @@ paths: post: summary: Remove tags of a domain description: >- - Removes tags from a domain. Answers `domain_modified` when at least one - tag name was sent (also when the domain did not have it), `Cannot - delete item` for an empty list; errors `domain_invalid`, - `access_denied`. + Removes tags from a domain. Answers `domain_modified` also for tags the + domain did not have. operationId: deleteDomainTags tags: - Domains @@ -6529,33 +6289,15 @@ paths: summary: Update aliases operationId: editAlias description: >- - Changes the aliases in `items`; attributes that are left out keep their - value, except the `goto_*` flags, which are 0 when left out. An alias - that discards or learns its mail (`null@localhost`, `spam@localhost`, - `ham@localhost`) therefore needs its `goto_*` flag in every edit: - without it, the current destination fails the address check - (`goto_invalid`), nothing is saved and the answer still contains - `alias_modified`. + 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. - Per alias: `alias_modified` on success; `alias_invalid` for an unknown - alias or one of a domain the caller does not manage; - `alias_group_managed` for the distribution address of a mailbox group - (change it in the group). A new `address` is checked like in - add/alias (`access_denied`, `alias_invalid`, `is_alias_or_mailbox`, - `domain_not_found`, `is_spam_alias`); send-as grants of mailbox groups - follow the new address. Destinations that are no e-mail address - (`goto_invalid`), external while external destinations are disabled - (`external_goto_denied`) or equal to the alias (`alias_goto_identical`) - are dropped; if none remains, nothing is saved. Comments are not - limited to 160 characters here. - - - `expand_alias` does not change the alias: it creates the missing copies - of it in the alias domains of its domain (same destinations, active, - visible in SOGo, `sender_allowed` 0) and answers `alias_modified`, or - warns `is_not_primary_alias` for an alias that is itself in an alias - domain. + Messages: `alias_modified`; errors `alias_invalid`, + `alias_group_managed`, `goto_invalid`, `is_not_primary_alias`. requestBody: content: application/json: @@ -6578,9 +6320,8 @@ paths: goto: type: string description: >- - New destination addresses, separated by spaces, - commas, semicolons or line breaks; replaces the current - ones. Ignored if a `goto_*` flag is 1. + 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 @@ -6614,8 +6355,9 @@ paths: expand_alias: type: [boolean, integer] description: >- - true or 1 = create the missing copies of the alias in - the alias domains; all other attributes are ignored + 1 = only create the missing copies of the alias in the + alias domains of its domain; other attributes are + ignored required: - items - attr @@ -6637,15 +6379,12 @@ paths: post: summary: Edit API keys description: >- - Changes API keys; attributes that are not sent keep their value. - `regen_key` gives a key a new random value: clients using the old value - are locked out. Service keys from mailcow.conf (API_KEY, - API_KEY_READ_ONLY) cannot be changed here. + 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. - One message per key. Success: `api_key_modified`. Errors: - `access_denied` (no key with this ID), `api_key_service_locked`, - `api_key_access_invalid`, `api_key_description_invalid`, + Messages: `api_key_modified`; errors `api_key_service_locked`, `api_key_network_invalid`, `ip_list_empty`. operationId: editApiKey tags: @@ -6695,19 +6434,15 @@ paths: post: summary: Edit domains description: >- - Changes domains. With an API key (admin) every attribute can be set; - quotas are in MiB, attributes not sent keep their value (`aliases`, - `maxquota` and `quota` keep it also for 0 or an empty value). - `relay_all_recipients` = 1 sets `backupmx`, `relay_unknown_only` = 1 - sets both. `tags` are added to the existing tags (remove tags with - delete/domain/tag); a tag the domain has already ends the request - without an answer after the other values were saved. A domain admin (UI session) can only change - `description` (with the ACL `domain_desc`), `gal` and `tags`. Rate - limits are set with edit/rl-domain. Errors per domain: - `domain_invalid`, `mailbox_defquota_exceeds_mailbox_maxquota`, - `defquota_empty`, `mailbox_quota_exceeds_domain_quota`, - `maxquota_empty`, `max_quota_in_use`, `domain_quota_m_in_use`, - `mailboxes_in_use`, `aliases_in_use`; success `domain_modified`. + 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 @@ -6764,11 +6499,13 @@ paths: relay_all_recipients: type: [integer, string] enum: [0, 1, "0", "1"] - description: Relay all recipients + description: Relay all recipients; 1 sets `backupmx` relay_unknown_only: type: [integer, string] enum: [0, 1, "0", "1"] - description: Relay non-existing mailboxes only + description: >- + Relay only recipients without a local mailbox; 1 sets + `backupmx` and `relay_all_recipients` relayhost: type: [integer, string] description: >- @@ -6808,14 +6545,13 @@ paths: post: summary: Set the domain-wide footer description: >- - Sets the footer that is added to all outgoing mails of addresses of the - domains. The footer is replaced as a whole: values not sent are emptied. - The footer texts can use `{= auth_user =}`, `{= from_user =}`, + 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 like `{= foo =}`. Entries of `exclude` that are no - existing mailbox, alias or alias domain are reported with - `username_invalid` and left out. Success `domain_footer_modified`, - errors `domain_invalid`, `access_denied` (both stop the call). + mailbox attributes. + + + Messages: `domain_footer_modified`; error `domain_invalid`. operationId: editDomainFooter tags: - Domains @@ -6854,8 +6590,8 @@ paths: description: No footer in replies exclude: description: >- - Mailboxes, aliases (addresses) and alias domains that - get no footer + Mailboxes, aliases and alias domains without footer; + unknown entries are skipped (`username_invalid`) oneOf: - type: string - type: array @@ -6882,38 +6618,18 @@ paths: post: summary: Edit Fail2Ban settings, bans and filters description: >- - Changes Fail2Ban (admins only, an API key may). What happens depends - on `attr.action`: + 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`. - - `unban`, `whitelist`, `blacklist` act on the networks in `items`: - queue the unban; add to the allowlist (and unban); add to the - denylist (not `0.0.0.0/0` or the mailcow networks). Answer - `object_modified` per network; `network_host_invalid` (danger) - for an invalid network with `whitelist`/`blacklist` (`unban` - skips it silently). - - `unban-all` queues all active bans for unbanning (the denylist - stays). Answer `f2b_modified`. - - `edit-regex` replaces the regex filters with the list in - `attr.regex` (numbered from 1). Answer `f2b_modified`. - - `reset-regex` restores the default filters and waits up to 15 - seconds for netfilter (`reset_f2b_regex` (danger) when it takes - longer). Send a non-empty `items` (the UI sends `["self"]`); the - answer is `object_modified` per item. - - Without `action` the settings are saved. Values that are not sent - keep their value, except `ban_time_increment` and - `manage_external`, which become 0, and `whitelist`/`blacklist` - replace the lists. Values are clamped: `ban_time`, `max_ban_time` - at least 60, `max_attempts`, `retry_window` at least 1, - `netban_ipv4` 8-32, `netban_ipv6` 8-128. Answer `f2b_modified`, - `network_host_invalid` (danger) for every entry of the lists that - is left out. - - An `unban`, `whitelist`, `blacklist` or `reset-regex` without `items` - saves the settings like a call without `action` (and so turns off - `ban_time_increment` and `manage_external`); an unknown `action` with - `items` answers `object_modified` without changing anything. - `access_denied` for non-admins. + Messages: `f2b_modified`, `object_modified`; errors + `network_host_invalid`, `reset_f2b_regex`. operationId: editFail2Ban tags: - Fail2Ban @@ -6976,7 +6692,7 @@ paths: description: Denylist, networks separated by space, comma, semicolon or newline; replaces the list manage_external: type: [boolean, integer, string] - description: 1 = netfilter only keeps the banlist and sets no rules (block with the banlist URL externally); not sent = 0 + description: 1 = netfilter sets no rules, block externally with the banlist; not sent = 0 required: - attr examples: @@ -7028,21 +6744,16 @@ paths: summary: Update mailboxes operationId: editMailbox description: >- - Changes the given mailboxes. Fields that are not sent keep their value, - except `attribute_hash`, which is cleared. Admins and domain admins (for - their domains); a mailbox user gets `access_denied`. Some fields need an - ACL of domain admins and are silently ignored without it: `sogo_access` - (sogo_access), the protocol fields (protocol_access), `relayhost` - (mailbox_relayhost), `extended_sender_acl` (extend_sender_acl, error - `extended_sender_acl_denied`); API keys have all ACLs. + 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 per mailbox: `mailbox_modified` or `username_invalid`, - `access_denied`, `mailbox_quota_left_exceeded`, - `mailbox_quota_exceeded`, `password_complexity`, `password_mismatch`, - `sender_acl_invalid`, `extra_acl_invalid`, `extra_acl_invalid_domain`. - Quota 0 (unlimited) for a mailbox with a quota needs the - `unlimited_quota` ACL (`unlimited_quota_acl`, stops the call). + Messages: `mailbox_modified`; errors `mailbox_quota_exceeded`, + `password_complexity`, `sender_acl_invalid`, + `extended_sender_acl_denied`. requestBody: required: true content: @@ -7086,12 +6797,9 @@ paths: summary: Set custom attributes of mailboxes operationId: editMailboxCustomAttributes description: >- - Replaces the custom attributes (free key/value pairs, e.g. for - identity provider mappings) of the given mailboxes: `attribute[i]` - gets `value[i]`, attributes that are not sent are removed; spaces in - attribute names are removed. Both lists must have the same length. - Admins and domain admins (for their domains). Messages per mailbox: - `mailbox_modified`, `username_invalid`, `access_denied`. + 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: @@ -7142,19 +6850,13 @@ paths: post: summary: Update mailbox groups description: >- - Applies `attr` to every group in `items`, attributes that are not sent - keep their value. The domain of a group cannot be changed. `members` - replaces the manual members the caller may access; members added by the - identity provider sync (`source` idp) stay and cannot be removed here - (`group_member_idp`). Admins (every read/write API key) may edit every - group; domain admins need the `mailbox_groups` ACL, and groups with - send-as addresses or grants outside their domains are read-only for - them. + 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. - Answers one message per id: `group_modified` (plus warnings as for - `add`) or the error of that group (`access_denied` for unknown ids and - ids that are no number, the errors listed for `add`). + Messages: `group_modified`; errors `group_member_idp` and those of add. operationId: editMailboxGroups tags: - Groups @@ -7219,15 +6921,13 @@ paths: post: summary: Request an identity sync run description: >- - Admins only (every read/write API key). Queues a sync run of the - Identity Provider (Keycloak and LDAP); the identity sync cron starts it - within a minute, see `GET /api/v1/get/identity-provider/sync-status`. - An identical pending request is reused. `items` is not used. + 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. - Answers `iam_sync_requested`, or `iam_sync_mode_invalid`, - `iam_sync_unavailable` (no Keycloak or LDAP provider configured), - `access_denied`. + Messages: `iam_sync_requested`; errors `iam_sync_mode_invalid`, + `iam_sync_unavailable`. operationId: requestIdentitySync tags: - Identity Provider @@ -7269,21 +6969,13 @@ paths: post: summary: Act on the mail queue description: >- - Runs a Postfix queue command (admins only, an API key may): + 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. - - `hold` (`postsuper -h`), `unhold` (`postsuper -H`) and `deliver` - (`postqueue -i`) act on the queue IDs in `items`. - - `flush` (`postqueue -f`) tries to deliver the whole queue, - `super_delete` (`postsuper -d ALL`) deletes every queued message. - Both ignore `items`. - - Messages: `queue_command_success`; `Error: command failed: ...` - (danger) with the output of the command; `unknown` (danger) when the - command gave no answer; `access_denied` for non-admins. An unknown - `action`, or `hold`/`unhold`/`deliver` without `items`, does nothing - and is answered with `Task completed`. Queue IDs that are not - hexadecimal are skipped. + Messages: `queue_command_success`; errors `Error: command failed: ...`, + `unknown`. operationId: editMailQueue tags: - Queue Manager @@ -7345,13 +7037,14 @@ paths: operationId: editPushover description: >- Saves the Pushover settings (push notification on new mail) of the - mailboxes, or removes them with `delete: "true"`. Needs the user ACL - `pushover` (domain admins: their own ACL `pushover`, off by default). - API keys may change any mailbox, a mailbox user only its own (the UI - sends its address as `items`). `key` and `token` must be sent the first - time; later, empty fields keep their value. Messages per mailbox: - `pushover_settings_edited` or `access_denied`, `pushover_key`, - `pushover_token`, "Invalid regex". + 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: @@ -7384,14 +7077,14 @@ paths: description: Text of the notification senders: type: string - description: Only notify for these senders (addresses separated by comma, space or semicolon; invalid ones are dropped) + 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 mails as high-priority notifications (0 when not sent) + 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"] @@ -7432,11 +7125,8 @@ paths: operationId: editQuarantineNotification description: >- How often the mailbox user gets a summary of quarantined mail. Needs - the user ACL `quarantine_notification`. API keys may change any - mailbox, a mailbox user only its own. `quarantine_notification` must be - sent: without it the call fails with an empty answer. Messages per - mailbox: `mailbox_modified` or `access_denied` (also for an invalid - value). + the user ACL `quarantine_notification`; a mailbox user may change only + its own. An invalid value answers `access_denied`. requestBody: required: true content: @@ -7477,18 +7167,12 @@ paths: post: summary: Update sync jobs description: >- - Applies `attr` to every job in `items`; attributes that are not sent - keep their value, an empty `password1` or `user1` keeps the stored one. - The local mailbox (`username`) cannot be changed. Needs the `syncjobs` - ACL and access to the local mailbox of each job (admins and API keys: - every job). The source is only checked again when `source_id` changes. - Sending `last_run` or `success` (any value except null) resets that - field. `prio` is set by admins only. + 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. - Answers one message per id: `mailbox_modified` with the local mailbox, - or the error of that job (`access_denied` for unknown jobs and ids that - are no number, otherwise the errors of `add`). + Messages: `mailbox_modified`; errors as for add. operationId: editSyncJobs tags: - Sync jobs @@ -7548,17 +7232,11 @@ paths: post: summary: Run sync jobs next description: >- - Admins only (every read/write API key): moves the jobs to the front of - the queue. Each job gets a `prio` above the current maximum, `last_run` - and `success` are cleared, so the runner starts them next. Values in - `items` that are no number are ignored, `attr` is not used. + Moves sync jobs to the front of the queue so the runner starts them + next; their `last_run` and `success` are cleared. - Answers `imapsync_job_running` (danger) for each job that is running - right now and `imapsync_run_next_done` with the number of moved jobs. - When no job was moved and none is running (e.g. unknown ids) the answer - is `{"type": "error", "msg": "Cannot edit item"}`; without valid ids - `access_denied`. + Messages: `imapsync_run_next_done`; errors `imapsync_job_running`. operationId: runSyncJobsNext tags: - Sync jobs @@ -7595,23 +7273,17 @@ paths: post: summary: Update sync sources description: >- - Applies `attr` to every source in `items` (ids that are no number are - skipped); attributes that are not sent keep their value, an empty - `oauth_client_secret` keeps the stored secret. Domains and users are - only replaced when `scope` is sent. Needs the `syncjobs` ACL and edit - rights on the source (admins and API keys: every source; others the - sources they created, domain admins also those of their mailboxes). - Changing the server or the OAuth2 client drops the stored tokens. - Changing the server or the OAuth2 client, or turning `verify_cert` off, - needs access to every mailbox whose jobs use the source - (`imapsync_source_used_by_others`). A client_credentials source fetches - a new token while it is saved. + 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. - Answers one message per id: `imapsync_source_modified` (plus - `imapsync_source_token_refresh_failed` when the new token could not be - fetched), or the error of that source (`access_denied` for unknown - ids, the errors of `add`). + Messages: `imapsync_source_modified`, + `imapsync_source_token_refresh_failed`; errors + `imapsync_source_used_by_others` and those of add. operationId: editSyncJobSources tags: - Sync jobs @@ -7658,13 +7330,14 @@ paths: post: summary: Refresh the token of a sync source description: >- - Fetches a new OAuth2 token for a XOAUTH2 client_credentials source now - (the cron refreshes tokens before they expire). Only the first id of - `items` is used, `attr` is not used. Needs the `syncjobs` ACL and edit - rights on the source. Answers `imapsync_source_token_refreshed`, or - `imapsync_source_refresh_unsupported` (other sources), - `imapsync_source_token_refresh_failed` (with the provider error), - `access_denied` (unknown id, id that is no number, no edit rights). + 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 @@ -7701,11 +7374,13 @@ paths: post: summary: Update global sync job settings description: >- - Admins only (every read/write API key). Sets how many sync jobs run at - the same time and the bandwidth limit of every sync job process (a - lower per-job `maxbytespersecond` still applies). `items` is not used. - Answers `max_parallel_saved`, or `imapsync_max_parallel_invalid`, - `imapsync_max_kb_per_second_invalid`, `access_denied`. + 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 @@ -7735,9 +7410,7 @@ paths: type: - integer - string - description: >- - Bandwidth limit per sync job process in KB/s, 0-10485760 - (stored as bytes/s); 0, empty or not sent = unlimited + description: Bandwidth limit per sync job process in KB/s; 0, empty or not sent = unlimited default: 0 minimum: 0 maximum: 10485760 @@ -7759,11 +7432,9 @@ paths: summary: Set the ACL of mailboxes operationId: editUserAcl description: >- - Sets the user ACL (what a mailbox user may change in the UI) of the - given mailboxes: listed ACLs are switched on, all others off. Admins - and domain admins (for their domains); a domain admin cannot change - ACLs that it does not have itself. Mailbox users get `access_denied`. - Success: `acl_saved` per mailbox. + 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: @@ -7816,10 +7487,9 @@ paths: summary: Get aliases operationId: getAliases description: >- - `all` lists the aliases of every domain and alias domain the caller - manages (an API key: all), an ID or address returns that alias. - Mailbox addresses (alias rows pointing to themselves) are not listed. - `{}` if there is none. + `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 @@ -7909,8 +7579,8 @@ paths: summary: Get the aliases of domains operationId: getAliasesByDomain description: >- - Lists the aliases of the named domains or alias domains. Domains the - caller does not manage are skipped. `{}` if there is none. + 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 @@ -7956,10 +7626,8 @@ paths: summary: Get the time-limited aliases of a mailbox operationId: getTimeLimitedAliases description: >- - The time-limited aliases of the mailbox that are still valid or - permanent. `{}` when there are none or the caller has no access (a - mailbox user: other mailboxes). If `{mailbox}` is no address, the - session user's aliases are returned (nothing for API keys). + The valid or permanent time-limited aliases of the mailbox. `{}` if + none or no access. parameters: - name: mailbox in: path @@ -7995,11 +7663,8 @@ paths: operationId: editTimeLimitedAlias description: >- Sets a new expiry (`validity` hours from now) or makes the aliases - permanent. Needs the user ACL `spam_alias` and access to the target - mailbox (API keys: any, mailbox users: their own). Aliases are skipped - silently when neither `validity` nor a true `permanent` is sent. - Messages per alias: `mailbox_modified` (without the address) or - `access_denied`. + permanent. Needs the user ACL `spam_alias`. Without `validity` or a + true `permanent` nothing changes. requestBody: required: true content: @@ -8046,9 +7711,7 @@ paths: summary: Delete time-limited aliases operationId: deleteTimeLimitedAlias description: >- - Deletes time-limited aliases. Needs the user ACL `spam_alias` and - access to the target mailbox (API keys: any, mailbox users: their own). - Messages per alias: `mailbox_modified` or `access_denied`. + Deletes time-limited aliases. Needs the user ACL `spam_alias`. requestBody: required: true content: @@ -8074,11 +7737,10 @@ paths: summary: Verify the Pushover credentials of mailboxes operationId: testPushover description: >- - Checks the stored Pushover key and token of each mailbox with the - Pushover API; `attr` is not used. Same access rules as `edit/pushover`. - Messages per mailbox: "Pushover API OK (200): ..." (success) or - "Pushover API ERR (code): ..." (danger), `access_denied`; a mailbox - without settings stops the call with `pushover_credentials_missing`. + 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: @@ -8111,12 +7773,9 @@ paths: summary: Set the handling of tagged mail operationId: editDelimiterAction description: >- - What happens to mail for `user+tag@example.org`: moved to the subfolder - "tag" (`subfolder`), "[tag]" added to the subject (`subject`), or - nothing (`none`, also for any other value). Needs the user ACL - `delimiter_action`. API keys may change any mailbox, a mailbox user - only its own. Messages per mailbox: `mailbox_modified` or - `access_denied`, `redis_error`. + 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: @@ -8157,10 +7816,8 @@ paths: summary: Set the TLS policy of mailboxes operationId: editTlsPolicy description: >- - Enforces TLS for incoming and/or outgoing mail of the mailboxes; a - field that is not sent keeps its value. Needs the user ACL - `tls_policy`. API keys may change any mailbox, a mailbox user only its - own. Messages per mailbox: `mailbox_modified` or `access_denied`. + Enforces TLS for incoming and/or outgoing mail; fields not sent keep + their value. Needs the user ACL `tls_policy`. requestBody: required: true content: @@ -8204,9 +7861,8 @@ paths: summary: Get the default spam score operationId: getDefaultSpamScore description: >- - The spam score thresholds of the session user; for API keys, which have - no mailbox, the server default from the Rspamd actions ("add header" - and "reject"; "5,15" if Rspamd cannot be asked). + The spam thresholds of the session user; for API keys the Rspamd + default (`5,15` if Rspamd is unreachable). responses: "200": description: Thresholds @@ -8221,7 +7877,7 @@ paths: /api/v1/get/api-key/{id}: get: summary: Get API key - description: One API key including its key value. A read-only API key gets `{}`. + description: One API key with its value. A read-only API key gets `{}`. operationId: getApiKey tags: - API Keys @@ -8259,9 +7915,8 @@ paths: get: summary: Get API keys description: >- - Lists all API keys including their key values, service keys from - mailcow.conf first. A read-only API key gets `{}`: it may not see the - keys. + Lists all API keys with their values, service keys first. A read-only + API key gets `{}`. operationId: getApiKeys tags: - API Keys @@ -8307,9 +7962,8 @@ paths: summary: Get the app passwords of a mailbox operationId: getAppPasswords description: >- - The app passwords of the mailbox, including the password hashes. `{}` - if there are none or the caller has no access to the mailbox (a - mailbox user: other mailboxes). + The app passwords of the mailbox, with password hashes. `{}` if none or + no access. parameters: - name: mailbox in: path @@ -8351,9 +8005,8 @@ paths: summary: Get the app passwords of the logged-in mailbox operationId: getOwnAppPasswords description: >- - The app passwords of the session user. Meant for a mailbox user - session; an API key has no mailbox and gets `{}` (use - `get/app-passwd/all/{mailbox}`). + 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 @@ -8372,9 +8025,8 @@ paths: summary: Get an app password (broken) operationId: getAppPassword description: >- - Does not work: json_api.php reads `$object['id']` from the path segment, - which is a string, so the request ends with an error and an empty body. - Use `get/app-passwd/all/{mailbox}`. + Broken: always ends with an error and an empty body. Use + `get/app-passwd/all/{mailbox}`. parameters: - name: id in: path @@ -8395,14 +8047,12 @@ paths: summary: Update app passwords operationId: editAppPassword description: >- - Changes app passwords by ID; fields that are not sent keep their value. - Needs the user ACL `app_passwds`. The app passwords are assigned to - `username`, which defaults to the session user: API keys must send the - mailbox the app passwords belong to (without it the backend tries to - assign them to "API", the database refuses that and the answer is - empty); a mailbox user may leave it out. Messages per ID: - `object_modified`, `app_passwd_id_invalid`, `password_complexity`, - `password_mismatch`. + 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: @@ -8470,10 +8120,9 @@ paths: summary: Get BCC maps operationId: getBccMaps description: >- - `all` lists the BCC maps of the domains the caller manages (an API key: - all), an ID returns that map. `{}` if there is none. The answer for an - ID carries an additional member `"0": null` (json_api.php appends an - undefined variable). + `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 @@ -8523,10 +8172,9 @@ paths: get: summary: Get the DKIM key of a domain description: >- - The DKIM public key of a domain or alias domain with the TXT record to - publish at `._domainkey.`; `{}` if it has none. The - private key is only answered when `SHOW_DKIM_PRIV_KEYS` is enabled in - vars.local.inc.php, else `privkey` is empty. + The DKIM public key of a domain or alias domain and the TXT record for + `._domainkey.`. `privkey` is empty unless + `SHOW_DKIM_PRIV_KEYS` is enabled. operationId: getDkimKey tags: - DKIM @@ -8557,13 +8205,11 @@ paths: post: summary: Import a DKIM key description: >- - Imports an RSA private key as the DKIM key of a domain; the public key - is derived from it. Admins only. The domain name must be valid but is - not checked against the domains of mailcow. The old key of the domain - is removed first, so a successful import answers `dkim_removed` and - `dkim_added`. Errors `access_denied`, `private_key_error`, - `dkim_domain_or_sel_invalid`, `dkim_domain_or_sel_exists` (a key exists - and `overwrite_existing` is not set). + 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 @@ -8607,7 +8253,7 @@ paths: /api/v1/get/domain-admin/all: get: summary: Get domain administrators - description: Lists all domain administrators with their details. + description: Lists all domain administrators. operationId: getDomainAdmins tags: - Domain admin @@ -8678,11 +8324,9 @@ paths: get: summary: Get domains description: >- - `all` answers the list of all domains, a domain name answers that - domain. An alias domain name answers its target domain. An API key sees - every domain, a domain admin (UI session) only the domains assigned to - it. Quotas are in bytes. `{}` when nothing is found, also for `all` - without domains. + `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 @@ -8757,9 +8401,8 @@ paths: get: summary: Get domain templates description: >- - `all` answers the list of domain templates, an ID that template - (`{}` if there is none; a non-numeric ID is read as 0). Admins and - domain admins. The template attributes hold the quotas in bytes. + `all` lists the domain templates, an ID returns that template. Domain + admins may call it too. Quotas are in bytes. operationId: getDomainTemplates tags: - Domains @@ -8810,11 +8453,13 @@ paths: post: summary: Add a domain template description: >- - Adds a domain template, the defaults for new domains (see `template` of - add/domain). Admins only. Quotas are sent in MiB and stored in bytes; - values not sent get the defaults shown (numbers and quotas also for - 0). Success `template_added`, - errors `access_denied`, `template_name_invalid`, `template_exists`. + 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 @@ -8856,14 +8501,10 @@ paths: post: summary: Edit domain templates description: >- - Replaces the attributes of domain templates. Admins only. Send all - attributes: one that is not sent is reset (numbers and quotas to 0, - `tags` to none, `rl_frame` to `s`, `active` and `gal` to 1, - `dkim_selector` to `dkim`, `key_size` to 2048). The `Default` template - keeps its name. Edit one template per call: with several IDs the - templates after the first get the name of the first one. Unknown IDs - answer `template_id_invalid`; the call always ends with - `template_modified`. + 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 @@ -8918,9 +8559,9 @@ paths: post: summary: Delete a domain template description: >- - Deletes a domain template. Admins only. Only the first ID of the list - is deleted. The `Default` template is never deleted; the answer is - `template_removed` in every case. + 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 @@ -8946,30 +8587,19 @@ paths: post: summary: Search domains (table of the UI) description: >- - Paging, sorting and searching of domains with the server-side - processing parameters of DataTables, used by the domain table of the - UI. Admins (also read-only API keys) search all domains, domain admins - their domains; other logins get `403` with `Insufficient permissions`. + 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. - The position of an entry in `columns` (and `order[].column`) selects - the database column: 2 domain name, 3 max. aliases (sorted by the - number of aliases), 4 max. mailboxes (sorted by the number of - mailboxes), 5 domain quota (sorted by the quota of the mailboxes), 6 - storage (sorting only), 7 default mailbox quota, 8 max. mailbox quota, - 10 relay domain, 14 tags (global search only), 15 active; other positions - mean the domain name. `search.value` is searched (`LIKE %value%`) in - the columns with `searchable: true` (positions 2 and 14 in the UI), - `columns[].search.value` filters one column: the one whose position is - given in `data`, else the domain name. `orderable` and `searchable` - must be set (`true` or `"true"`). `columns` is required when - `search.value` is set. + 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`. - Send `Content-Type: application/json`; without it the body is ignored - and all domains are answered. A database error answers - `{"error": "An SQL error occurred: ..."}` (status 200), e.g. a search - in position 6. + Without `Content-Type: application/json` all domains are returned. SQL + errors answer `{"error": "..."}` with status 200. operationId: searchDomains tags: - Domains @@ -9050,9 +8680,8 @@ paths: get: summary: Get alias domains description: >- - `all` answers the list of all alias domains, an alias domain name - answers that alias domain; `{}` when nothing is found. An API key sees - every alias domain, a domain admin those of its domains. + `all` lists all alias domains, a name returns that alias domain. Domain + admins see only those of their domains. operationId: getAliasDomains tags: - Domains @@ -9090,17 +8719,14 @@ paths: post: summary: Add alias domains description: >- - Adds alias domains: mail to an address of the alias domain goes to the - same local part in the target domain. Needs the ACL `alias_domains` - (API keys have it) and access to the target domain, which must be an - existing domain and no relay domain. Like add/domain this can set the - rate limit and create a DKIM key for each alias domain. Per alias - domain: success `aliasd_added`, errors `alias_domain_invalid` (also - when the name is taken by a domain or alias domain), - `aliasd_targetd_identical`, `targetd_not_found`, - `targetd_relay_domain`; for the call: `access_denied`, - `target_domain_invalid`. An invalid alias domain name currently ends - the request without an answer. + 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 @@ -9140,8 +8766,8 @@ paths: key_size: type: [integer, string] description: >- - RSA key size in bits of the DKIM key that is created; a key - is created only when `key_size` and `dkim_selector` are sent + 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 @@ -9161,11 +8787,12 @@ paths: post: summary: Edit alias domains description: >- - Changes alias domains; attributes not sent keep their value. The new - target domain must be an existing domain (no alias domain) the caller - has access to. Success `aliasd_modified`, errors per alias domain - `alias_domain_invalid` (unknown), `target_domain_invalid`, - `access_denied`. Rate limits are set with edit/rl-domain. + 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 @@ -9213,10 +8840,11 @@ paths: post: summary: Delete alias domains description: >- - Deletes alias domains together with their aliases, spam aliases, BCC - maps and mailbox group data. Success `alias_domain_removed`, errors - `domain_invalid`, `access_denied`. The rate limit of the alias domain - is not removed. + 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 @@ -9242,15 +8870,15 @@ paths: post: summary: Add an MTA-STS policy description: >- - Adds the MTA-STS policy of a domain, published (when active) at - `https://mta-sts./.well-known/mta-sts.txt`. Alias domains always - publish the policy of their target domain: a policy added for an alias - domain is accepted but never published. The policy ID for the - `_mta-sts` TXT record is the time of the change (`YYYYMMDDhhmmss`). There is no read route: the policy is shown in the - UI only. Answers `Task completed` on success; errors `access_denied` - (unknown domain or no access), `version_invalid`, `mode_invalid`, - `max_age_invalid`, `mx_invalid`, and the database message when the - domain has a policy already (use edit/mta-sts). + Adds the MTA-STS policy of a domain, published when active at + `https://mta-sts./.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 @@ -9282,9 +8910,7 @@ paths: only reports, `none` publishes without effect mx: type: string - description: >- - Comma-separated MX host names the senders may deliver to, - wildcards like `*.example.org` allowed + 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 @@ -9311,12 +8937,13 @@ paths: post: summary: Edit MTA-STS policies description: >- - Changes the MTA-STS policies of domains; attributes not sent keep their - value, but `version` must always be sent (else `version_invalid`). A - change of `version`, `mode`, `mx` or `max_age` gives the policy a new - ID. Success `object_modified`, errors per domain `access_denied` (also - for a domain without policy), `version_invalid`, `mode_invalid`, - `max_age_invalid`, `mx_invalid`. + 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 @@ -9380,10 +9007,8 @@ paths: get: summary: Get Fail2Ban settings and bans description: >- - Returns the Fail2Ban (netfilter) settings, the regex filters, the - allow- and denylists and the current bans. Admins only (an API key - may); other callers get `{}`. Any further path segment - (e.g. `/api/v1/get/fail2ban/all`) gives the same answer. + Returns the Fail2Ban settings, regex filters, allow- and denylists and + the current bans. operationId: getFail2Ban tags: - Fail2Ban @@ -9425,15 +9050,12 @@ paths: post: summary: Renew the Fail2Ban banlist URL description: >- - Gives the banlist (`/f2b-banlist?id=`, the list of denied - and banned networks for an external firewall) a new random ID, so the - old URL stops working. `items` must hold the current `banlist_id` - (from `GET /api/v1/get/fail2ban`); `attr` can be left out. Admins - only (an API key may). + Gives the banlist URL `/f2b-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. - Answers `f2b_banlist_refreshed`; a wrong ID is answered with status - 404 and `Cannot edit item`, a Redis error with 500 and `redis_error`. + Messages: `f2b_banlist_refreshed`; errors `redis_error`. operationId: refreshFail2BanBanlist tags: - Fail2Ban @@ -9477,7 +9099,7 @@ paths: /api/v1/get/logs/acme/{count}: get: summary: Get ACME logs (count or range) - description: Entries of the ACME log (Let's Encrypt certificates), newest first. + description: Entries of the ACME (Let's Encrypt) log, newest first. operationId: getAcmeLogsByCount tags: - Logs @@ -9485,11 +9107,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9502,10 +9120,7 @@ paths: /api/v1/get/logs/api/{count}: get: summary: Get API logs (count or range) - description: >- - Entries of the API log: every request to `/api/v1` with its form data - (values of keys like passwords and secrets replaced by `*`). Newest - first. + description: API requests with their data (secrets replaced by `*`), newest first. operationId: getApiLogsByCount tags: - Logs @@ -9513,11 +9128,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9530,9 +9141,7 @@ paths: /api/v1/get/logs/autodiscover/{count}: get: summary: Get Autodiscover logs (count or range) - description: >- - Requests to Autodiscover (Outlook, ActiveSync) and the service that was - offered, newest first. + description: Autodiscover requests (Outlook, ActiveSync) with the offered service, newest first. operationId: getAutodiscoverLogsByCount tags: - Logs @@ -9540,11 +9149,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9565,11 +9170,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9590,11 +9191,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9615,11 +9212,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9632,9 +9225,7 @@ paths: /api/v1/get/logs/ratelimited/{count}: get: summary: Get rate limit logs (count or range) - description: >- - Messages that were rejected because a rate limit was exceeded, newest - first. + description: Messages rejected by a rate limit, newest first. operationId: getRatelimitLogsByCount tags: - Logs @@ -9642,11 +9233,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9659,9 +9246,7 @@ paths: /api/v1/get/logs/rspamd-history/{count}: get: summary: Get Rspamd history (count or range) - description: >- - Messages scanned by Rspamd with score, action and symbols, newest - first. + description: Messages scanned by Rspamd, newest first. operationId: getRspamdHistoryByCount tags: - Logs @@ -9670,10 +9255,8 @@ paths: in: path required: true description: >- - `N`: the newest N messages. `from-to` (from ≥ 1, to ≥ from) is - passed to Rspamd, which counts from 0: `2-3` gives the third and - fourth newest message. Characters other than digits and `-` are - removed; `0` gives `{}`. + `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]+)?$ @@ -9694,11 +9277,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9711,7 +9290,7 @@ paths: /api/v1/get/logs/watchdog/{count}: get: summary: Get watchdog logs (count or range) - description: Health checks of the watchdog container, newest first. + description: Watchdog health checks, newest first. operationId: getWatchdogLogsByCount tags: - Logs @@ -9719,11 +9298,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9736,9 +9311,7 @@ paths: /api/v1/get/logs/acme: get: summary: Get ACME logs - description: >- - The newest 1000 entries of the ACME log (Let's Encrypt certificates), - newest first. + description: The newest 1000 entries of the ACME (Let's Encrypt) log, newest first. operationId: getAcmeLogs tags: - Logs @@ -9751,10 +9324,8 @@ paths: get: summary: Get API logs description: >- - The newest 1000 entries of the API log: every request to `/api/v1` - with its form data (values of keys like passwords and secrets - replaced by `*`). Requests with a JSON body show the body as `attr` or - `items`. Newest first. + The newest 1000 API requests with their data (secrets replaced by + `*`), newest first. operationId: getApiLogs tags: - Logs @@ -9767,8 +9338,8 @@ paths: get: summary: Get Autodiscover logs description: >- - The newest 1000 requests to Autodiscover (Outlook, ActiveSync) and the - service that was offered, newest first. + The newest 1000 Autodiscover requests (Outlook, ActiveSync) with the + offered service, newest first. operationId: getAutodiscoverLogs tags: - Logs @@ -9781,8 +9352,8 @@ paths: get: summary: Get cron logs description: >- - The newest 1000 entries of the scheduled tasks of mailcow (e.g. - identity provider sync, group shares), newest first. + The newest 1000 entries of the mailcow scheduled tasks (identity + provider sync, group shares, ...), newest first. operationId: getCronLogs tags: - Logs @@ -9794,9 +9365,7 @@ paths: /api/v1/get/logs/cron/{count}: get: summary: Get cron logs (count or range) - description: >- - Entries of the scheduled tasks of mailcow (e.g. identity provider - sync, group shares), newest first. + description: Entries of the mailcow scheduled tasks, newest first. operationId: getCronLogsByCount tags: - Logs @@ -9804,11 +9373,7 @@ paths: - name: count in: path required: true - description: >- - `N`: the newest N entries. `from-to`: the entries from position - `from` to `to` (the newest entry is 1). Characters other than - digits and `-` are removed; `0` or a range with `to` < `from` gives - `{}`. + description: "`N`: the newest N entries; `from-to`: entries `from` to `to` (newest = 1)" schema: type: string pattern: ^[0-9]+(-[0-9]+)?$ @@ -9833,9 +9398,7 @@ paths: /api/v1/get/logs/netfilter: get: summary: Get netfilter logs - description: >- - The newest 1000 entries of netfilter (failed logins, bans), newest - first. + description: The newest 1000 entries of netfilter (failed logins, bans), newest first. operationId: getNetfilterLogs tags: - Logs @@ -9859,9 +9422,7 @@ paths: /api/v1/get/logs/ratelimited: get: summary: Get rate limit logs - description: >- - The newest 1000 messages that were rejected because a rate limit was - exceeded, newest first. + description: The newest 1000 messages rejected by a rate limit, newest first. operationId: getRatelimitLogs tags: - Logs @@ -9873,9 +9434,7 @@ paths: /api/v1/get/logs/rspamd-history: get: summary: Get Rspamd history - description: >- - The newest 1000 messages scanned by Rspamd with score, action and - symbols, newest first. + description: The newest 1000 messages scanned by Rspamd, newest first. operationId: getRspamdHistory tags: - Logs @@ -9887,10 +9446,7 @@ paths: /api/v1/get/logs/rspamd-stats: get: summary: Get Rspamd statistics - description: >- - The statistics of Rspamd (`/stat` of its controller): scanned and - learned messages, actions, Bayes statistics. Further path segments are - ignored. + description: Rspamd statistics (scanned and learned messages, actions, Bayes). operationId: getRspamdStats tags: - Logs @@ -9942,8 +9498,7 @@ paths: summary: Get SASL logs description: >- The newest 1000 successful logins (IMAP, POP3, SMTP, SOGo, ...), one - entry per service, address and user with the time of the last login, - newest first. + entry per service, address and user, newest first. operationId: getSaslLogs tags: - Logs @@ -9956,8 +9511,7 @@ paths: get: summary: Get SASL logs (count or range) description: >- - Successful logins (IMAP, POP3, SMTP, SOGo, ...), one entry per - service, address and user with the time of the last login, newest + Successful logins, one entry per service, address and user, newest first. operationId: getSaslLogsByCount tags: @@ -9967,10 +9521,8 @@ paths: in: path required: true description: >- - `N`: the newest N entries. `from-to`: `to` entries starting at - position `from` (the newest entry is 1), so `2-3` gives the entries - 2 to 4. Characters other than digits and `-` are removed; `0` or a - range with `to` < `from` gives `{}`. + `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]+)?$ @@ -9995,9 +9547,7 @@ paths: /api/v1/get/logs/ui: get: summary: Get mailcow UI logs - description: >- - The newest 1000 actions of the mailcow UI and API (the messages of - their calls), newest first. + description: The newest 1000 messages of UI and API calls, newest first. operationId: getUiLogs tags: - Logs @@ -10009,9 +9559,7 @@ paths: /api/v1/get/logs/ui/{count}: get: summary: Get mailcow UI logs (count or range) - description: >- - Actions of the mailcow UI and API (the messages of their calls), - newest first. + description: Messages of UI and API calls, newest first. operationId: getUiLogsByCount tags: - Logs @@ -10020,10 +9568,8 @@ paths: in: path required: true description: >- - `N`: the newest N entries. `from-to`: `to` entries starting at - position `from` (the newest entry is 1), so `2-3` gives the entries - 2 to 4. Characters other than digits and `-` are removed; `0` or a - range with `to` < `from` gives `{}`. + `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]+)?$ @@ -10036,8 +9582,7 @@ paths: /api/v1/get/logs/watchdog: get: summary: Get watchdog logs - description: >- - The newest 1000 health checks of the watchdog container, newest first. + description: The newest 1000 watchdog health checks, newest first. operationId: getWatchdogLogs tags: - Logs @@ -10053,13 +9598,12 @@ paths: summary: Get a mailbox operationId: getMailbox description: >- - Details of one mailbox, `{}` if it does not exist or the caller has no - access to it. A mailbox user may read its own mailbox. + One mailbox, `{}` if not found or no access. A mailbox user may read + its own. - With the query parameter `tags`, `{id}` is a search term instead: the - answer is the list of mailboxes whose address contains `{id}` and that - have a tag containing one of the tags, `[]` when none matches. + 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 @@ -10089,9 +9633,7 @@ paths: get: summary: Get mailbox group description: >- - One group by id, with the same visibility rules as - `GET /api/v1/get/mailbox-group/all`. Answers `{}` when the id is not a - number, the group does not exist or the caller may not see it. + One group by id, visible as in `GET /api/v1/get/mailbox-group/all`. operationId: getMailboxGroup tags: - Groups @@ -10140,13 +9682,10 @@ paths: get: summary: Get group memberships of a mailbox description: >- - The groups of a mailbox, its effective group template (the template of - the active group with the highest priority, then the lowest id) and the - addresses it may send as through its active groups. Admins (every API - key) get it for every existing mailbox, domain admins with the - `mailbox_groups` ACL for their mailboxes (only the groups of their - domains), a mailbox user for himself. Answers `{}` for unknown mailboxes - or without access. + 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 @@ -10186,10 +9725,8 @@ paths: get: summary: Get mailbox groups description: >- - All groups the caller may see, ordered by domain and name: admins (and - every API key) all groups, domain admins with the `mailbox_groups` ACL - the groups of their domains, others none. `can_edit` is false for - read-only API keys. Answers `{}` when there is no group. + 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 @@ -10246,8 +9783,7 @@ paths: get: summary: Get mailbox groups of domains description: >- - Like `GET /api/v1/get/mailbox-group/all`, limited to the groups of the - given domains. Answers `{}` when there is no group. + Like `GET /api/v1/get/mailbox-group/all`, limited to the given domains. operationId: getMailboxGroupsOfDomains tags: - Groups @@ -10297,13 +9833,9 @@ paths: get: summary: Get identity sync status description: >- - Status of the Identity Provider sync (admins and API keys, also - read-only; `{}` for others): the provider, whether it can be synced - (Keycloak and LDAP) and a scheduled sync is enabled, counts of the - mailboxes of the provider and their links, and the last 10 sync runs, - newest first. Run status: `pending`, `running`, `ok`, `blocked` (the - change limit `offboarding_limit` stopped the run, nothing was changed) - or `error` (`summary.error`, nothing was changed). + 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 @@ -10369,11 +9901,9 @@ paths: get: summary: Get identity link of a mailbox description: >- - The Identity Provider user a mailbox is linked to (admins and API keys, - domain admins for their mailboxes). Answers `{}` without a link or - without access. `missing_since` is set while the sync does not find the - mailbox at the provider; a mailbox that was never linked then has a row - without `external_id`. + 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 @@ -10403,9 +9933,7 @@ paths: get: summary: Get the mail queue description: >- - Returns the Postfix mail queue (`postqueue -j`), at most 10000 - entries. Admins only (an API key may); other callers and an empty - queue get `[]`. + Returns the Postfix mail queue, at most 10000 entries. operationId: getMailQueue tags: - Queue Manager @@ -10433,14 +9961,9 @@ paths: get: summary: Get a queued message description: >- - Returns the output of `postcat -q ` for a message in the Postfix - queue: envelope records, headers and body. Admins only (an API key - may); other callers get an empty answer. - - - The answer is sent with `Content-Type: application/json`, but the body - is the plain postcat text, not JSON-encoded. An unknown or - non-hexadecimal queue ID gives the error text of postcat. + 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 @@ -10481,7 +10004,7 @@ paths: /api/v1/get/oauth2-client/{id}: get: summary: Get OAuth2 client - description: One OAuth2 client including its secret. + description: One OAuth2 client with its secret. operationId: getOAuth2Client tags: - oAuth Clients @@ -10514,8 +10037,7 @@ paths: get: summary: Get OAuth2 clients description: >- - Lists the OAuth2 clients that may use mailcow as OAuth2 server, - including their secrets. + Lists the clients of the mailcow OAuth2 server with their secrets. operationId: getOAuth2Clients tags: - oAuth Clients @@ -10542,15 +10064,12 @@ paths: post: summary: Edit OAuth2 clients description: >- - Does one of three things per client, in this order of precedence: - `revoke_tokens` deletes all access and refresh tokens of the client, - `renew_secret` gives it a new random secret, otherwise `redirect_uri` - is set. `revoke_tokens` and `renew_secret` act when they are present, - whatever their value. + 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. - Success: `object_modified` per client. Errors: `access_denied` (no - client with this ID; stops the call), `Redirect/Callback URL cannot be + Messages: `object_modified`; error `Redirect/Callback URL cannot be empty`. operationId: editOAuth2Client tags: @@ -10600,9 +10119,8 @@ paths: get: summary: Get the sender deny list of a domain description: >- - The deny list (blacklist) entries of the domain and of all its - mailboxes (`object` tells which); `{}` if there are none or the domain - is unknown. + The deny list (blacklist) entries of the domain and all its mailboxes; + `object` tells which. operationId: getDomainBlacklist tags: - Domain antispam policies @@ -10633,9 +10151,8 @@ paths: get: summary: Get the sender allow list of a domain description: >- - The allow list (whitelist) entries of the domain and of all its - mailboxes (`object` tells which); `{}` if there are none or the domain - is unknown. + The allow list (whitelist) entries of the domain and all its + mailboxes; `object` tells which. operationId: getDomainWhitelist tags: - Domain antispam policies @@ -10669,9 +10186,8 @@ paths: get: summary: Get quarantined messages description: >- - Returns the quarantined messages without their content. An API key - (admin) gets every item, a domain admin the items of their domains, a - mailbox user their own items. `[]` when there are none. + Returns the quarantined messages without content. Admins get every + item, domain admins those of their domains, mailbox users their own. operationId: getQuarantine tags: - Quarantine @@ -10704,13 +10220,10 @@ paths: summary: Set the quarantine notification category of mailboxes operationId: editQuarantineCategory description: >- - Which quarantined mail the notifications list: rejected mail - (`reject`), mail sent to the junk folder (`add_header`) or both - (`all`). Needs the user ACL `quarantine_category`. API keys may change - any mailbox, a mailbox user only its own. `quarantine_category` must be - sent: without it the call fails with an empty answer. Messages per - mailbox: `mailbox_modified` or `access_denied` (also for an invalid - value). + 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: @@ -10751,9 +10264,8 @@ paths: summary: Get a quarantined message description: >- Returns one quarantine item with the raw message and the Rspamd - symbols. An API key (admin) may read every item; others only items of - their mailboxes or domains. `[]` for an unknown or non-numeric ID or - without access. + symbols. Domain admins and mailbox users only get their own items. + `[]` for an unknown ID. operationId: getQuarantineItem tags: - Quarantine @@ -10795,16 +10307,12 @@ paths: post: summary: Edit quarantine settings description: >- - Saves the global quarantine settings (admins only, an API key may). - `attr.action` must be `settings`; `items` is ignored. Every call - writes all settings: an attribute that is not sent is reset (a missing - `retention_size` or `max_size` becomes 0, which turns the quarantine - off). The current values cannot be read through the API. + 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`; `redis_error` (danger); `access_denied` - for non-admins. Without `action` nothing happens and the answer is - `Task completed`. + Messages: `saved_settings`; errors `redis_error`. operationId: editQuarantineSettings tags: - Quarantine @@ -10827,10 +10335,10 @@ paths: description: Items kept per mailbox; 0 disables the quarantine max_size: type: [integer, string] - description: Maximum message size in MiB; larger messages are not quarantined (0 is not unlimited) + 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 (9999.0) + 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 @@ -10896,10 +10404,9 @@ paths: summary: Get recipient maps operationId: getRecipientMaps description: >- - `all` lists the recipient maps, an ID returns that map. `{}` if there - is none or the caller is no administrator. The answer for an ID - carries an additional member `"0": null` (json_api.php appends an - undefined variable). + `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 @@ -10954,11 +10461,12 @@ paths: summary: Update BCC maps operationId: editBccMap description: >- - Changes the BCC maps in `items`; attributes that are left out keep - their value, `local_dest` cannot be changed. Same callers as - add/bcc. Per map: `bcc_edited`, `access_denied` (unknown, no access or - no ACL), `bcc_must_be_email`, `bcc_exists`. `type` is not checked by the - backend: use `sender` or `rcpt`. + 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: @@ -11009,11 +10517,12 @@ paths: summary: Update recipient maps operationId: editRecipientMap description: >- - Changes the recipient maps in `items`; attributes that are left out - keep their value. Administrators and API keys only. Per map: - `recipient_map_entry_saved`, `access_denied` (unknown ID), - `invalid_recipient_map_old`, `invalid_recipient_map_new`; - `recipient_map_entry_exists` stops the call. + 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: @@ -11062,9 +10571,9 @@ paths: summary: Get sender-dependent transports operationId: getRelayhosts description: >- - `all` lists the sender-dependent transports, an ID returns that entry, - with the password in clear text and the domains and mailboxes that use - it. `{}` if there is none or the caller is no administrator. + `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 @@ -11116,8 +10625,7 @@ paths: summary: Get all resources operationId: getResources description: >- - All resources of the domains the caller manages, `{}` when there are - none. + All resources of the domains the caller manages, `{}` if none. responses: "200": description: List of resources @@ -11145,8 +10653,7 @@ paths: summary: Get a resource operationId: getResource description: >- - One resource by its address, `{}` if it does not exist or the caller - does not manage its domain. + One resource by address, `{}` if not found or no access. parameters: - name: id in: path @@ -11171,10 +10678,8 @@ paths: summary: Update resources operationId: editResource description: >- - Changes resources; fields that are not sent keep their value (the - address does not change with the description). Admins and domain - admins (for their domains). Messages per resource: `resource_modified` - or `resource_invalid`, `description_invalid`, `access_denied`. + Changes resources, also for domain admins; fields not sent keep their + value. The address does not change with the description. requestBody: required: true content: @@ -11231,9 +10736,8 @@ paths: summary: Get the rate limit of a mailbox operationId: getMailboxRatelimit description: >- - The outgoing rate limit set on the mailbox, `{}` when it has none (the - domain limit applies then) or the caller is no admin or domain admin of - it. + The rate limit set on the mailbox; `{}` if it has none (the domain + limit applies) or no access. parameters: - name: mailbox in: path @@ -11258,9 +10762,8 @@ paths: get: summary: Get rate limits of domains description: >- - The rate limit (outgoing messages per time frame) of a domain or alias - domain, `{}` if it has none. `all` answers the list of all domains and - alias domains that have a rate limit, each with its `domain`. + Rate limit (outgoing messages per time frame) of a domain or alias + domain; `all` lists all that have one. operationId: getDomainRatelimits tags: - Ratelimits @@ -11298,10 +10801,11 @@ paths: post: summary: Set rate limits of domains description: >- - Sets the rate limit (outgoing messages per time frame) of domains or - alias domains. Needs the ACL `ratelimit` (API keys have it). - `rl_value` empty or 0 removes the limit; `rl_frame` must be valid then - too. Success `rl_saved`, errors `rl_timeframe`, `access_denied`. + 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 @@ -11354,9 +10858,8 @@ paths: summary: Get the rate limits of all mailboxes operationId: getMailboxRatelimits description: >- - The outgoing rate limits set on mailboxes the caller manages; mailboxes - without their own limit are left out. Admins and domain admins, `{}` - when there is none. + The rate limits set on single mailboxes the caller manages (no domain + limits). `{}` if none. responses: "200": description: List of rate limits @@ -11384,12 +10887,9 @@ paths: summary: Set the rate limit of mailboxes operationId: editMailboxRatelimit description: >- - Sets or removes the outgoing rate limit of mailboxes: `rl_value` - messages per `rl_frame`. A value of 0 or empty removes the limit; - `rl_frame` must be valid in that case too. Needs the ACL `ratelimit` - (admins, domain admins for their domains); mailbox users get - `access_denied`. Messages per mailbox: `rl_saved` or `rl_timeframe`, - `access_denied`. + 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: @@ -11438,12 +10938,9 @@ paths: summary: Reset a rate limit counter operationId: deleteRatelimitHash description: >- - Deletes the counter of a rate-limited sender (the `rl_hash` of an entry - of `get/logs/ratelimited`) and its log lines, so the sender can send - again. Admins only. The body is a list with one hash (several are - concatenated into one). Unlike other write routes the answer is not - JSON: `1` when the hash was deleted, an empty body when it was not - found, is invalid or the caller is no admin. + 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: @@ -11472,9 +10969,7 @@ paths: /api/v1/get/status/containers: get: summary: Get container status - description: >- - State, start time and image of every container of the mailcow - installation, stopped containers included, keyed by service name. + description: State, start time and image of all mailcow containers (also stopped ones). operationId: getContainerStatus tags: - Status @@ -11505,7 +11000,7 @@ paths: /api/v1/get/status/vmail: get: summary: Get mail storage status - description: Disk usage of the file system that holds the mail storage (`/var/vmail`). + description: Disk usage of the file system that holds the mail storage. operationId: getVmailStatus tags: - Status @@ -11543,9 +11038,7 @@ paths: /api/v1/get/status/version: get: summary: Get mailcow version - description: >- - The installed mailcow version: the release tag on the master branch, - else the short commit ID. + description: The installed mailcow version, the release tag on master, else the short commit ID. operationId: getVersion tags: - Status @@ -11568,12 +11061,9 @@ paths: get: summary: Get container statistics description: >- - Resource statistics of one container: the last (up to three) Docker - stats snapshots, taken about five seconds apart while this route is - called. The container is named by its full Docker container ID (64 hex - digits, e.g. from `docker ps --no-trunc`), which the API does not - list. For an unknown ID the call waits until the dockerapi timeout (60 - seconds) and answers with the curl error text as a JSON string. + 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 @@ -11680,10 +11170,9 @@ paths: get: summary: Get public IP addresses description: >- - The public IPv4 and IPv6 address of the server, as seen by the third - party services ipv4.mailcow.email and ipv6.mailcow.email (requested on - every call, regardless of the IP check setting of `edit/ip_check`). - Other path segments after `host` give an empty answer. + 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 @@ -11710,9 +11199,7 @@ paths: get: summary: Get all sync jobs without logs description: >- - Like `GET /api/v1/get/syncjobs/all`, with an empty `log` (the job list - of the UI). The last segment is a comma-separated option list, only - `no_log` has a meaning; other values are ignored. + Like `GET /api/v1/get/syncjobs/all`, with an empty `log`. operationId: getSyncJobsWithoutLog tags: - Sync jobs @@ -11731,9 +11218,7 @@ paths: get: summary: Get sync source description: >- - One sync source by id, with the visibility rules of - `GET /api/v1/get/syncjob_source/all`. Answers `{}` when the id is not a - whole number, the source does not exist or the caller may not see it. + One sync source by id, visible as in `GET /api/v1/get/syncjob_source/all`. operationId: getSyncJobSource tags: - Sync jobs @@ -11791,13 +11276,10 @@ paths: get: summary: Get allowed custom imapsync options description: >- - The imapsync options sync jobs may use in `custom_params` - (`$IMAPSYNC_OPTIONS` of vars.local.inc.php, defaults from vars.inc.php; - options that run code, use local files or print secrets are always - removed). Option name (lowercase, without dashes) mapped to its rule: - `true` needs a value, `false` is a flag without value, a string is a - regular expression the whole value must match. Available to every - logged-in caller. + 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 @@ -11825,7 +11307,7 @@ paths: get: summary: Get global sync job settings description: >- - Settings of the sync job runner (admins and API keys; `{}` for others). + Settings of the sync job runner. operationId: getSyncJobSettings tags: - Sync jobs @@ -11846,12 +11328,9 @@ paths: get: summary: Get all sync jobs description: >- - All sync jobs in queue order (highest `prio` first, then jobs that - never ran, then the least recently run), with their logs. Admins (every - API key) get every job, also jobs whose local mailbox no longer exists; - domain admins the jobs of the mailboxes of their domains; mailbox users - none (see `GET /api/v1/get/syncjobs/{mailbox}`). Answers `{}` when - there is no job. + 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 @@ -11918,11 +11397,9 @@ paths: get: summary: Get sync jobs of a mailbox description: >- - The sync jobs of a local mailbox in queue order, with their logs. - Admins (every API key) get the jobs of every existing mailbox, domain - admins of their mailboxes, users of their own. A value that is no email - address returns the caller's own jobs (none for an API key). Answers - `{}` when there is no job or no access. + 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 @@ -11949,9 +11426,7 @@ paths: get: summary: Get sync jobs of a mailbox without logs description: >- - Like `GET /api/v1/get/syncjobs/{mailbox}`, with an empty `log`. The - last segment is a comma-separated option list, only `no_log` has a - meaning. + Like `GET /api/v1/get/syncjobs/{mailbox}`, with an empty `log`. operationId: getMailboxSyncJobsWithoutLog tags: - Sync jobs @@ -11978,13 +11453,10 @@ paths: get: summary: Get sync sources description: >- - The sync sources the caller may see, ordered by name: admins (every API - key) all; domain admins their own, `all` sources, sources for their - domains or mailboxes and sources created by their mailboxes; users - their own, `all` sources and sources for them or their domain. Secrets - are never returned (`has_client_secret`, `has_access_token`), extra - OAuth2 parameters only to callers who may edit the source (`can_edit`, - false for read-only API keys). Answers `{}` when there is no source. + 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 @@ -12039,10 +11511,9 @@ paths: summary: Get TLS policy maps operationId: getTlsPolicyMaps description: >- - `all` lists the TLS policy maps, an ID returns that map. `{}` if there - is none or the caller is no administrator. The answer for an ID - carries an additional member `"0": null` (json_api.php appends an - undefined variable). + `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 @@ -12093,12 +11564,13 @@ paths: summary: Update TLS policy maps operationId: editTlsPolicyMap description: >- - Changes the TLS policy maps in `items`; attributes that are left out - keep their value (`parameters: ""` clears the parameters). - Administrators and API keys only. Per map: `tls_policy_map_entry_saved` - or `access_denied` (unknown ID); `tls_policy_map_dest_invalid`, - `tls_policy_map_parameter_invalid` and an existing destination (answered - with `recipient_map_entry_exists`) stop the call. + 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: @@ -12158,9 +11630,8 @@ paths: summary: Get transport maps operationId: getTransports description: >- - `all` lists the transport maps, an ID returns that entry, with the - password in clear text. `{}` if there is none or the caller is no - administrator. + `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 @@ -12220,10 +11691,11 @@ paths: summary: Update sender-dependent transports operationId: editRelayhost description: >- - Changes the sender-dependent transports in `items`; attributes that are - left out keep their value (an empty `hostname` too). Administrators - and API keys only. Per entry: `object_modified` (without the host - name), `relayhost_invalid` (unknown ID), `mysql_error`. + 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: @@ -12275,17 +11747,14 @@ paths: summary: Update transport maps operationId: editTransport description: >- - Changes the transport maps in `items`; attributes that are left out - keep their value (an empty `destination`, `nexthop`, `is_mx_based` or - `active` too). An empty `username` also clears the password. The - credentials are written to every entry with the same next hop. - Administrators and API keys only. + 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. - Per entry: `object_modified` (without names), `relayhost_invalid` - (unknown ID), `mysql_error`; `transport_dest_exists`, - `invalid_destination`, `next_hop_interferes` and - `next_hop_interferes_any` stop the call. + Messages: `object_modified`; errors `relayhost_invalid`, + `transport_dest_exists`, `invalid_destination`, `next_hop_interferes`. requestBody: content: application/json: @@ -12340,12 +11809,11 @@ paths: post: summary: Edit CORS settings description: >- - Sets which origins (web pages of other hosts) may call the API from a - browser and with which methods. A missing value is replaced by its - default. `items` is not used. + Sets the origins and methods allowed to call the API from a browser. A + missing value is reset to its default. - Success: `cors_headers_edited`. Errors: `cors_invalid_origin`, + Messages: `cors_headers_edited`; errors `cors_invalid_origin`, `cors_invalid_method`. operationId: editCors tags: @@ -12362,9 +11830,8 @@ paths: properties: allowed_origins: description: >- - Origins (`scheme://host[:port]`, http or https, no path) - or `*` for any origin; a list or a string with one - origin per line. Default: the URL of the mailcow host. + `scheme://host[:port]` (http/https, no path) or `*`; a + list or one origin per line. Default: the mailcow URL. oneOf: - type: array items: @@ -12372,10 +11839,8 @@ paths: - type: string allowed_methods: description: >- - Allowed methods: `GET`, `POST`, `PUT`, `DELETE` - (uppercase); a list or a string separated by single - spaces, commas, semicolons or newlines (`GET,POST`, not - `GET, POST`). Default: all four. + Uppercase; a list or a string with single separators + (`GET,POST`, not `GET, POST`). Default: all four. oneOf: - type: array items: @@ -12410,9 +11875,8 @@ paths: summary: Get the spam score of a mailbox operationId: getSpamScore description: >- - The spam score thresholds of the mailbox: its own values or the server - default. `{}` if the caller has no access to the mailbox (a mailbox - user: other mailboxes). + The spam thresholds of the mailbox, its own or the server default. `{}` + without access. parameters: - name: mailbox in: path @@ -12439,13 +11903,9 @@ paths: summary: Set the spam score of mailboxes operationId: editSpamScore description: >- - Sets the spam thresholds of the mailboxes: from the first value on mail - goes to the junk folder, from the second it is rejected (equal values: - the second is raised by 0.1). `default` removes the own values. Needs - the user ACL `spam_score`. API keys may change any mailbox, a mailbox - user only its own. Messages per mailbox: `mailbox_modified` or - `access_denied`, "Invalid spam score, format must be "1,2" where first - is low and second is high spam value.". + 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: @@ -12488,12 +11948,12 @@ paths: summary: Create a mailbox template operationId: addMailboxTemplate description: >- - Saves a named set of mailbox settings that `add/mailbox` (field - `template`) and the UI use as defaults. Admins only (`access_denied` - otherwise). Errors: `template_name_invalid` (empty name), - `template_exists`, `quarantine_category_invalid`. Success: - `template_added`. Fields that are not sent get the defaults named in - the schema; without `acl` the template grants no user ACL. + 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: @@ -12540,9 +12000,8 @@ paths: summary: Get all mailboxes operationId: getMailboxes description: >- - Details of every mailbox in the domains the caller manages (API keys - and admins: all domains). Resources are not included. `{}` when there - are none. + All mailboxes of the domains the caller manages, without resources. + `{}` if none. parameters: - $ref: "#/components/parameters/MailboxTagsQuery" responses: @@ -12566,10 +12025,8 @@ paths: summary: Get the mailboxes of domains operationId: getMailboxesOfDomains description: >- - Like `get/mailbox/all`, limited to the given domains. Caution: a domain - that does not exist or that the caller does not manage adds all - mailboxes the caller manages (API keys: every mailbox) to the answer. - `{}` when nothing is found. + 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 @@ -12597,9 +12054,8 @@ paths: summary: Get all mailboxes (reduced details) operationId: getMailboxesReduced description: >- - Like `get/mailbox/all`, but each mailbox without the costly fields - `max_new_quota`, `spam_aliases`, `pushover_active`, `rl`, `rl_scope`, - `is_relayed` and `sender_acl`. Faster for large installations. + Like `get/mailbox/all` without the costly fields named in `Mailbox`; + faster on large installations. parameters: - $ref: "#/components/parameters/MailboxTagsQuery" responses: @@ -12620,9 +12076,8 @@ paths: summary: Get the mailboxes of domains (reduced details) operationId: getMailboxesReducedOfDomains description: >- - Like `get/mailbox/reduced`, limited to the given domains, with the same - caution as `get/mailbox/all/{domains}`: an unknown domain adds all - mailboxes the caller manages. + Like `get/mailbox/reduced` for the given domains; an unknown domain + adds all mailboxes the caller manages. parameters: - name: domains in: path @@ -12650,8 +12105,7 @@ paths: summary: Get all mailbox templates operationId: getMailboxTemplates description: >- - All mailbox templates. Admins and domain admins; `{}` for others or - when there is none. + All mailbox templates, also for domain admins. `{}` if none. responses: "200": description: List of templates @@ -12709,8 +12163,7 @@ paths: summary: Get a mailbox template operationId: getMailboxTemplate description: >- - One mailbox template by its ID, `{}` if there is none. Admins and - domain admins. + One mailbox template by ID, also for domain admins. `{}` if not found. parameters: - name: id in: path @@ -12735,17 +12188,14 @@ paths: summary: Update mailbox templates operationId: editMailboxTemplate description: >- - Changes mailbox templates and passes the change on to the mailboxes - whose effective group template it is. Admins only (`access_denied`). - The template "Default" keeps its name. Messages: `template_id_invalid`, - `quarantine_category_invalid`, once at the end `template_modified`. + 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. - Send the complete template as the UI does: values that are not sent are - not taken over from the stored template. `quota` falls back to 0 - (unlimited), `quarantine_category` must be sent (else - `quarantine_category_invalid`), and without `protocol_access` or `acl` - the protocol or ACL settings are lost. + Messages: `template_modified`; errors `template_id_invalid`, + `quarantine_category_invalid`. requestBody: required: true content: @@ -12814,13 +12264,10 @@ paths: summary: Rename a mailbox operationId: renameMailbox description: >- - Renames `old_local_part@domain` to `new_local_part@domain`: the address - in all tables (aliases, ACLs, filters, app passwords, BCC and recipient - maps, sync jobs, groups, SOGo), the maildir and the SOGo account; IMAP - ACLs are moved over. `items` is not used, the mailbox is named in - `attr`. The mailbox must be active (1 or 2). Admins and domain admins - (for their domains). Errors: `username_invalid`, `access_denied`. - Success: `mailbox_renamed`. + 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: @@ -12874,8 +12321,8 @@ paths: summary: Delete mailbox templates operationId: deleteMailboxTemplate description: >- - Deletes mailbox templates by ID; the template "Default" is kept - silently. Admins only (`access_denied`). Answers `template_removed`. + Deletes mailbox templates by ID; `Default` is kept silently. Answers + `template_removed`. requestBody: required: true content: @@ -12901,12 +12348,9 @@ paths: summary: Get the last logins of a mailbox operationId: getLastLogin description: >- - Logins of the mailbox in the last 7 days (`sasl`: one entry per - address, service and app password with the latest time) and its - previous UI login (`ui`, the one before the latest). `sasl` is empty - without access to the mailbox; `ui` is only given to admins (API keys) - and the mailbox user itself (`false` when there is none), domain admins - get an empty list. + 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 @@ -12981,10 +12425,8 @@ paths: summary: Clear the login history of a mailbox operationId: resetLastLogin description: >- - Deletes the stored logins of the mailbox (the SASL log and, for admins - and the mailbox user itself, the successful UI logins). A `get` route - that changes data: read-only API keys can call it too. Always answers - `true`. + 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 @@ -13011,9 +12453,8 @@ paths: operationId: deleteEasCache description: >- Deletes the ActiveSync device cache of the mailboxes, so devices sync - from scratch. Needs the user ACL `eas_reset`. API keys may reset any - mailbox, a mailbox user only its own. Messages per mailbox: `eas_reset` - or `access_denied`. + from scratch. Needs the user ACL `eas_reset`; a mailbox user may reset + only its own. requestBody: required: true content: @@ -13036,11 +12477,9 @@ paths: summary: Reset the SOGo profile of mailboxes operationId: deleteSogoProfile description: >- - Deletes the SOGo data of the mailboxes: profile, settings, calendars, - address books and their shares. Needs the user ACL - `sogo_profile_reset`. API keys may reset any mailbox, a mailbox user - only its own. Messages per mailbox: `sogo_profile_reset` or - `access_denied`. + 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: @@ -13063,10 +12502,8 @@ paths: summary: Get the possible BCC map destinations operationId: getBccDestinationOptions description: >- - What a BCC map can be bound to: the domains the caller manages, per - mailbox the mailbox and its aliases (aliases of other domains only if - the caller manages them), and the alias domains. Keys without entries - are left out. + 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 @@ -13110,26 +12547,15 @@ paths: summary: Search mailboxes page by page operationId: searchMailboxes description: >- - Server-side search behind the mailbox table of the UI, with the request - and answer format of DataTables (server-side processing): paging, - sorting and a search over the mailboxes the caller manages (API keys: - all; resources are not included). Read-only API keys may use it. - Mailbox users get `403` with `Insufficient permissions`. + 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 are addressed by number, as in the UI table: 2 address - (`username`), 3 quota, 4 last mail login, 5 last password change, 6 - quota in use, 7 name, 20 messages, 23 tags, 24 active. Sorting works on - all of them except 23; searching on 2, 3, 7, 23 and 24. Searching in 4, - 5, 6 or 20 or sorting by 23 makes the database query fail, so send - these columns as not searchable/orderable. Other numbers stand for the - address. `columns` is needed for a search or a sort: - `columns[n]` describes column n. - - - Each entry of `data` holds the full details of a mailbox, like - `get/mailbox/{id}`. `recordsTotal` counts the mailboxes after the - search too (same as `recordsFiltered`). + 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: @@ -13196,26 +12622,15 @@ paths: post: summary: Configure the Identity Provider description: >- - Admins only (every read/write API key). Saves the configuration of the - external Identity Provider (Keycloak, generic OpenID Connect or LDAP). - Send the complete configuration of the provider: every setting of the - provider is written, settings that are not sent get their default (flags - off, `login_provisioning` off, `group_autocreate` off), and the secrets - (`client_secret`, `bindpass`) must be sent again. `redirect_url_extra`, - `default_template` and the `mappers`/`templates` pair are only changed - when sent. Settings of other providers stay stored. The cached Keycloak - access token is cleared. Changing the LDAP `id_attribute` drops the - stored LDAP ids (mailboxes are linked by email again). `items` is not - used. + 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. - Answers `object_modified`. Errors: `required_data_missing` (`authsource` - or a required setting missing: Keycloak `server_url`, `realm`, - `client_id`, `client_secret`, `redirect_url`, `version`; generic-oidc - `authorize_url`, `token_url`, `userinfo_url`, `client_id`, - `client_secret`, `redirect_url`; LDAP `basedn`, `binddn`, `bindpass`), - `invalid_authsource`, `authsource_in_use` (mailboxes use another - external provider), `access_denied`. Secrets are logged as `*`. + Messages: `object_modified`; errors `required_data_missing`, + `invalid_authsource`, `authsource_in_use`. operationId: editIdentityProvider tags: - Identity Provider @@ -13308,13 +12723,10 @@ paths: get: summary: Get Identity Provider settings description: >- - The stored settings of the external Identity Provider (admins and API - keys; `{}` for others). Values are returned as stored (mostly strings), - also settings of a provider that was configured before. Read-only API - keys get `*` instead of `client_secret`, `bindpass` and `access_token`; - read/write API keys get them in plain text. Without a configuration the - answer is `{"login_provisioning": 1}`. Any further path segment other - than `sync-status` returns the same. + 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 @@ -13359,20 +12771,11 @@ paths: post: summary: Test an Identity Provider connection description: >- - Admins only (every read/write API key). Tests the connection data in - `attr` (the stored settings are not used, send the secrets too): - Keycloak requests a client_credentials token from - `/realms//protocol/openid-connect/token`, generic-oidc - sends an OPTIONS request to `token_url` (both succeed on HTTP 200, 7 s - timeout), LDAP connects and binds with `host`, `port`, `basedn`, - `binddn`, `bindpass` (all required), `use_ssl`, `use_tls`. Nothing is - stored. `items` is not used. - - - The answer carries no details: `{"type": "success", "msg": "Task - completed"}` or `{"type": "error", "msg": "Cannot edit item"}` - (`access_denied` for non-admins). A missing or unknown `authsource` - answers success without testing anything. + 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 @@ -13463,11 +12866,12 @@ paths: post: summary: Delete the Identity Provider configuration description: >- - Admins only (every read/write API key). Deletes all Identity Provider - settings, all mailbox links (`identity-link`) and the sync run history. - Refused with `authsource_in_use` while any mailbox uses an external - provider. The body must be valid JSON, its content is not used (e.g. - `[]`). Answers `item_deleted`, or `authsource_in_use`, `access_denied`. + 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 @@ -13491,13 +12895,13 @@ paths: summary: Create a Sieve filter operationId: addFilter description: >- - Adds a Sieve script to a mailbox. Needs the ACL `filters`, which admins - (API keys) and domain admins have, mailbox users not. `username` is - required for API keys and domain admins (`no_user_defined`). The script - is checked with a Sieve parser (`sieve_error`). Activating a filter - deactivates the other filters of the same type and mailbox. Errors: - `access_denied`, `script_empty`, `value_missing`, `filter_type`. - Success: `mailbox_modified`. + 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: @@ -13553,8 +12957,7 @@ paths: summary: Get all Sieve filters operationId: getFilters description: >- - The Sieve filters of all mailboxes the caller manages, `{}` when there - are none. + The Sieve filters of all mailboxes the caller manages, `{}` if none. responses: "200": description: List of filters @@ -13584,9 +12987,7 @@ paths: summary: Get the Sieve filters of a mailbox operationId: getMailboxFilters description: >- - The Sieve filters of the mailbox, `{}` when there are none or the - caller has no access. If `{mailbox}` is no address, the session user's - filters are returned (nothing for API keys). + The Sieve filters of the mailbox, `{}` if none or no access. parameters: - name: mailbox in: path @@ -13613,11 +13014,10 @@ paths: summary: Update Sieve filters operationId: editFilter description: >- - Changes filters by ID; fields that are not sent keep their value. - Needs the ACL `filters` (admins, domain admins). Activating a filter - deactivates the other filters of the same type and mailbox. Messages - per ID: `mailbox_modified` or `access_denied` (unknown ID or no - access), `sieve_error`, `filter_type`. + 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: @@ -13670,8 +13070,7 @@ paths: operationId: deleteFilter description: >- Deletes filters by ID; IDs that are not numeric are skipped. Needs the - ACL `filters` (admins, domain admins). Messages per ID: `delete_filter` - or `access_denied`. + ACL `filters` (admins, domain admins). requestBody: required: true content: @@ -13697,10 +13096,8 @@ paths: summary: Get the active Sieve script of a mailbox operationId: getActiveUserSieve description: >- - The Sieve script the user activated in its mail client or SOGo (read - from Dovecot), as a list with one string. `{}` when there is none or - the caller has no access. If `{mailbox}` is no address, the session - user's script is read (nothing for API keys). + 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 @@ -13734,13 +13131,12 @@ paths: summary: Add a sender to the allow or deny list of a mailbox operationId: addMailboxPolicy description: >- - Adds a sender address or pattern to the spam allow list (`wl`, mail is - never treated as spam) or deny list (`bl`, mail is rejected) of a - mailbox. Needs the user ACL `spam_policy`. `username` is required for - all callers; a mailbox user may only name its own mailbox. Errors: - `access_denied`, `policy_list_from_invalid` (characters other than - letters, digits, `@ _ . - *`), `policy_list_from_exists`. Success: - `mailbox_modified`. + 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: @@ -13763,7 +13159,7 @@ paths: description: wl = allow list, bl = deny list object_from: type: string - description: Sender address, domain or pattern with `*` + description: "Sender address, domain or pattern; allowed: letters, digits, `@ _ . - *`" example: username: john.doe@example.org object_list: bl @@ -13782,11 +13178,8 @@ paths: summary: Get the allow list of a mailbox operationId: getMailboxPolicyAllowList description: >- - The allow list entries that apply to the mailbox: its own and those of - its domain (`object` tells which). `{}` when there are none, the - mailbox does not exist or the caller has no access. If `{mailbox}` is - no address, the session user's list is returned (nothing for API - keys). + The allow list entries of the mailbox and of its domain (see `object`). + `{}` if none or no access. parameters: - name: mailbox in: path @@ -13851,10 +13244,9 @@ paths: summary: Delete allow or deny list entries of mailboxes operationId: deleteMailboxPolicy description: >- - Deletes allow or deny list entries of mailboxes by their `prefid`. - Needs the user ACL `spam_policy` and access to the mailbox of the entry - (entries of a domain are refused, use `delete/domain-policy`). Messages - per ID: `items_deleted` or `access_denied`. + 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: @@ -13877,16 +13269,12 @@ paths: post: summary: Add Rspamd settings rule description: >- - Adds a rule to the Rspamd settings map (admins only, an API key may). - `content` is the body of an Rspamd settings entry (`priority`, `rcpt`, - `from`, `authenticated`, `apply` ...); active rules are handed to - Rspamd as `additional_settings_`. The presets of - `GET /api/v1/get/presets/rspamd` are examples. + 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`; `map_content_empty` (danger) when - `content` is empty; `access_denied` for non-admins. `desc` is required - by the database: without it the insert fails and the answer is empty. + Messages: `settings_map_added`; errors `map_content_empty`. operationId: addRspamdSetting tags: - Rspamd @@ -13915,9 +13303,8 @@ paths: get: summary: Get Rspamd settings rules description: >- - Returns one rule of the Rspamd settings map, or all rules with `all` - (a list of the same objects). Admins only (an API key may); other - callers, unknown IDs and an empty map get `{}`. + Returns one rule of the Rspamd settings map, or a list of all rules + with `all`. operationId: getRspamdSettings tags: - Rspamd @@ -13960,14 +13347,11 @@ paths: post: summary: Edit Rspamd settings rules description: >- - Changes rules of the Rspamd settings map (admins only, an API key may). - Only the attributes that are sent change; an empty `desc` or `content` - keeps the old value. `content` is trimmed. + Changes rules of the Rspamd settings map. Fields not sent, and an empty + `desc` or `content`, keep the old value. - Messages: `object_modified` (with all requested IDs) for every changed - rule, `settings_map_invalid` (danger) for an unknown ID, - `access_denied` for non-admins. + Messages: `object_modified`; errors `settings_map_invalid`. operationId: editRspamdSetting tags: - Rspamd @@ -14016,9 +13400,8 @@ paths: post: summary: Delete Rspamd settings rules description: >- - Deletes rules of the Rspamd settings map (admins only, an API key may). - Answers `settings_map_removed` for every ID, also for IDs that do not - exist; `access_denied` for non-admins. + Deletes rules of the Rspamd settings map. Answers + `settings_map_removed` for every ID, even unknown ones. operationId: deleteRspamdSettings tags: - Rspamd @@ -14046,19 +13429,14 @@ paths: post: summary: Edit Rspamd global regex maps description: >- - Replaces the content of global Rspamd regex maps (Configuration > - Global filters in the UI; admins only, an API key may). Each line is a - regular expression like `/^spam@example\.org$/i`, lines starting with - `#` are comments. The UI checks the expressions before it saves, the - API does not. Every map takes about a second (the file is touched - again for Rspamd to reload it). + 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` per map, `global_map_invalid` (danger) for - an unknown map name, `global_map_write_error` (danger) when the file - cannot be written, `access_denied` for non-admins. A known map whose - file does not exist is not written but still answered with - `object_modified`. + Messages: `object_modified`; errors `global_map_invalid`, + `global_map_write_error`. operationId: editRspamdMap tags: - Rspamd @@ -14105,10 +13483,9 @@ paths: get: summary: Get Rspamd action statistics description: >- - Returns how many messages Rspamd handled with each action (from - Rspamd's `/stat`), as `[action, count]` pairs. Greylisted - messages are counted as `soft reject`. Admins only (an API key may); - other callers, or an Rspamd that does not answer, get `{}`. + 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 @@ -14123,7 +13500,7 @@ paths: type: array prefixItems: - type: string - description: Action, e.g. `reject`, `soft reject`, `rewrite subject`, `add header`, `no action` + description: Rspamd action - type: integer description: Number of messages minItems: 2 @@ -14145,10 +13522,9 @@ paths: get: summary: Get Rspamd or Sieve presets description: >- - Returns the example presets the UI offers: `rspamd` for Rspamd settings - rules (see `POST /api/v1/add/rsetting`), `sieve` for Sieve filters. - `headline` is translated into the language of the session. Admins and - domain admins (an API key may); other callers get `{}`. + 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 @@ -14200,16 +13576,13 @@ paths: post: summary: Save a global Sieve filter description: >- - Replaces the global Sieve prefilter (runs before the filters of the - mailboxes) or postfilter (runs after them) and restarts Dovecot. - Admins only (an API key may). The script is parsed first and not - saved when it has errors. + Replaces the global Sieve prefilter or postfilter and restarts Dovecot. + A script with errors is not saved. - Messages: `dovecot_restart_success`, or `dovecot_restart_failed` - (warning), then `global_filter_written`; `sieve_error` (danger) with - the parser error; `invalid_filter_type` (danger); - `global_filter_write_error` (danger); `access_denied` for non-admins. + 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 @@ -14249,8 +13622,7 @@ paths: get: summary: Get the global Sieve filters description: >- - Returns the global Sieve prefilter and postfilter. Admins only (an API - key may); other callers get `{}`. + Returns the global Sieve prefilter and postfilter. operationId: getGlobalFilters tags: - Global filters @@ -14278,9 +13650,8 @@ paths: get: summary: Get one global Sieve filter description: >- - Returns the global Sieve prefilter or postfilter as a JSON string. - Admins only (an API key may); other callers and an empty script get - `{}`. + Returns the global Sieve prefilter or postfilter as a JSON string; + `{}` when the script is empty. operationId: getGlobalFilter tags: - Global filters @@ -14312,14 +13683,11 @@ paths: 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 (admins only, an API key - may). `items` is ignored. Every call writes all three values: one that - is not sent becomes empty. The current values cannot be read through - the API. + 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`; `redis_error` (danger); `access_denied` - for non-admins. + Messages: `saved_settings`; errors `redis_error`. operationId: editQuotaNotification tags: - Quota notifications @@ -14336,7 +13704,7 @@ paths: properties: sender: type: string - description: Sender address (control characters and non-ASCII bytes are removed; an invalid address becomes empty) + description: Sender address (invalid address = empty) subject: type: string description: Subject @@ -14363,16 +13731,13 @@ paths: 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 subject gets the username appended). Admins and domain admins of - the domain (an API key may; the domain or alias domain must exist). - `items` is ignored. The list replaces the old one; the current list - cannot be read through the API. + 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`; `goto_invalid` (danger) for an invalid - address, which is left out while the others are saved; `redis_error` - (danger); `access_denied` for an unknown or foreign domain. + Messages: `saved_settings`; errors `goto_invalid`, `redis_error`. operationId: editQuotaNotificationBcc tags: - Quota notifications @@ -14419,10 +13784,7 @@ paths: /api/v1/get/admin/all: get: summary: Get administrators - description: >- - Lists all administrators with their details. Domain administrators are - not part of this list (see `get/domain-admin/all`). The API key itself - (account `API`) is no administrator account and is not listed. + description: Lists all administrators, without domain administrators and the API key account. operationId: getAdmins tags: - Administrators @@ -14485,15 +13847,13 @@ paths: post: summary: Create administrator description: >- - Creates an administrator account with full access to mailcow. - The username is converted to lowercase; it may only contain letters, - digits, `_`, `.` and `-` and must not be used by another administrator - or domain administrator. The password must match `password2` and the - password policy. + 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. - Success: `admin_added`. Errors: `username_invalid`, `object_exists`, - `password_complexity`, `password_mismatch`. + Messages: `admin_added`; errors `object_exists`, `password_complexity`, + `password_mismatch`. operationId: addAdmin tags: - Administrators @@ -14515,9 +13875,7 @@ paths: description: The password again active: type: [integer, string, boolean] - description: >- - 1 = the account can log in, 0 = disabled. Missing counts as - 0: send `1` for a usable account. + description: 1 = the account can log in, 0 = disabled default: 0 required: - username @@ -14539,20 +13897,14 @@ paths: post: summary: Edit administrators description: >- - Changes administrator accounts. Attributes that are not sent keep their - value, except `force_tfa` and `force_pw_update`, which are set to 0 when - they are missing. The password is only changed when `password` is not - empty. Renaming an account moves its two-factor authentication and the - sync job sources it created to the new name (FIDO2 keys stay with the - old name). + 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. - One message per account. Success: `admin_modified`. Errors: - `access_denied` (no administrator of this name), `username_invalid` - (invalid `username_new` or the name of another administrator), warning - `no_active_admin` (the last active administrator cannot be - deactivated). A password that does not match `password2` or the policy - (`password_mismatch`, `password_complexity`) stops the call. + Messages: `admin_modified`; errors `username_invalid`, + `password_mismatch`, `password_complexity`; warning `no_active_admin`. operationId: editAdmin tags: - Administrators @@ -14595,9 +13947,7 @@ paths: default: 0 disable_tfa: type: [integer, string, boolean] - description: >- - Present (with any value) = deactivate the two-factor - authentication of the account + description: Present (any value) = turn off two-factor authentication required: - items - attr @@ -14620,14 +13970,11 @@ paths: post: summary: Delete administrators description: >- - Deletes administrator accounts with their two-factor authentication - and FIDO2 keys; sync job sources they created are released. + Deletes administrators with their two-factor authentication and FIDO2 + keys. - One message per account. Success: `admin_removed`. Errors: - `username_invalid` (no administrator of this name), warning - `cannot_delete_self` (the account of the current login, never the case - for an API key). + Messages: `admin_removed`; error `username_invalid`. operationId: deleteAdmin tags: - Administrators @@ -14652,10 +13999,7 @@ paths: /api/v1/get/passwordpolicy: get: summary: Get password policy - description: >- - The password policy for mailboxes, administrators and domain - administrators. Any further path segment except `html` gives the same - answer. + description: The password policy for mailboxes, administrators and domain administrators. operationId: getPasswordPolicy tags: - Password policy @@ -14678,8 +14022,8 @@ paths: get: summary: Get password policy as HTML description: >- - The password policy as an HTML snippet in the default language, as the - mailcow UI shows it below password fields. + The password policy as HTML snippet in the default language, as shown + below password fields. operationId: getPasswordPolicyHtml tags: - Password policy @@ -14697,12 +14041,11 @@ paths: post: summary: Edit password policy description: >- - Changes the password policy; attributes that are not sent keep their - value. The policy is checked when a password is set, existing passwords - are not affected. `items` is not used. + Changes the password policy; fields not sent keep their value. Existing + passwords are not checked again. - Success: `password_policy_saved`. + Messages: `password_policy_saved`. operationId: editPasswordPolicy tags: - Password policy @@ -14751,17 +14094,17 @@ paths: post: summary: Edit password reset e-mail description: >- - Sets sender, subject and templates of the e-mail a mailbox user gets - to reset a forgotten password (sent to the recovery address of the - mailbox). All four values are replaced: a missing value is saved as - empty; without both templates the default templates are used. - Password reset is only offered while sender and subject are set. - Subject and templates may use the placeholders `{{username}}`, - `{{username2}}` (recovery address), `{{date}}`, `{{token_lifetime}}` - (minutes), `{{hostname}}` and `{{link}}`. `items` is not used. + 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. - Success: `saved_settings`. + Placeholders: `{{username}}`, `{{username2}}` (recovery address), + `{{date}}`, `{{token_lifetime}}` (minutes), `{{hostname}}`, `{{link}}`. + + + Messages: `saved_settings`. operationId: editPasswordResetNotification tags: - Password policy @@ -14806,14 +14149,12 @@ paths: post: summary: Edit app links description: >- - Replaces the custom links of the "Apps" menu. The links are sent as - four lists of equal length, one entry per link; if the lengths differ, - nothing is saved but `app_links` is reported anyway. An empty list - removes all custom links. The links of mailcow itself (SOGo, ...) are - set in vars.local.inc.php and are not affected. `items` is not used. + 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. - Success: `app_links`. Error: `demo_mode_enabled`. + Messages: `app_links`. operationId: editAppLinks tags: - UI customization @@ -14839,16 +14180,12 @@ paths: type: string user_href: type: array - description: >- - URLs for logged-in accounts, `%u` is replaced with the - username; empty = `href` + description: URLs for logged-in accounts (`%u` = username); empty = `href` items: type: string hide: type: array - description: >- - Per link: `"0"` or `0` shows it on the login page, any - other value (also `false`) hides it there + description: Per link, `0` shows it on the login page, any other value (even `false`) hides it items: type: [string, integer, boolean] required: @@ -14878,11 +14215,11 @@ paths: post: summary: Edit login page options description: >- - Sets the options of the login pages. All four options are replaced: a - missing option counts as 0. `items` is not used. + Sets the login page options. All four are replaced: a missing option + counts as 0. - Success: `custom_login_modified`. Error: `demo_mode_enabled`. + Messages: `custom_login_modified`. operationId: editCustomLogin tags: - UI customization @@ -14910,10 +14247,7 @@ paths: default: 0 force_sso: type: [integer, string, boolean] - description: >- - 1 = with an OIDC identity provider configured, show only - the Single Sign-On button instead of the mailcow login - form + description: 1 = show only the Single Sign-On button (needs an OIDC identity provider) default: 0 required: - attr @@ -14934,12 +14268,11 @@ paths: post: summary: Edit IP check description: >- - Opt-in for the IP check of the dashboard, which asks the third party - services ipv4.mailcow.email and ipv6.mailcow.email for the public - addresses of the server. `items` is not used. + Turns the dashboard IP check on or off, which asks ipv4.mailcow.email + and ipv6.mailcow.email for the public addresses. - Success: `ip_check_opt_in_modified`. Error: `demo_mode_enabled`. + Messages: `ip_check_opt_in_modified`. operationId: editIpCheck tags: - UI customization @@ -14974,11 +14307,10 @@ paths: summary: Edit UI texts description: >- Sets the texts of the mailcow UI. All values are replaced: a missing - value is saved as empty, which means the default for the three names. - `items` is not used. + one is saved as empty. - Success: `ui_texts`. Error: `demo_mode_enabled`. + Messages: `ui_texts`. operationId: editUiTexts tags: - UI customization @@ -15044,12 +14376,10 @@ paths: post: summary: Edit UI theme description: >- - Selects the theme of the mailcow UI. Themes are folders - `data/web/css/themes//` with a `theme.css`. `items` is not used. + Selects the UI theme by its folder name in `data/web/css/themes/`. - Success: `ui_theme_modified`. Errors: `ui_theme_invalid` (no theme of - this name), `demo_mode_enabled`. + Messages: `ui_theme_modified`; error `ui_theme_invalid`. operationId: editUiTheme tags: - UI customization @@ -15064,9 +14394,7 @@ paths: type: object properties: ui_theme: - description: >- - Folder name of the theme; empty or missing = the default - theme. A list counts with its first entry. + description: Folder name of the theme, empty = default theme; of a list only the first entry counts oneOf: - type: string - type: array