This API should be used by your application and not by the end users directly, so normally it should probably be hidden behind a firewall.
To add another layer of protection the API can be set to require an access token. The token value can be set in configuration file "api.accessToken". If the value is set, then all requests against the API must include a query argument *accessToken* with the same value as in the configuration file.
For paging lists longer than allowed limit, Wild Duck API returns URLs for `next` and `previous` pages. When paging do not change these URLs yourself. If query arguments are changed then the results might be unreliable.
Recipient/forward limits assume that messages are sent using ZoneMTA with [zonemta-wildduck](https://github.com/wildduck-email/zonemta-wildduck) plugin, otherwise the counters are not updated.
### Add a new user
#### POST /users
Creates a new user, returns the ID upon success.
**Parameters**
- **username** (required) is the username of the user. This is not an email address but authentication username, use only letters and numbers
- **password** (required) is the password for the user
- **address** is the main email address for the user. If address is not set then a new one is generated based on the username and current domain name
- **name** is the name for the user
- **forward** is an email address to where all messages are forwarded to
- **targetUrl** is an URL to where all messages are uploaded to
- **quota** is the maximum storage in bytes allowed for this user. If not set then the default value is used
- **retention** is the default retention time in ms for mailboxes. Messages in Trash and Junk folders have a capped retention time of 30 days.
- **language** is the language code for the user, eg. "en" or "et". Mailbox names for the default mailboxes (eg. "Trash") depend on the language
- **recipients** is the maximum number of recipients allowed to send mail to in a 24h window. Requires ZoneMTA with the Wild Duck plugin
- **forwards** is the maximum number of forwarded emails in a 24h window. Requires ZoneMTA with the Wild Duck plugin
- **ip** is the IP address the request was made from
- **username** (required) is the username or one of the email addresses of the user
- **password** (required) is the password for the user. Can be either master password or an [application specific password](#application-specific-passwords)
- **scope** is the scope to request for (defaults to "master"). Application specific password can not be used with "master" scope. Allowed scopes are "master", "imap", "pop3", "smtp"
- **protocol** is the application type this authentication is made from, eg "IMAP" or "API"
- **ip** is the IP address the request was made from
**Response fields**
- **success** should be `true`
- **id** is the id of the authenticated user
- **username** is the user name of the logged in user (useful if you logged in used)
- **scope** is the scope this authentication is valid for
- **require2fa** if `true` the the user should also [provide a 2FA token](#verify-2fa) before the user is allowed to proceed
- **action** is an optional filter to list only specific actions, for example "create asp" to list only entries for creating new application specific passwords
Wild Duck supports TOTP based 2FA. If 2FA is enabled then users are requested to enter authentication token after successful login. Also, with 2FA enabled, master password can not be used in IMAP, POP3 or SMTP. The user must create an [Application Specific Password](#application-specific-passwords) with a correct scope for email clients using these protocols.
2FA checks do not happen magically, your application must be 2FA aware:
1. Authenticate user with the [/authenticate](#authenticate-an-user) call
2. If authentication ends with `require2fa:false` then do nothing, otherwise continue with Step 3.
3. Request TOTP token from the user before allowing to perform other actions
4. Check the token with [/user/{user}/2fa?token=123456](#check-2fa)
5. If token verification succeeds then user is authenticated
### Setup 2FA
#### POST /users/{user}/2fa
This call prepares the user to support 2FA tokens. If 2FA is already enabled then this call fails.
**Parameters**
- **user** (required) is the ID of the user
- **issuer** is the name to be shown in the Authenticator App
Once 2FA QR code is generated the user must return the token with this call. Once the token is successfully provided then 2FA is enabled for the account.
**Parameters**
- **user** (required) is the ID of the user
- **token** is the 2FA token generated from the QR code
- **ip** is the IP address the request was made from
Application Specific Passwords can be used to allow specific applications to access only specific parts of the user account. For example one password can be used to access IMAP, one for SMTP etc.
### List existing passwords
#### GET /user/{user}/asps
Lists all application specific passwords for an user.
- **scopes** is an array (or a comma separated string) of scopes this password is valid for. Valid scopes are "imap", "pop3", "smtp". Special scope "*" (also the default) is valid for all ASP supported scopes (this does not include "master")
Resulting password should be shown to the client. This password is shown only once so if the user forgets it then the APS should be deleted and replaced with a new one. Application Specific Password can include spaces, so using "slrf waav yzma tgxf" is the same as "slrfwaavyzmatgxf".
Profile file should be sent to the client with Content-Type value of `application/x-apple-aspen-config`.
Creates a new email address alias for an existing user, returns the ID upon success.
**Parameters**
- **user** (required) is the ID of the user
- **address** (required) is the email address to use as an alias for this user. You can also use internationalized email addresses like _андрис@уайлддак.орг_.
- **main** indicates that this is the default address for that user (defaults to _false_)
- **counters** is an optional GET argument to include counters (total messages, unseen messages) in listing results. Not recommended if you have a large list as checking every counter can be expensive operation.
Creates a new mailbox for an existing user account, returns the ID upon success.
**Parameters**
- **user** (required) is the ID of the user
- **path** (required) is the mailbox path with slashes as folder separators. Parent folder does not have to exist. Using unicode characters is allowed.
- **retention** optional retention time in milliseconds that applies to messages in that mailbox
- **path** is the optional new mailbox path if you want to rename the mailbox. INBOX can not be renamed.
- **retention** is the optional new retention time. Changing retention time applies only to new messages. Existing messages expire once the original retention time is reached
Manage messages in a mailbox. While other data types usually have a 24 byte hex string ID value then message object have integers as IDs. These values map to IMAP UID values.
### List existing messages
#### GET /user/{user}/mailboxes/{mailbox}/messages
Lists existing messages in a mailbox
**Parameters**
- **user** (required) is the ID of the user
- **mailbox** (required) is the ID of the mailbox
- **order** optional message ordering, either "asc" or "desc". Defaults to "desc" (newer first)
The search uses MongoDB fulltext index, see [MongoDB docs](https://docs.mongodb.com/manual/reference/operator/query/text/#search-field) for explanation how to use it.
### Get message details
#### GET /users/{user}/mailboxes/{mailbox}/messages/{message}
"Notice that the HTML content is an array of HTML strings"
],
"attachments": []
}
```
### Update message details
#### PUT /users/{user}/mailboxes/{mailbox}/messages/{message}
Updates the properties of a message or move the message to another mailbox. This call can be used to modify more than a single message at once (see the "messge" parameter description).
**Parameters**
- **user** (required) is the ID of the user
- **mailbox** (required) is the ID of the mailbox
- **message** (required) is the ID of the message (eg. "messages/444") or a comma separated list of IDs (eg. "messages/444,445,446") or a range of message IDs (eg. "messages/444:446")
- **moveTo** is the ID of the destination mailbox if you want to move the message
- **seen** is a boolean to mark message as seen or unseen
- **flagged** is a boolean to mark message as flagged or not
- **draft** is a boolean to mark message as a draft or not
- **deleted** is a boolean to mark message as deleted or not. This value is used by IMAP clients to indicate that a message should be deleted in the future
- **expires** is either a date/timestamp to autodelete the message at given time or `false` if you want to clear the expiration date. Message is not deleted exactly on the expire time, it is only marked to be deleted and it is removed after the garbage collector process steps in.
Manage message filters. Filters are applied to incoming messages in LMTP and these can be used to move specific messages to specific mailboxes, mark messages as seen etc.
### Create new filter
#### POST /users/{user}/filters
Creates a filter
**Parameters**
- **user** (required) is the ID of the user
- **filter** (required) is the ID of the filter to update
- **name** is the name of the filter
- **query_from** is a string to match against the From: header
- **query_to** is a string to match against the To:/Cs: headers
- **query_subject** is a string to match against the Subject: header
- **query_text** is a string to match against the message text
- **query_ha** is a boolean that requires the message to have attachments (true) or not attachments (false)
- **query_size** is a number that requires the RFC822 message size be larger than (positive integer) or smaller than (negative integer)
- **action_seen** is a boolean that marks message as seen (true) or unseen (false)
- **action_flag** is a boolean that marks message as flagged (true) or not (false)
- **action_delete** is a boolean that makes the message to be deleted immediately (true). This action does not initiate a bounce, the message is dropeed silently
- **action_spam** is a boolean that marks message as spam (true) or not spam (false). Spam messages are automatically moved to the Junk mailbox
- **action_mailbox** is the mailbox ID the message should me moved to
- **action_forward** is an email address the message should be forwarded to. You can also mix this action with `delete`.
- **action_targetUrl** is a web URL the message should be uploaded to
If a key is not included or is empty in update payload then the key is not used for when filtering.
**Example**
This example sets up a filter to search for "abc" in From: header, matching messages are flagged.
The listing entries include query and action arrays. These are meant to be human readable descriptions divided into tuples. This would allow using translation on the left side elements (keys). In the end these values should be joined together into a description string.
Updates the properties of a filter. To unset a specific key use an empty string as the value.
**Parameters**
- **user** (required) is the ID of the user
- **filter** (required) is the ID of the filter to update
- **name** is the name of the filter
- **query_from** is a string to match against the From: header
- **query_to** is a string to match against the To:/Cs: headers
- **query_subject** is a string to match against the Subject: header
- **query_text** is a string to match against the message text
- **query_ha** is a boolean that requires the message to have attachments (true) or not attachments (false)
- **query_size** is a number that requires the RFC822 message size be larger than (positive integer) or smaller than (negative integer)
- **action_seen** is a boolean that marks message as seen (true) or unseen (false)
- **action_flag** is a boolean that marks message as flagged (true) or not (false)
- **action_delete** is a boolean that makes the message to be deleted immediately (true). This action does not initiate a bounce, the message is dropeed silently
- **action_spam** is a boolean that marks message as spam (true) or not spam (false). Spam messages are automatically moved to the Junk mailbox
- **action_mailbox** is the mailbox ID the message should me moved to
- **action_forward** is an email address the message should be forwarded to. You can also mix this action with `delete`.
- **action_targetUrl** is a web URL the message should be uploaded to
If a key is not included in update payload then the value is left as is. Empty value clears the key if it is set.
**Example**
This example clears query_from, requires messages to have attachments and marks these as spam
First entry in the event stream indicates that a message with id `596e0703f0bdd512aeac3600` was added to mailbox `596c9c37ef2213165daadc65`, second entry indicates that a new mailbox called *"My Mail"* with id `596e09853f845a14f3620b5c` was created.
Be aware though that this connection needs to be properly closed if you do not want to end up with memory leaks.
You can see a demo of catching user events when navigating to http://localhost:8080/public/ (assuming localhost:8080 is your API host).