wildduck/docs/api.md

2206 lines
62 KiB
Markdown
Raw Normal View History

2017-07-25 18:56:50 +08:00
# HTTP API
2018-01-21 03:38:56 +08:00
**DEPRECATED DOCS**, see https://api.wildduck.email
2018-01-02 21:04:01 +08:00
WildDuck Mail Server is a scalable IMAP / POP3 server that natively exposes internal data through an HTTP API.
2017-07-25 18:56:50 +08:00
2017-07-25 20:50:16 +08:00
This API is not meant to be used by end users but your application.
2017-11-23 17:51:37 +08:00
<!-- toc -->
2018-04-29 03:44:38 +08:00
* [API Usage Info](#api-usage-info)
* [Authentication](#authentication)
* [Responses](#responses)
* [Paging](#paging)
* [Users](#users)
* [Search and list users](#search-and-list-users)
* [GET /users](#get-users)
* [Get one user](#get-one-user)
* [GET /users/{user}](#get-usersuser)
* [Add a new user](#add-a-new-user)
* [POST /users](#post-users)
* [Update user details](#update-user-details)
* [PUT /users/{user}](#put-usersuser)
* [Delete user](#delete-user)
* [DELETE /users/{user}](#delete-usersuser)
* [Log out user from all IMAP sessions](#log-out-user-from-all-imap-sessions)
* [PUT /users/{user}/logout](#put-usersuserlogout)
* [Reset user password](#reset-user-password)
* [POST /users/{user}/password/reset](#post-usersuserpasswordreset)
* [Authentication](#authentication-1)
* [Authenticate an user](#authenticate-an-user)
* [POST /authenticate](#post-authenticate)
* [List the authentication log](#list-the-authentication-log)
* [GET /users/{user}/authlog](#get-usersuserauthlog)
* [2FA](#2fa)
* [Setup 2FA](#setup-2fa)
* [POST /users/{user}/2fa/totp/setup](#post-usersuser2fatotpsetup)
* [Verify 2FA](#verify-2fa)
* [POST /users/{user}/2fa/totp/enable](#post-usersuser2fatotpenable)
* [Check 2FA](#check-2fa)
* [POST /users/{user}/2fa/totp/check](#post-usersuser2fatotpcheck)
* [Disable TOTP](#disable-totp)
* [DELETE /users/{user}/2fa/totp](#delete-usersuser2fatotp)
* [Disable 2FA](#disable-2fa)
* [DELETE /users/{user}/2fa](#delete-usersuser2fa)
* [Application Specific Passwords](#application-specific-passwords)
* [List existing passwords](#list-existing-passwords)
* [GET /user/{user}/asps](#get-useruserasps)
* [Add a new Application Specific Password](#add-a-new-application-specific-password)
* [POST /users/{user}/asps](#post-usersuserasps)
* [Delete an Application Specific Password](#delete-an-application-specific-password)
* [DELETE /users/{user}/asps/{asp}](#delete-usersuseraspsasp)
* [Addresses](#addresses)
* [Search and list addresses](#search-and-list-addresses)
* [GET /addresses](#get-addresses)
* [List user addresses](#list-user-addresses)
* [GET /users/{user}/addresses](#get-usersuseraddresses)
* [Get one address](#get-one-address)
* [GET /users/{user}/addresses/{address}](#get-usersuseraddressesaddress)
* [Add a new address](#add-a-new-address)
* [POST /users/{user}/addresses](#post-usersuseraddresses)
* [Update address details](#update-address-details)
* [PUT /users/{user}/addresses/{address}](#put-usersuseraddressesaddress)
* [Delete an alias address](#delete-an-alias-address)
* [DELETE /users/{user}/addresses/{address}](#delete-usersuseraddressesaddress)
* [Mailboxes](#mailboxes)
* [List existing mailboxes](#list-existing-mailboxes)
* [GET /user/{user}/mailboxes](#get-userusermailboxes)
* [Get one mailbox](#get-one-mailbox)
* [GET /users/{user}/mailboxes/{mailbox}](#get-usersusermailboxesmailbox)
* [Add a new mailbox](#add-a-new-mailbox)
* [POST /users/{user}/mailboxes](#post-usersusermailboxes)
* [Update mailbox details](#update-mailbox-details)
* [PUT /users/{user}/mailboxes/{mailbox}](#put-usersusermailboxesmailbox)
* [Delete a mailbox](#delete-a-mailbox)
* [DELETE /users/{user}/mailboxes/{mailbox}](#delete-usersusermailboxesmailbox)
* [Messages](#messages)
* [List existing messages](#list-existing-messages)
* [GET /user/{user}/mailboxes/{mailbox}/messages](#get-userusermailboxesmailboxmessages)
* [List flagged messages](#list-flagged-messages)
* [GET /user/{user}/flagged](#get-useruserflagged)
* [Search for messages](#search-for-messages)
* [GET /user/{user}/search](#get-userusersearch)
* [Get message details](#get-message-details)
* [GET /users/{user}/mailboxes/{mailbox}/messages/{message}](#get-usersusermailboxesmailboxmessagesmessage)
* [Get message events](#get-message-events)
* [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/events](#get-usersusermailboxesmailboxmessagesmessageevents)
* [Update message details](#update-message-details)
* [PUT /users/{user}/mailboxes/{mailbox}/messages/{message}](#put-usersusermailboxesmailboxmessagesmessage)
* [Delete a message](#delete-a-message)
* [DELETE /users/{user}/mailboxes/{mailbox}/messages/{message}](#delete-usersusermailboxesmailboxmessagesmessage)
* [Get message source](#get-message-source)
* [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/message.eml](#get-usersusermailboxesmailboxmessagesmessagemessageeml)
* [Get message attachment](#get-message-attachment)
* [GET /users/{user}/mailboxes/{mailbox}/messages/{message}/attachments/{attachment}](#get-usersusermailboxesmailboxmessagesmessageattachmentsattachment)
* [Filters](#filters)
* [Create new filter](#create-new-filter)
* [POST /users/{user}/filters](#post-usersuserfilters)
* [List existing filters](#list-existing-filters)
* [GET /user/{user}/filters](#get-useruserfilters)
* [Get filter details](#get-filter-details)
* [GET /users/{user}/filters/{filter}](#get-usersuserfiltersfilter)
* [Update filter details](#update-filter-details)
* [PUT /users/{user}/filters/{filter}](#put-usersuserfiltersfilter)
* [Delete a filter](#delete-a-filter)
* [DELETE /users/{user}/filters/{filter}](#delete-usersuserfiltersfilter)
* [Autoreplies](#autoreplies)
* [Setup Autoreply](#setup-autoreply)
* [PUT /users/{user}/autoreply](#put-usersuserautoreply)
* [Disable Autoreply](#disable-autoreply)
* [DELETE /users/{user}/autoreply](#delete-usersuserautoreply)
* [Check Autoreply status](#check-autoreply-status)
* [GET /users/{user}/autoreply](#get-usersuserautoreply)
* [Archive](#archive)
* [List archived messages](#list-archived-messages)
* [GET /user/{user}/archived](#get-useruserarchived)
* [Get archived message details](#get-archived-message-details)
* [GET /users/{user}/archived/{message}](#get-usersuserarchivedmessage)
* [Restore archived message](#restore-archived-message)
* [POST /users/{user}/archived/{message}/restore](#post-usersuserarchivedmessagerestore)
* [Quota](#quota)
* [Recalculate user quota](#recalculate-user-quota)
* [POST /users/{user}/quota/reset](#post-usersuserquotareset)
* [Updates](#updates)
* [Stream update events](#stream-update-events)
* [GET /users/{user}/updates](#get-usersuserupdates)
2017-11-23 17:51:37 +08:00
<!-- tocstop -->
2017-07-25 18:56:50 +08:00
## API Usage Info
2017-07-25 20:50:16 +08:00
### Authentication
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.
2017-11-23 17:51:37 +08:00
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.
2017-07-25 20:50:16 +08:00
```
curl "http://localhost:8080/users?query=testuser01&accessToken=secrettoken"
```
2017-07-25 18:56:50 +08:00
### Responses
All successful responses look like the following:
```
{
"success": true,
other response specific fields
}
```
All failed responses look like the following:
```json
{
2017-11-23 17:51:37 +08:00
"error": "Some error message"
2017-07-25 18:56:50 +08:00
}
```
### Paging
2018-01-02 21:04:01 +08:00
For paging lists longer than allowed limit, WildDuck API returns cursors for `next` and `previous` pages.
2017-07-25 18:56:50 +08:00
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"total": 200,
"page": 2,
"results": ["a list of results"],
"previousCursor": "abcdef12344",
"nextCursor": "abcdef12377"
2017-07-25 18:56:50 +08:00
}
```
2017-11-23 17:51:37 +08:00
The `page` property in return value is a "soft" argument, you need to set it yourself with the query argument. WildDuck does not know from which page the
request was made to but your application does. `limit` argument limits the output size (in most cases can not be set higher than 250).
2017-11-22 22:22:36 +08:00
Fetch next page using cursors:
2017-11-23 17:51:37 +08:00
GET /users/{user}/mailboxes/{mailbox}/messages?next={nextCursor}&page={page+1}&limit=20
2017-11-22 22:22:36 +08:00
Fetch previous page using cursors:
2017-11-23 17:51:37 +08:00
GET /users/{user}/mailboxes/{mailbox}/messages?previous={previousCursor}&page={page-1}&limit=20
2017-11-22 22:22:36 +08:00
2017-07-25 18:56:50 +08:00
## Users
User accounts
### Search and list users
#### GET /users
Returns data about existing users
**Parameters**
2018-04-29 03:44:38 +08:00
* **query** is an optional string to filter username (partial match), by default all users are listed
* **limit** is an optional number to limit listing length, defaults to 20
* **tags** is an optional string of comma separated tags. At least a single tag must be set for an user to be listed
* **requiredTags** is an optional string of comma separated tags. All tags must be set for an user to be listed
2017-07-25 18:56:50 +08:00
**Example**
```
2017-11-23 17:51:37 +08:00
curl "http://localhost:8080/users?query=testuser01&tags=red,green"
2017-07-25 18:56:50 +08:00
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"query": "testuser01",
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"results": [
{
"id": "59fc66a03e54454869460e45",
"username": "testuser01@example.com",
"name": null,
"address": "testuser01@example.com",
"tags": ["green", "blue"],
"encryptMessages": false,
"encryptForwarded": false,
"quota": {
"allowed": 107374182400,
"used": 289838
},
"hasPasswordSet": true,
"activated": true,
"disabled": false
}
]
2017-07-25 18:56:50 +08:00
}
```
### Get one user
#### GET /users/{user}
Returns data about a specific user
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** is the ID of the user
2017-07-25 18:56:50 +08:00
**Example**
```
2017-11-23 17:51:37 +08:00
curl "http://localhost:8080/users/59fc66a03e54454869460e45"
2017-07-25 18:56:50 +08:00
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59fc66a03e54454869460e45",
"username": "testuser01",
"name": null,
"address": "testuser01@example.com",
"retention": false,
"enabled2fa": [],
"encryptMessages": false,
"encryptForwarded": false,
"pubKey": "",
"keyInfo": false,
"limits": {
"quota": {
"allowed": 107374182400,
"used": 289838
},
"recipients": {
"allowed": 2000,
"used": 0,
"ttl": false
},
"forwards": {
"allowed": 2000,
"used": 0,
"ttl": false
}
2017-07-25 18:56:50 +08:00
},
2017-11-23 17:51:37 +08:00
"tags": ["green", "blue"],
"hasPasswordSet": true,
"activated": true,
"disabled": false
2017-07-25 18:56:50 +08:00
}
```
2017-11-23 17:51:37 +08:00
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 or checked.
2017-07-25 18:56:50 +08:00
### Add a new user
#### POST /users
Creates a new user, returns the ID upon success.
**Parameters**
2018-04-29 03:44:38 +08:00
* **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. You can use `false` to create an account without a password
* **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
* **emptyAddress** if true, then do not set up an address for the user
* **name** is the name for the user
* **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 WildDuck plugin
* **forwards** is the maximum number of forwarded emails in a 24h window. Requires ZoneMTA with the WildDuck plugin
* **tags** is an array of tags to be associated with that user. Tags can be used for filtering.
* **pubKey** is an optional PGP public key. WildDuck uses OpnePGP.js so keys using EC might not pass validation.
* **encryptMessages** (boolean) indicates if messages stored should be encrypted using the PGP key
* **encryptForwarded** (boolean) indicates if forwarded messages stored be encrypted using the PGP key. Encryption applies after filter rules
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users" -H 'content-type: application/json' -d '{
"username": "testuser",
"password": "secretpass",
"address": "testuser@example.com",
"ip": "192.168.10.10"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59708695cdb513ce63340801"
2017-07-25 18:56:50 +08:00
}
```
After you have created an user you can use these credentials to log in to the IMAP server.
### Update user details
#### PUT /users/{user}
2017-07-25 18:56:50 +08:00
Updates the properties of an user. Only specify these fields that you want to be updated.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **name** is the updated name for the user
* **password** is the updated password for the user (do not set if you do not want to change user password)
* **quota** is the maximum storage in bytes allowed for this user
* **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"
* **recipients** is the maximum number of recipients allowed to send mail to in a 24h window. Requires ZoneMTA with the WildDuck plugin
* **forwards** is the maximum number of forwarded emails in a 24h window. Requires ZoneMTA with the WildDuck plugin
* **tags** is an array of tags to be associated with that user. Tags can be used for filtering.
* **pubKey** is an optional PGP public key. WildDuck uses OpnePGP.js so keys using EC might not pass validation.
* **encryptMessages** (boolean) indicates if messages stored should be encrypted using the PGP key
* **encryptForwarded** (boolean) indicates if forwarded messages stored be encrypted using the PGP key. Encryption applies after filter rules
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
If you want the user to verify existing password before changing anything you can add the following POST field:
2018-04-29 03:44:38 +08:00
* **existingPassword** is the current password provided by the user for extra verification
2017-07-25 18:56:50 +08:00
**Example**
Set user quota to 1 kilobyte:
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6" -H 'content-type: application/json' -d '{
"quota": 1024
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-11-17 19:37:53 +08:00
### Delete user
#### DELETE /users/{user}
2017-11-23 17:51:37 +08:00
Deletes user data form database. Messages are not immediately deleted but marked to be deleted in 2 days. Various related log entries expire by default
retention settings and are not touched by this call
2017-11-17 19:37:53 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** is the ID of the user
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-11-17 19:37:53 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/5970860fcdb513ce633407a1"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-11-17 19:37:53 +08:00
}
```
### Log out user from all IMAP sessions
#### PUT /users/{user}/logout
Forces closing all active IMAP session of an user
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **reason** is an optional message to be sent to the user with logout notification
**Example**
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6/logout" -H 'content-type: application/json' -d '{
2017-10-03 16:18:23 +08:00
"reason": "Account was deleted"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
}
```
### Reset user password
#### POST /users/{user}/password/reset
2017-11-23 17:51:37 +08:00
Generates a new temporary password and resets 2FA if set. Once user password is reset, then authentication results will include `requirePasswordChange: true`
parameter. This means that the user should not be able to perform regular actions before the password has been changed.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
**Example**
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/password/reset" -H 'content-type: application/json' -d '{}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"password": "somesecretvalue"
}
```
2017-07-25 18:56:50 +08:00
## Authentication
### Authenticate an user
#### POST /authenticate
Authenticates an user
**Parameters**
2018-04-29 03:44:38 +08:00
* **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". Only needed for logging
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **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** is an array of enabled 2FA mechanisms for this user. If the value is an empty array then 2FA is not enabled
* **requirePasswordChange** if `true` then the user should be forced to change their password
* **u2fAuthRequest** is set if U2F is enabled and 2FA is required. This value can be used to set up U2F check
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/authenticate" -H 'content-type: application/json' -d '{
"username": "testuser",
"password": "amurboxphxvnyqre",
"scope": "pop3",
"ip": "192.168.10.10"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "5971da1754cfdc7f0983b2ec",
"username": "testuser",
"scope": "pop3",
"require2fa": false,
"requirePasswordChange": false
2017-07-25 18:56:50 +08:00
}
```
### List the authentication log
#### GET /users/{user}/authlog
Returns data about authentication related events. This includes also password changes, application specific password changes etc.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **limit** is an optional number to limit listing length, defaults to 20
* **action** is an optional filter to list only specific actions, for example "create asp" to list only entries for creating new application specific passwords
* **sess** is an optional session identifier to be used for filtering
* **ip** is an optional IP address to be used for filtering
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/authlog"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": "sadasdsdfdfdfg",
"results": [
{
"id": "59762d2f9c035be17bbb1fdf",
"action": "create asp",
"asp": "59762d2f9c035be17bbb1fde",
"result": "success",
"ip": "192.168.10.10",
"created": "2017-07-24T17:23:59.041Z"
}
]
2017-07-25 18:56:50 +08:00
}
```
Log entries expire after 30 days.
## 2FA
2018-01-02 21:04:01 +08:00
WildDuck supports TOTP and U2f based 2FA. If 2FA is enabled then users are requested to enter authentication token after successful login. Also, with 2FA
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
2FA checks do not happen magically, your application must be 2FA aware:
2018-04-29 03:44:38 +08:00
1. Authenticate user with the [/authenticate](#authenticate-an-user) call
2. If authentication result includes `requirePasswordChange:true` then force user to change their password
3. If authentication result includes `require2fa:false` then do nothing, the user is now authenticated. Otherwise continue with Step 4. or Step 5.
4. If `require2fa` array includes 'totp' then:
5. Request TOTP token from the user before allowing to perform other actions
6. Check the token with _/user/{user}/2fa/totp/check_
7. If token verification succeeds then user is authenticated
8. If `require2fa` array includes 'u2f' then:
9. Authentication response should include u2fAuthRequest object. If it is missing or verification times out then you can fetch a new U2F request object from the
server with _/user/{user}/2fa/u2f/start_
2017-11-23 17:51:37 +08:00
10. Send authentication request to U2F key
11. Send authentication response from key to server with _/user/{user}/2fa/totp/check_
12. If token verification succeeds then user is authenticated
2017-07-25 18:56:50 +08:00
### Setup 2FA
2017-10-10 16:19:10 +08:00
#### POST /users/{user}/2fa/totp/setup
2017-07-25 18:56:50 +08:00
This call prepares the user to support 2FA tokens. If 2FA is already enabled then this call fails.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **issuer** is the name to be shown in the Authenticator App
* **fresh** is a boolean. If true then generates a new seed even if an old one already exists
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
* **qrcode** is the data url for the 2FA QR-code. The user must scan the code and return the token with a PUT call
2017-07-25 18:56:50 +08:00
**Example**
```
2017-10-10 16:19:10 +08:00
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/2fa/totp/setup" -H 'content-type: application/json' -d '{
2017-07-25 18:56:50 +08:00
"issuer": "testikas",
"ip": "192.168.10.10"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSU..."
2017-07-25 18:56:50 +08:00
}
```
### Verify 2FA
2017-10-10 16:19:10 +08:00
#### POST /users/{user}/2fa/totp/enable
2017-07-25 18:56:50 +08:00
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**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **token** is the 2FA token generated from the QR code
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-07-25 18:56:50 +08:00
**Example**
```
2017-10-10 16:19:10 +08:00
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/2fa/totp/enable" -H 'content-type: application/json' -d '{
2017-07-25 18:56:50 +08:00
"token": "455912",
"ip": "192.168.10.10"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-10-10 16:19:10 +08:00
### Check 2FA
2017-07-25 18:56:50 +08:00
2017-10-10 16:19:10 +08:00
#### POST /users/{user}/2fa/totp/check
2017-07-25 18:56:50 +08:00
2017-10-10 16:19:10 +08:00
Validates a TOTP token against user 2FA settings. This check should be performed when an user authentication response includes `request2fa:['totp']`
2017-07-25 18:56:50 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **token** (required) is the token to check
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-07-25 18:56:50 +08:00
**Example**
```
2017-10-10 16:19:10 +08:00
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/2fa/totp/check" -H 'content-type: application/json' -d '{
"token": "455912",
"ip": "192.168.10.10"
}'
2017-07-25 18:56:50 +08:00
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-10-10 16:19:10 +08:00
### Disable TOTP
2017-07-25 18:56:50 +08:00
2017-10-10 16:19:10 +08:00
#### DELETE /users/{user}/2fa/totp
2017-07-25 18:56:50 +08:00
2017-10-10 16:19:10 +08:00
Disabling TOTP for authentication. Other 2FA schemes remain in place.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-10-10 16:19:10 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-10-10 16:19:10 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/2fa/totp?ip=192.168.10.10"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-10-10 16:19:10 +08:00
}
```
### Disable 2FA
#### DELETE /users/{user}/2fa
Disables all 2FA schemes. Disabling 2FA re-enables master password usage for IMAP, POP3 and SMTP.
2017-07-25 18:56:50 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-07-25 18:56:50 +08:00
**Example**
```
2017-10-10 16:19:10 +08:00
curl -XDELETE "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/2fa?ip=192.168.10.10"
2017-07-25 18:56:50 +08:00
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
## Application Specific Passwords
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
### List existing passwords
#### GET /user/{user}/asps
Lists all application specific passwords for an user.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/asps"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"results": [
{
"id": "5975d1ac97130ca55afa0c7f",
"description": "OSX Mail App",
"scopes": ["*"],
"created": "2017-07-24T10:53:32.136Z"
},
{
"id": "5975f5e5453019c6ebfed3b4",
"description": "Nodemailer",
"scopes": ["smtp"],
"created": "2017-07-24T13:28:05.770Z"
}
]
2017-07-25 18:56:50 +08:00
}
```
### Add a new Application Specific Password
#### POST /users/{user}/asps
Creates a new Application Specific Password for an existing user, returns the ID upon success.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **description** (required) is the name or description for the new Application Specific Password
* **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")
* **generateMobileconfig** is a boolean. If true, then the result includes a base64 formatted profile file to autoconfigure OSX and iOS mail clients
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/asps" -H 'content-type: application/json' -d '{
"description": "Mac OSX Mail Client",
"scopes": ["*"],
"ip": "192.168.10.10"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59762d2f9c035be17bbb1fde",
"password": "mjxlzydlusadfynn"
2017-07-25 18:56:50 +08:00
}
```
2017-07-26 15:45:46 +08:00
Or with the profile file:
2017-07-25 20:50:16 +08:00
```
curl -XPOST "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/asps" -H 'content-type: application/json' -d '{
"description": "Mac OSX Mail Client",
2017-07-26 15:45:46 +08:00
"scopes": ["imap", "smtp"],
2017-07-25 20:50:16 +08:00
"generateMobileconfig": true
"ip": "192.168.10.10"
}'
```
2017-07-26 15:45:46 +08:00
and the result with the profile file:
2017-07-25 20:50:16 +08:00
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59773be3a7bc855155286d91",
"password": "slrfwaavyzmatgxf",
"mobileconfig": "MIIO8gYJKoZIhvcNAQcCo..."
2017-07-25 20:50:16 +08:00
}
```
2017-11-23 17:51:37 +08:00
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".
2017-07-26 15:45:46 +08:00
Profile file should be sent to the client with Content-Type value of `application/x-apple-aspen-config`.
```javascript
res.set('Content-Description', 'Mail App Configuration Profile');
res.set('Content-Type', 'application/x-apple-aspen-config');
res.set('Content-Disposition', 'attachment; filename="profile.mobileconfig"');
res.send(Buffer.from(asp.mobileconfig, 'base64'));
```
2017-07-25 18:56:50 +08:00
### Delete an Application Specific Password
#### DELETE /users/{user}/asps/{asp}
Deletes an Application Specific Password
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **asp** (required) is the ID of the Application Specific Password
* **sess** an optional string of user session to be stored in security log
* **ip** is the IP address the request was made from
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/59467f27535f8f0f067ba8e6/asps/59762d2f9c035be17bbb1fde?ip=192.168.10.10"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
## Addresses
Manage email addresses
### Search and list addresses
#### GET /addresses
Returns data about existing addresses. Use this endpoint if you want to find an address but do not know to which user it belongs to.
**Parameters**
2018-04-29 03:44:38 +08:00
* **query** is an optional string to filter addresses (partial match), by default all addresses are listed
* **limit** is an optional number to limit listing length, defaults to 20
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/addresses?query=testuser01"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"query": "testuser01",
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"results": [
{
"id": "5970860fcdb513ce633407a8",
"address": "testuser01@example.com",
"user": "5970860fcdb513ce633407a1"
}
]
2017-07-25 18:56:50 +08:00
}
```
### List user addresses
#### GET /users/{user}/addresses
Lists all registered email addresses for an user.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/addresses"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"results": [
{
"id": "596c9c37ef2213165daadc6b",
"address": "testuser@example.com",
"main": true,
"created": "2017-07-17T11:15:03.841Z"
},
{
"id": "596c9dd31b201716e764efc2",
"address": "user@example.com",
"main": false,
"created": "2017-07-17T11:21:55.960Z"
}
]
2017-07-25 18:56:50 +08:00
}
```
### Get one address
#### GET /users/{user}/addresses/{address}
Returns data about a specific address.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **address** (required) is the ID of the address
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/addresses/596c9c37ef2213165daadc6b"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "596c9c37ef2213165daadc6b",
"address": "testuser@example.com",
"main": true,
"created": "2017-07-17T11:15:03.841Z"
2017-07-25 18:56:50 +08:00
}
```
### Add a new address
#### POST /users/{user}/addresses
Creates a new email address alias for an existing user, returns the ID upon success.
**Parameters**
2018-04-29 03:44:38 +08:00
* **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_)
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/addresses" -H 'content-type: application/json' -d '{
"address": "user@example.com"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "596c9dd31b201716e764efc2"
2017-07-25 18:56:50 +08:00
}
```
After you have registered a new address then LMTP maildrop server starts accepting mail for it and stores messages to the users mailbox.
### Update address details
#### PUT /users/{user}/addresses/{address}
Updates the properties of an address. Currently, only `main` can be updated.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **address** (required) is the ID of the address
* **main** must be true. Indicates that this is the default address for that user
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6/addresses/596c9dd31b201716e764efc2" -H 'content-type: application/json' -d '{
"main": true
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-11-23 17:51:37 +08:00
2017-07-25 18:56:50 +08:00
### Delete an alias address
#### DELETE /users/{user}/addresses/{address}
Deletes an email address alias from an existing user.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **address** (required) is the ID of the address
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/59467f27535f8f0f067ba8e6/addresses/596c9dd31b201716e764efc2"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
## Mailboxes
Manage user mailboxes
### List existing mailboxes
#### GET /user/{user}/mailboxes
Lists existing mailboxes for an user
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **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.
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"results": [
{
"id": "597089f1b3378cd394611284",
"name": "INBOX",
"path": "INBOX",
"specialUse": null,
"modifyIndex": 71,
"subscribed": true
},
{
"id": "597089f1b3378cd394611289",
"name": "Archive",
"path": "Archive",
"specialUse": "\\Archive",
"modifyIndex": 0,
"subscribed": true
},
{
"id": "597089f1b3378cd394611287",
"name": "Drafts",
"path": "Drafts",
"specialUse": "\\Drafts",
"modifyIndex": 0,
"subscribed": true
}
]
2017-07-25 18:56:50 +08:00
}
```
List mailboxes with counters
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes?counters=true"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"mailboxes": [
{
"id": "597089f1b3378cd394611284",
"name": "INBOX",
"path": "INBOX",
"specialUse": null,
"modifyIndex": 71,
"subscribed": true,
"total": 33,
"unseen": 8
},
{
"id": "597089f1b3378cd394611289",
"name": "Archive",
"path": "Archive",
"specialUse": "\\Archive",
"modifyIndex": 0,
"subscribed": true,
"total": 0,
"unseen": 0
},
{
"id": "597089f1b3378cd394611287",
"name": "Drafts",
"path": "Drafts",
"specialUse": "\\Drafts",
"modifyIndex": 0,
"subscribed": true,
"total": 0,
"unseen": 0
}
]
2017-07-25 18:56:50 +08:00
}
```
### Get one mailbox
#### GET /users/{user}/mailboxes/{mailbox}
Returns data about a specific address.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/597089f1b3378cd394611284"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "597089f1b3378cd394611284",
"name": "INBOX",
"path": "INBOX",
"specialUse": null,
"modifyIndex": 71,
"subscribed": true,
"total": 33,
"unseen": 8
2017-07-25 18:56:50 +08:00
}
```
### Add a new mailbox
#### POST /users/{user}/mailboxes
Creates a new mailbox for an existing user account, returns the ID upon success.
**Parameters**
2018-04-29 03:44:38 +08:00
* **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
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes" -H 'content-type: application/json' -d '{
"path": "My New mailbox"
}'
```
or as a subfolder
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes" -H 'content-type: application/json' -d '{
"path": "Some parent/Subfolder/My New mailbox"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "596c9dd31b201716e764efc2"
2017-07-25 18:56:50 +08:00
}
```
### Update mailbox details
#### PUT /users/{user}/mailboxes/{mailbox}
Updates the properties of a mailbox.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the 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
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2" -H 'content-type: application/json' -d '{
"path": "New Mailbox Name"
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-11-23 17:51:37 +08:00
2017-07-25 18:56:50 +08:00
### Delete a mailbox
#### DELETE /users/{user}/mailboxes/{mailbox}
Deletes a mailbox. Only user made mailboxes can be deleted. Special mailboxes (INBOX, Trash etc) can not be deleted.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
## Messages
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
### List existing messages
#### GET /user/{user}/mailboxes/{mailbox}/messages
Lists existing messages in a mailbox
**Parameters**
2018-04-29 03:44:38 +08:00
* **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)
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2/messages"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"specialUse": null,
"results": [
{
"id": 444,
"mailbox": "59467f27535f8f0f067ba8e6",
"thread": "5971da7754cfdc7f0983bbde",
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"subject": "Subject line",
"date": "2011-11-02T19:19:08.000Z",
"intro": "Beginning text in the message…",
"attachments": false,
"seen": true,
"deleted": false,
"flagged": false,
"draft": false
}
]
2017-07-25 18:56:50 +08:00
}
```
2017-11-22 22:22:36 +08:00
### List flagged messages
#### GET /user/{user}/flagged
Lists flagged messages in the account (excludes Spam and Trash)
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **order** optional message ordering, either "asc" or "desc". Defaults to "desc" (newer first)
2017-11-22 22:22:36 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/flagged"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"results": [
{
"id": 444,
"mailbox": "59467f27535f8f0f067ba8e6",
"thread": "5971da7754cfdc7f0983bbde",
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"subject": "Subject line",
"date": "2011-11-02T19:19:08.000Z",
"intro": "Beginning text in the message…",
"attachments": false,
"seen": true,
"deleted": false,
"flagged": true,
"draft": false
}
]
2017-11-22 22:22:36 +08:00
}
```
2017-07-25 18:56:50 +08:00
### Search for messages
#### GET /user/{user}/search
Search user messages. This is a account wide search function that searches from every folder except Trash and Junk.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **query** query string to search for
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/search?query=myname"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"query": "myname",
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"results": [
{
"id": 444,
"mailbox": "59467f27535f8f0f067ba8e6",
"thread": "5971da7754cfdc7f0983bbde",
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"subject": "Subject line",
"date": "2011-11-02T19:19:08.000Z",
"intro": "Beginning text in the message…",
"attachments": false,
"seen": true,
"deleted": false,
"flagged": false,
"draft": false
}
]
2017-07-25 18:56:50 +08:00
}
```
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
### Get message details
#### GET /users/{user}/mailboxes/{mailbox}/messages/{message}
2017-10-20 18:43:44 +08:00
Returns data about a specific message.
2017-07-25 18:56:50 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **message** (required) is the ID of the message
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2/messages/444"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": 444,
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"to": [
{
"address": "testuser@example.com",
"name": "Test User"
}
],
"subject": "Subject line",
"messageId": "<FA472D2A-092E-44BC-9D38-AFACE48AB98E@example.com>",
"date": "2011-11-02T19:19:08.000Z",
"seen": true,
"deleted": false,
"flagged": false,
"draft": false,
"html": ["Notice that the HTML content is an array of HTML strings"],
"attachments": []
2017-07-25 18:56:50 +08:00
}
```
2017-10-20 18:43:44 +08:00
### Get message events
#### GET /users/{user}/mailboxes/{mailbox}/messages/{message}/events
Returns timeline information about a specific message.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **message** (required) is the ID of the message
2017-10-20 18:43:44 +08:00
**Example**
```
2017-10-20 19:51:35 +08:00
curl "http://localhost:8080/users/59cb9b0f8d78173c5fc6871c/mailboxes/59cb9b0f8d78173c5fc6871d/messages/43/events"
2017-10-20 18:43:44 +08:00
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59e9dfac7f60c84cb2c467c4",
"events": [
{
"id": "15f3991b258000f6e5.002",
"action": "STORE",
"source": "MX",
"origin": "sender.com",
"from": "andris12@example.com",
"to": ["andris2@example.com"],
"transtype": "ESMTPSA",
"time": "2017-10-20T11:36:12.481Z"
},
{
"id": "15f3991b9d7000fb8f",
"action": "FORWARD",
"from": "andris12@example.com",
"to": ["andris@kreata.ee", "andris.reinman@gmail.com"],
"time": "2017-10-20T11:36:12.523Z"
},
{
"id": "15f3991b9d7000fb8f",
"seq": "002",
"action": "REJECTED",
"src": "0.0.0.0",
"dst": "gmail-smtp-in.l.google.com",
"response":
"421-4.7.0 This message does not have authentication information or fails to pass authentication checks. To best protect our users from spam, the message has been blocked. Please visit https://",
"from": "andris12@example.com",
"to": ["andris.reinman@gmail.com"],
"time": "2017-10-20T11:36:18.446Z"
},
{
"id": "15f3991b9d7000fb8f",
"seq": "001",
"action": "ACCEPTED",
"src": "0.0.0.0",
"dst": "aspmx.l.google.com",
"response": "250 2.0.0 OK 1508499378 v89si365958lje.238 - gsmtp",
"from": "andris12@example.com",
"to": ["andris@kreata.ee"],
"time": "2017-10-20T11:36:18.934Z"
}
]
2017-10-20 18:43:44 +08:00
}
```
2017-07-25 18:56:50 +08:00
### Update message details
#### PUT /users/{user}/mailboxes/{mailbox}/messages/{message}
2017-11-23 17:51:37 +08:00
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).
2017-07-25 18:56:50 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **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.
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2/messages/444" -H 'content-type: application/json' -d '{
"seen": true
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-11-17 19:37:53 +08:00
2017-07-25 18:56:50 +08:00
### Delete a message
#### DELETE /users/{user}/mailboxes/{mailbox}/messages/{message}
Deletes a message from mailbox. This deletes the message entirely, in most cases consider the message to the Trash folder instead.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **message** (required) is the ID of the message
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/mailboxes/5971da1754cfdc7f0983b2ed/messages/444"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
### Get message source
#### GET /users/{user}/mailboxes/{mailbox}/messages/{message}/message.eml
Returns raw message source.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **message** (required) is the ID of the message
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2/messages/444/message.eml"
```
Response for a successful operation:
```
HTTP/1.1 200 OK
2018-01-02 21:04:01 +08:00
Server: WildDuck API
2017-07-25 18:56:50 +08:00
Content-Type: message/rfc822
Date: Fri, 21 Jul 2017 19:11:04 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Delivered-To: testuser@example.com
Received: .....
<rfc822 formatted message>
```
### Get message attachment
#### GET /users/{user}/mailboxes/{mailbox}/messages/{message}/attachments/{attachment}
Returns data about a specific address.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **mailbox** (required) is the ID of the mailbox
* **message** (required) is the ID of the message
* **attachment** (required) is the ID of the attachment
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/mailboxes/596c9dd31b201716e764efc2/messages/444/attachments/ATT00001"
```
Response for a successful operation:
```
HTTP/1.1 200 OK
2018-01-02 21:04:01 +08:00
Server: WildDuck API
2017-07-25 18:56:50 +08:00
Content-Type: image/png
Date: Fri, 21 Jul 2017 18:39:05 GMT
Connection: keep-alive
Transfer-Encoding: chunked
<attachment contents>
```
## Filters
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
### Create new filter
#### POST /users/{user}/filters
Creates a filter
**Parameters**
2018-04-29 03:44:38 +08:00
* **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
2017-07-25 18:56:50 +08:00
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.
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/filters" -H 'content-type: application/json' -d '{
"query_from": "abc",
"action_flag": true
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
### List existing filters
#### GET /user/{user}/filters
Lists existing messages in a mailbox
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-25 18:56:50 +08:00
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/filters"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"results": [
{
"id": "59759c440e1d676f15e76b5f",
"name": "Flag messages from abc",
"query": [["from", "(abc)"]],
"action": [["flag it"]],
"created": "2017-07-24T07:05:40.355Z"
}
]
2017-07-25 18:56:50 +08:00
}
```
### Get filter details
#### GET /users/{user}/filters/{filter}
Returns data about a specific filter.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **filter** (required) is the ID of the filter
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/filters/59759c440e1d676f15e76b5f"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "59759c440e1d676f15e76b5f",
"name": "Flag messages from abc",
"created": "2017-07-24T07:05:40.355Z",
"query_from": "abc",
"action_flag": true
2017-07-25 18:56:50 +08:00
}
```
### Update filter details
#### PUT /users/{user}/filters/{filter}
Updates the properties of a filter. To unset a specific key use an empty string as the value.
**Parameters**
2018-04-29 03:44:38 +08:00
* **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
2017-07-25 18:56:50 +08:00
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
```
curl -XPUT "http://localhost:8080/users/59467f27535f8f0f067ba8e6/filters/59759c440e1d676f15e76b5f" -H 'content-type: application/json' -d '{
"query_from": "",
"query_ha": true,
"action_spam": true
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
### Delete a filter
#### DELETE /users/{user}/filters/{filter}
Deletes a message filter.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **filter** (required) is the ID of the filter
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/59467f27535f8f0f067ba8e6/filters/59759c440e1d676f15e76b5f"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-25 18:56:50 +08:00
}
```
2017-07-30 23:07:35 +08:00
## Autoreplies
2018-01-02 21:04:01 +08:00
WildDuck supports setting up autoreply messages that are sent to senders by LMTP process.
2017-07-30 23:07:35 +08:00
### Setup Autoreply
#### PUT /users/{user}/autoreply
2017-11-15 21:59:37 +08:00
This call sets up or updates autoreply message for the user.
2017-07-30 23:07:35 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **status** is a boolean that indicates if autoreply messages should be sent (true) or not (false)
* **subject** is the subject line of autoreply message
* **text** is text body of the autoreply message
* **html** is html body of the autoreply message
* **start** is the start time of the autoreply
* **end** is the end time of the autoreply
2017-07-30 23:07:35 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-07-30 23:07:35 +08:00
2017-11-15 21:59:37 +08:00
Autoreply update calls can be done partially, eg. only updating status or subject.
2017-07-30 23:07:35 +08:00
**Example**
```
curl -XPUT "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/autoreply" -H 'content-type: application/json' -d '{
"status": true,
"subject": "Out of office",
2017-11-15 21:59:37 +08:00
"text": "I'm out of office this week",
"start": "2017-11-15T00:00:00.000Z",
"end": "2017-11-19T00:00:00.000Z",
2017-07-30 23:07:35 +08:00
}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-30 23:07:35 +08:00
}
```
### Disable Autoreply
#### DELETE /users/{user}/autoreply
You can disable autoreplies either by updating it with status:false or deleting it.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-30 23:07:35 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
2017-07-30 23:07:35 +08:00
**Example**
```
curl -XDELETE "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/autoreply"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true
2017-07-30 23:07:35 +08:00
}
```
### Check Autoreply status
#### GET /users/{user}/autoreply
Return current autoreply status
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-30 23:07:35 +08:00
**Response fields**
2018-04-29 03:44:38 +08:00
* **success** should be `true`
* **status** is a boolean that indicates if autoreply messages should be sent (true) or not (false)
* **subject** is the subject line of autoreply message
* **message** is text body of the autoreply message
2017-07-30 23:07:35 +08:00
**Example**
```
curl "http://localhost:8080/users/5971da1754cfdc7f0983b2ec/autoreply"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"status": true,
"subject": "Out of office",
"message": "I'm out of office this week"
2017-07-30 23:07:35 +08:00
}
```
2017-11-17 19:37:53 +08:00
## Archive
2017-11-23 17:51:37 +08:00
Deleted messages are moved to temporary archive from where these are purged after configured delay (defaults to 2 weeks). During that window it is possible to
list and restore archived messages. Restoring an archived message resets the UID of a message. Archived messages do not count against user quota.
2017-11-17 19:37:53 +08:00
### List archived messages
#### GET /user/{user}/archived
2017-11-23 17:51:37 +08:00
Lists archived messages for an user. This is similar to listing mailbox messages, major difference being that archived message IDs are not numeric but hex
strings
2017-11-17 19:37:53 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **order** optional message ordering, either "asc" or "desc". Defaults to "desc" (newer first)
2017-11-17 19:37:53 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/archived"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"total": 1,
"page": 1,
"previousCursor": false,
"nextCursor": false,
"specialUse": null,
"results": [
{
"id": "5a0d7baa221311cf2d8f145e",
"mailbox": "59467f27535f8f0f067ba8e6",
"thread": "5971da7754cfdc7f0983bbde",
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"subject": "Subject line",
"date": "2011-11-02T19:19:08.000Z",
"intro": "Beginning text in the message…",
"attachments": false,
"seen": true,
"deleted": false,
"flagged": false,
"draft": false
}
]
2017-11-17 19:37:53 +08:00
}
```
### Get archived message details
#### GET /users/{user}/archived/{message}
2017-11-23 17:51:37 +08:00
Returns data about a specific message. This is similar to listing mailbox message, major difference being that archived message ID is not numeric but a hex
strings
2017-11-17 19:37:53 +08:00
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **message** (required) is the ID of the message
2017-11-17 19:37:53 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/archived/5a0d7baa221311cf2d8f145e"
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"id": "5a0d7baa221311cf2d8f145e",
"from": {
"address": "sender@example.com",
"name": "Sender Name"
},
"to": [
{
"address": "testuser@example.com",
"name": "Test User"
}
],
"subject": "Subject line",
"messageId": "<FA472D2A-092E-44BC-9D38-AFACE48AB98E@example.com>",
"date": "2011-11-02T19:19:08.000Z",
"seen": true,
"deleted": false,
"flagged": false,
"draft": false,
"html": ["Notice that the HTML content is an array of HTML strings"],
"attachments": []
2017-11-17 19:37:53 +08:00
}
```
### Restore archived message
#### POST /users/{user}/archived/{message}/restore
Restores archived message
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
* **message** (required) is the ID of the message
* **mailbox** is an optional ID of the destination mailbox. By default the message is restored to the mailbox it was deleted from or to INBOX if the source
mailbox does not exist anymore
2017-11-17 19:37:53 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/archived/5a0d7baa221311cf2d8f145e/restore" -H 'content-type: application/json' -d '{}'
```
Response for a successful operation includes the mailbox ID the message was restored to and the updated UID of the message:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"mailbox": "5a05ad49484b251f07951b22",
"uid": 40
2017-11-17 19:37:53 +08:00
}
```
2017-07-25 18:56:50 +08:00
## Quota
### Recalculate user quota
#### POST /users/{user}/quota/reset
Recalculates used storage for an user. Use this when it seems that quota counters for an user do not match with reality.
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-25 18:56:50 +08:00
**Example**
```
curl -XPOST "http://localhost:8080/users/59467f27535f8f0f067ba8e6/quota/reset" -H 'content-type: application/json' -d '{}'
```
Response for a successful operation:
```json
{
2017-11-23 17:51:37 +08:00
"success": true,
"storageUsed": 128
2017-07-25 18:56:50 +08:00
}
```
Be aware though that this method is not atomic and should be done only if quota counters are way off.
## Updates
Get user related events as an Event Source stream
### Stream update events
#### GET /users/{user}/updates
Streams changes in user account as EventSource stream
**Parameters**
2018-04-29 03:44:38 +08:00
* **user** (required) is the ID of the user
2017-07-25 18:56:50 +08:00
**Example**
```
curl "http://localhost:8080/users/59467f27535f8f0f067ba8e6/updates"
```
Response stream:
```
data: {"command":"EXISTS", "message":"596e0703f0bdd512aeac3600", "mailbox":"596c9c37ef2213165daadc65",...}
id: 596e0703f0bdd512aeac3605
data: {"command":"CREATE","mailbox":"596e09853f845a14f3620b5c","name":"My Mail",...}
id: 596e09853f845a14f3620b5d
```
2017-11-23 17:51:37 +08:00
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.
2017-07-25 18:56:50 +08:00
Be aware though that this connection needs to be properly closed if you do not want to end up with memory leaks.