`appStoreId` is the [Cloudron Store](https://cloudron.io/appstore.html) Id of this application. For example,
`io.gogs.cloudronapp` is the id of Gogs app. A specific version can be specified using the '@' suffix. For
apps that are not published on the Cloudron Store, skip this field and provide a `manifest` instead. Apps
with an `appStoreId` will automatically be kept up-to-date as newer version of the app are published on the
store.
`manifest` is the [manifest](https://cloudron.io/references/manifest.html) of the app to be installed. This
is only required if `appStoreId` is not provided. Apps with a manifest won't receive automatic updates.
`location` is the subdomain on which the app is installed. This can be empty if the app was installed on the naked domain.
If another app already exists in the same location, 409 is returned.
For apps that require login, `accessRestriction` is the *restricted* list of users and groups that can access this app. If null, all of this Cloudron users can access this app.
`icon` is an application icon that is displayed in the web ui. If not provided, this is automatically downloaded
from the Cloudron Store (or uses a fallback icon).
`cert` and `key` provide the TLS certificates. If the domain name of the app does not must match with the certificate
provided, a 400 will be returned.
If `altDomain` is set, the app can be accessed from `https://<altDomain>`.
`xFrameOptions` is set to `SAMEORIGIN` unless otherwise specified. This property can hold one value of either `DENY`, `SAMEORIGIN` or `ALLOW-FROM https://example.com/`.
Read more about this [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).
location: <string>, // subdomain on which app is installed
fqdn: <string>, // the FQDN of this app
altDomain: <string> // alternate domain from which this app can be reached
accessRestriction: null || { // list of users and groups who can access this application
users: [ ],
groups: [ ]
},
lastBackupId: <string>, // last known backup of this app
manifest: <manifest>, // the application manifest
portBindings: { // mapping from application ports to public ports
},
iconUrl: <url>, // a relative url providing the icon
memoryLimit: <number> // memory constraint in bytes
}
```
`id` is an unique id for this application.
`appStoreId` is the Cloudron Store id of this application. Cloudron will use this id to look for updates to this application. This can be null if none was provided at installation time.
`manifest` is the [Cloudron Manifest](/references/manifest.html) of the app.
`installationState` is one of the values below:
*`pending_install` - The app is being installed. Use the `installationProgress` field to track the progress.
*`pending_configure` - The app is being re-configured. For example, if the app was moved to a new location or the port bindings was changed.
*`pending_uinstall` - The app is being uninstalled.
*`pending_restore` - The app is being restored from a previous backup.
*`pending_update` - The app is being updated.
*`pending_force_update` - The app is being force-updated.
*`pending_backup` - The app is being backed up.
*`error` - There was an error executing one of the above pending commands.
*`installed` - The app is installed. Use the `runState` and `health` to determine if the app is running and healthy.
`installationProgress` is a string indicating the progress when the app's `installationState` is one of the `pending_*` states. It is
of the format `<percent>, <message>`.
`runState` is one of the values below:
*`pending_start` - The app is being started.
*`pending_stop` - The app is being stopped.
*`stopped` - The app was stopped.
*`running` - The app is running.
`health` is one of the values below:
*`healthy` - The app is responding to health checks and is healthy.
*`unhealthy` - The app is not responding to health checks.
*`error` - There was an error checking the health of the app.
*`dead` - The app is dead. Most likely it was stopped or being uninstalled.
`location` is the subdomain on which the app is installed. This can be empty if the app was installed on the naked domain. The app can be
accessed from `fqdn` i.e `https//<fqdn>`. If `altDomain` is set, the app should be accessed from `https://<altDomain>`.
For apps that require login, `accessRestriction` is the *restricted* list of users and groups that can access this app. If null, all of this Cloudron users can access this app.
`lastBackupId` is the last valid backup id. The [restore API](/references/api.html#restore-app) can be used to restore the app to this backup.
`manifest` is the [application manifest](/references/manifest.html).
### List apps
GET `/api/v1/apps/:appId` <scope>admin</scope>
Gets the list of installed apps.
Response (200):
```
{
apps: [
{
id: <string>, // a unique id for the app
appStoreId: <string>, // Cloudron Store Id for updates
manifest: <manifest>, // current manifest of the app
monotonicTimestamp: <number>, // time passed since boot
message: [ <byte>,... ], // utf8 buffer
source: <process name> // source of this message
}
```
Logs are aggregated from one or more `source`s. The application logs have the `source` set to `main`.
Other sources include `scheduler`.
### Get log stream
GET `/api/v1/apps/:appId/logstream` <scope>admin</scope>
Stream the logs of an application with id `appId` as a `text/event-stream`. See the [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
interface documentation for details.
The `lines` query parameter can be used to specify the number of log lines to prefetch.
box: <semver>, // Set to the next available Cloudron version
apps: {
<appid>: <semver>. // Set to next available app version
...
}
},
progress: { // See progress API
},
isCustomDomain: <boolean>, // false if the cloudron is on a .cloudron.me subdomain. true otherwise
developerMode: <boolean>,
region: <string>, // the geo-region of this Cloudron
size: <string>, // the size of this Cloudron
billing: <boolean>, // true if the user has setup billing
memory: <string>, // the physical memory
provider: <string>,
cloudronName: <string> // the name of this cloudron
}
```
## Eventlog
### List events
GET `/api/v1/eventlog` <scope>admin</scope>
Lists all the past events.
The `action` query parameter can be used to list events of a specific action.
The `search` query parameter can be used to do a wildcard ('*search*') on the data field.
This API supports [pagination](/references/api.html#pagination) - use the `page` and `per_page` query parameters to get specific pages.
Response (200):
```
{
eventlogs: [
{
id: <string>, // unique id for the event
action: <enum>, // see below
source: <object>, // originator of this event
data: <object>, // value depends on action. see below
creationTime: <date> // ISO-8601 date in UTC
},
....
]
}
```
`action` is one of the values below:
* cloudron.activate
* app.configure
* app.install
* app.restore
* app.uninstall
* app.update
* backup.finish
* backup.start
* certificate.renew
* settings.climode
* cloudron.start
* cloudron.update
* user.add
* user.login
* user.remove
* user.update
`source` contains information on the originator of the action. For example, for user.login, this contains the IP address, the appId and the authType (ldap or simpleauth or oauth).
`data` contains information on the event itself. For example, for user.login, this contains the userId that logged in. For app.install, it contains the manifest and location of the app that was installed.
To list all the app installation events:
```
curl -X GET -H 'Authorization: Bearer cb0463455a6606482be7956fc3abd53330ae23244e3492cda3914a2c5154c47e' https://my-demo.cloudron.me/api/v1/eventlog?action=app.install
```
## Groups
Cloudron groups are a mechanism to restrict application access to a subset of users. You can add one or more users
to a group and assign one or more groups to an application. Only users that are members of any of the groups can access the application.
Group membership is dynamic. Users instantly lose or gain access to an application based on their group
membership.
### Create group
POST `/api/v1/groups` <scope>admin</scope>
Creates a new group.
Request:
```
{
name: <string>
}
```
`name` must be atleast 2 characters. The special built-in group named `admin` has all the
Cloudron administrators.
Response (200):
```
{
id: <string>,
name: <string>
}
```
### Get group
GET `/api/v1/groups/:groupId` <scope>admin</scope>
Gets an existing group with id `groupId`.
Response (200):
```
{
id: <string>,
name: <string>,
userIds: [ <string>, ... ] // list of users that are part of this group
}
```
### List groups
GET `/api/v1/groups` <scope>admin</scope>
Lists all groups.
Response (200):
```
{
groups: [
{
id: <string>,
name: <string>,
userIds: [ <string>, ... ] // list of users that are part of this group
Mailboxes allow users to receive mail using `IMAP`. Every user gets a mailbox with the same name as the username.
Users can receive email using IMAP (TLS) at `my.customdomain.com` and send mail using SMTP (STARTTLS) at
`my.customdomain.com`.
Apps can also receive email using the [recvmail addon](/references/addons.html#recvmail). App mailboxes are
named as `<subdomain>.app`. For this reason, the `.app` suffix is reserved for apps.
### Create mailbox
POST `/api/v1/mailboxes` <scope>admin</scope>
Creates a new mailbox.
`name` specifies the address at which email can be received and does not include the domain name. `name` can contain
only alphanumeric characters and a dot ('.') and must be lower case. The Cloudron mail server support '+' based subaddressing (i.e)name+tag@domain.com will be delivered to this mailbox.
mailboxes can only be accessed by users with the same username as the mailbox. A mailbox is automatically created
for every user on the Cloudron.
Request:
```
{
name: <string>
}
```
`name` must be atleast 2 characters and must be alphanumeric.
Response (200):
```
{
id: <string>,
name: <string>
}
```
### Get mailbox
GET `/api/v1/mailboxes/:mailboxName` <scope>admin</scope>
Gets an existing mailbox with name `mailboxName`.
Response (200):
```
{
id: <string>,
name: <string>,
aliases: [ <string>, ...]
}
```
### List mailboxes
GET `/api/v1/mailboxes` <scope>admin</scope>
Lists all mailboxes.
Response (200):
```
{
mailboxes: [
{
id: <string>,
name: <string>
},
...
]
}
```
### Set mailbox aliases
PUT `/api/v1/mailboxes/:mailboxName/aliases` <scope>admin</scope>
Sets aliases of an existing mailbox.
An alias is an alternate email address for a mailbox. Mails received at the alternate address are stored
in the mailbox. The email's `to` header should indicate the address that the original sent it to.
This also allows users to send emails with `From` address set to an alias.
Note that this call will replace the current aliases for this mailbox, it does **not** merge the provided ones with the current aliases.
Aliases have to be unique and cannot conflict with existing aliases or mailbox names. Any conflict with result in a 409.
Request:
```
{
aliases: [ <string>, ... ]
}
```
### Get mailbox aliases
GET `/api/v1/mailboxes/:mailboxName/aliases` <scope>admin</scope>
Gets the profile information of the token owner. This is useful to verify access tokens.
Response (200):
```
{
id: <string>,
username: <string>,
email: <email>,
admin: <boolean>,
displayName: <string>
}
```
### Update profile
POST `/api/v1/profile` <scope>profile</scope>
Updates the email or displayName of the token owner.
Request:
```
{
email: <email>, // optional
displayName: <string> // optional
}
```
Response (204):
```
{}
```
### Update password
POST `/api/v1/profile/password` <scope>profile</scope>
Updates the password of the token owner.
Request:
```
{
password: <string>, // current password. only required for OAuth tokens
newPassword: <string>
}
```
Response (204):
```
{}
```
### Tutorial
POST `/api/v1/profile/tutorial` <scope>profile</scope>
Toggles display of the tutorial when the token owner logs in.
Request:
```
{
showTutorial: <boolean>
}
```
Response (204):
```
{}
```
## Settings
### Get auto update pattern
GET `/api/v1/settings/autoupdate_pattern` <scope>admin</scope>
Gets the auto update pattern that the Cloudron uses to automatically update itself and installed apps.
Patterns are matched based on the Cloudron's [timezone](references/api.html#get-timezone).
Response (200):
```
{
pattern: <string> // a cron pattern
}
```
### Set auto update pattern
POST `/api/v1/settings/autoupdate_pattern` <scope>admin</scope>
Sets the auto update pattern that the Cloudron uses to automatically update itself and installed apps.
Request:
```
{
pattern: <string> // a cron pattern
}
```
`pattern` has the format listed in the [node-cron](https://github.com/ncb000gt/node-cron#cron-ranges) page.
Note that unlike classic crontab format, the pattern contains seconds as the first part.
Setting pattern to `never` disables auto update.
Some examples of patterns are:
*`00 00 1,3,5,23 * * *` would run updates at 1am, 3am, 5am, 11pm every night.
*`0 030 4 1,15 * 5` would run updates at 4:30 am on the 1st and 15th of each month, plus every Friday.
Patterns are matched based on the Cloudron's [timezone](references/api.html#get-timezone).
### Get avatar
GET `/api/v1/settings/cloudron_avatar` <scope>admin</scope>
Gets the Cloudron avatar image as `Content-Type: image/png`.
Note that the avatar is also available without authentication using the [Get avatar](/references/api.html#get-avatar) API.
Response (200):
```
Content-Type: image/png
```
### Set avatar
POST `/api/v1/settings/cloudron_avatar` <scope>admin</scope>
Sets the avatar of the Cloudron.
The request is sent as `multipart/form-data`. It must contain a field named `avatar` and must be a `png`.
Example:
```
curl -X POST -F "avatar=@./avatar.png" -H 'Authorization: Bearer 215841b5943f5432a26ef3a1526f548a40268a92ed9baca5db980be0545da596' https://my-demo.cloudron.me/api/v1/settings/cloudron_avatar
```
### Get Backup Configuration
GET `/api/v1/settings/backup_config` <scope>admin</scope> <scope>internal</scope>
Gets the credentials used to upload backups.
This is currently internal API and is documented here for completeness.
Response(200):
```
{
"provider": <string>, // 'caas'
"key": <string>, // encryption key
"region": <string>, // s3 region
"bucket": <string>, // s3 bucket name
"prefix": <string>, // s3 bucket prefix
"token": <string> // caas specific token
}
```
### Set Backup Configuration
POST `/api/v1/settings/backup_config` <scope>admin</scope> <scope>internal</scope>
Sets the credentials used to upload backups.
This is currently internal API and is documented here for completeness.
### Get DNS Configuration
GET `/api/v1/settings/dns_config` <scope>admin</scope> <scope>internal</scope>
Gets the credentials used to configure DNS.
This is currently internal API and is documented here for completeness.
Response(200):
```
{
"provider": <string>, // 'caas'
"token": <string> // caas specific token
}
```
### Set DNS Configuration
POST `/api/v1/settings/dns_config` <scope>admin</scope> <scope>internal</scope>
Sets the credentials used to configure DNS.
This is currently internal API and is documented here for completeness.
### Set fallback Certificate
POST `/api/v1/settings/certificate` <scope>admin</scope> <scope>internal</scope>
Sets the fallback TLS certificate to use if automatic certificate generation or renewal fails.
The fallback certificate only applies to Cloudrons running on a custom domain.
The Cloudron automatically installs and renews certificates for all subdomains using Let's Encrypt.
The fallback certificate is used if Let's Encrypt fails.
Request:
```
{
cert: <pem encoded string>, // TLS certificate including the full chain
key: <pem encoded string> // TLS key
}
```
### Set `my` subdomain certification
POST `/api/v1/settings/admin_certificate` <scope>admin</scope> <scope>internal</scope>
Sets the certificate to use for the `my` subdomain.
The `my` subdomain certificate only applies to Cloudrons running on a custom domain.
Request:
```
{
cert: <pem encoded string>, // TLS certificate including the full chain
key: <pem encoded string> // TLS key
}
```
### Get name
GET `/api/v1/settings/cloudron_name` <scope>admin</scope>
Gets the name of the Cloudron.
Note that the name is also available without authentication using the [Get status](/references/api.html#get-status) API.
```
Response (200):
{
name: <string>
}
```
### Set name
POST `/api/v1/settings/cloudron_name` <scope>admin</scope>
Sets the name of the Cloudron.
The Cloudron name is shown in the title bar and all the login screens. It has a maximum length of 32 characters.
Request:
```
{
name: <string>
}
```
### Get timezone
GET `/api/v1/settings/time_zone` <scope>admin</scope>
Gets the timezone of the Cloudron.
Timezone is automatically set based on the IP address from where the Cloudron was activated. This timezone is used with the [auto update pattern](/references/api.html#get-auto-update-pattern) to trigger updates at the
correct time.
```
Response (200):
{
timeZone: <string> // the timezone
}
```
### Set timezone
POST `/api/v1/settings/time_zone` <scope>admin</scope>
Sets the time zone of the Cloudron.
Timezone is automatically set based on the IP address from where the Cloudron was activated. This timezone is used with the [auto update pattern](/references/api.html#get-auto-update-pattern) to trigger updates at the
correct time.
See the [Tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for a list of valid values.
Request:
```
{
timeZone: <string>
}
```
## Users
### Create user
POST `/api/v1/users` <scope>admin</scope>
Creates a new user.
Request:
```
{
email: <email>, // required
invite: <boolean>, // required
username: <string>, // optional
displayName: <string> // optional
}
```
`invite` indicates if the user should be sent an invitation email. The invitation email allows the user
to setup a username and password. Set this to `false` to send out a custom invitation email of your own
to the user. The invitation link can be constructed based on the `resetToken` in the response.
`username` has to be at least two characters long and must be alphanumeric. If unspecified, the new user
can pick any available name on first sign up. For security, `username` cannot be changed once set.
Some apps (incorrectly) use the `username` as their unique identifier. As a result, it might mistake a newly created user as a previous user with the same username. If you want to reset the username, delete the existing
the user and create a new one again.
`displayName` may consist of one or more words to specify the first name and surname.
Response (201):
```
{
id: <string>,
username: <string>,
displayName: <string>,
email: <email>,
groupIds: [ <string>, ... ]
resetToken: <string> // User can sign up at https://my-demo.cloudron.me/api/v1/session/account/setup.html?reset_token=<resetToken>
}
```
### Get user
GET `/api/v1/users/:userId` <scope>admin</scope>
Gets detailed information about a specific user with id `userId`.
Response (200):
```
{
id: <string>,
username: <string>,
email: <email>,
groupIds: [ <string>, ... ], // list of groups this user is part of
admin: <boolean>, // a boolean indicating if this user is an admin
displayName: <string>
}
```
### List users
GET `/api/v1/users` <scope>admin</scope>
Lists all users.
Response (200):
```
{
users: [
{
id: <string>,
username: <string>,
email: <email>,
displayName: <string>,
groupIds: [ <string>, ... ], // list of groups this user is part of
admin: <boolean> // a boolean indicating if this user is an admin
},
...
]
}
```
### Update user
POST `/api/v1/users/:userId` <scope>admin</scope>
Modify user's email or display name. As noted in [Create user](/references/api.html#create-user), username
cannot be changed.
Request:
```
{
email: <email>, // optional
displayName: <displayName> // optional
}
```
Response (204):
```
{}
```
### Re-invite user
POST `/api/v1/users/:userId/invite` <scope>admin</scope>
Resends the invitation link to an existing user.
A re-invite call invalidates any previous invite links. The invitation link can be constructed based on the resetToken in the response.
Request:
```
{}
```
Response (200):
```
{
resetToken: <string> // // User can sign up at https://my-demo.cloudron.me/api/v1/session/account/setup.html?reset_token=<resetToken>
}
```
### Set groups
PUT `/api/v1/users/:userId/groups` <scope>admin</scope>
Sets the groups for the user with id `userId`.
Groups are identified by groupIds which can be retrieved using the