@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api DRACOON API
@base /api
@version 5.49.0
@auth OAuth2
@endpoints 314
@hint download_for_search
@toc public(19), downloads(4), users(15), user(43), uploads(3), system(47), shares(18), settings(16), provisioning(17), nodes(71), groups(11), config(14), auth(4), roles(7), datev(19), resources(2), eventlog(4)

@group public
@endpoint GET /v4/public/shares/downloads/{access_key}/{token}
@desc Download file with token
@required {access_key: str # Access key, token: str # Download token}
@optional {Range: str # Range   e.g. `bytes=0-999`, generic_mimetype: bool # Always return `application/octet-stream` instead of specific mimetype, inline: bool # Use Content-Disposition: `inline` instead of `attachment`}
@returns(200) OK
@returns(206) Partial Content
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 416: Range Not Satisfiable}

@endpoint HEAD /v4/public/shares/downloads/{access_key}/{token}
@desc Download file with token
@required {access_key: str # Access key, token: str # Download token}
@optional {Range: str # Range   e.g. `bytes=0-999`, generic_mimetype: bool # Always return `application/octet-stream` instead of specific mimetype, inline: bool # Use Content-Disposition: `inline` instead of `attachment`}
@returns(200) OK
@returns(206) Partial Content
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 416: Range Not Satisfiable}

@endgroup

@group downloads
@endpoint GET /v4/downloads/{token}
@desc Download file
@required {token: str # Download token}
@optional {Range: str # Range   e.g. `bytes=0-999`, generic_mimetype: bool # Always return `application/octet-stream` instead of specific mimetype, inline: bool # Use Content-Disposition: `inline` instead of `attachment`}
@returns(200) OK
@returns(206) Partial Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 416: Range Not Satisfiable}

@endpoint HEAD /v4/downloads/{token}
@desc Download file
@required {token: str # Download token}
@optional {Range: str # Range   e.g. `bytes=0-999`, generic_mimetype: bool # Always return `application/octet-stream` instead of specific mimetype, inline: bool # Use Content-Disposition: `inline` instead of `attachment`}
@returns(200) OK
@returns(206) Partial Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 416: Range Not Satisfiable}

@endgroup

@group users
@endpoint GET /v4/users/{user_id}
@desc Request user
@required {user_id: int(int64) # User ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), effective_roles: bool # Filter users with DIRECT or DIRECT **AND** EFFECTIVE roles.  * `false`: DIRECT roles  * `true`: DIRECT **AND** EFFECTIVE roles  DIRECT means: e.g. user gets role **directly** granted from someone with _grant permission_ right.  EFFECTIVE means: e.g. user gets role through **group membership**.}
@returns(200) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, avatarUuid: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, email: str, phone: str, expireAt: str(date-time), hasManageableRooms: bool, isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), homeRoomId: int(int64), publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}, userRoles: map{items: [map]}, isMfaEnabled: bool, isMfaEnforced: bool, userAttributes: map{items: [map]}, title: str, lockStatus: int(int32), login: str, authMethods: [map], gender: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/users/{user_id}
@desc Update user's metadata
@required {user_id: int(int64) # User ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), firstName: str # User first name, lastName: str # User last name, userName: str # Username, email: str # Email, isLocked: bool=false # User is locked:  * `false` - unlocked  * `true` - locked    User is locked and can not login anymore., phone: str # Phone number, receiverLanguage: str # IETF language tag, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, authData: map{method: str, login: str, adConfigId: int(int32), oidConfigId: int(int32)} # User Authentication Data Update Request, mfaConfig: map{mfaEnforced: bool} # Multi-factor authentication configuration, title: str # Job title, lockStatus: int(int32) # User lock status:  * `0` - locked  * `1` - Web access allowed  * `2` - Web and mobile access allowed    Please use `isLocked` instead., gender: str=n # Gender  Do NOT use `gender`! It will be ignored., authMethods: [map{authId!: str, isEnabled!: bool, options: [map]}] # Authentication methods:  * `sql`  * `active_directory`  * `openid`  use `authData` instead}
@returns(200) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, avatarUuid: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, email: str, phone: str, expireAt: str(date-time), hasManageableRooms: bool, isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), homeRoomId: int(int64), publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}, userRoles: map{items: [map]}, isMfaEnabled: bool, isMfaEnforced: bool, userAttributes: map{items: [map]}, title: str, lockStatus: int(int32), login: str, authMethods: [map], gender: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/users/{user_id}
@desc Remove user
@required {user_id: int(int64) # User ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/users/{user_id}/userAttributes
@desc Request custom user attributes
@required {user_id: int(int64) # User ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/users/{user_id}/userAttributes
@desc Add or edit custom user attributes
@required {user_id: int(int64) # User ID, items: [map{key!: str, value!: str}] # List of key-value pairs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/users/{user_id}/userAttributes
@desc Set custom user attributes
@required {user_id: int(int64) # User ID, items: [map{key!: str, value!: str}] # List of key-value pairs}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(201) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, avatarUuid: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, email: str, phone: str, expireAt: str(date-time), hasManageableRooms: bool, isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), homeRoomId: int(int64), publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}, userRoles: map{items: [map]}, isMfaEnabled: bool, isMfaEnforced: bool, userAttributes: map{items: [map]}, title: str, lockStatus: int(int32), login: str, authMethods: [map], gender: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group user
@endpoint GET /v4/user/subscriptions/upload_shares
@desc List Upload Share subscriptions
@optional {filter: str # Filter string, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., offset: int(int32) # Range offset, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/subscriptions/upload_shares
@desc Subscribe or Unsubscribe a List of Upload Shares for notifications
@required {isSubscribed: bool # Creates or deletes a subscription on each item in an array of objects., objectIds: [int(int64)] # List of ids}
@returns(201) Created
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/subscriptions/nodes
@desc List node subscriptions
@optional {filter: str # Filter string, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., offset: int(int32) # Range offset, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/subscriptions/nodes
@desc Subscribe or Unsubscribe a List of nodes for notifications
@required {isSubscribed: bool # Creates or deletes a subscription on each item in an array of objects., objectIds: [int(int64)] # List of ids}
@returns(201) Created
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/subscriptions/download_shares
@desc List Download Share subscriptions
@optional {filter: str # Filter string, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., offset: int(int32) # Range offset, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/subscriptions/download_shares
@desc Subscribe or Unsubscribe a List of Download Shares for notifications
@required {isSubscribed: bool # Creates or deletes a subscription on each item in an array of objects., objectIds: [int(int64)] # List of ids}
@returns(201) Created
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/profileAttributes
@desc Request user profile attributes
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/profileAttributes
@desc Add or edit user profile attributes
@required {items: [map{key!: str, value!: str}] # List of key-value pairs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/profileAttributes
@desc Set user profile attributes
@required {items: [map{key!: str, value!: str}] # List of key-value pairs}
@returns(201) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # Created
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/notifications/config/{id}
@desc Update notification configuration
@required {id: int(int64) # Unique identifier for a notification configuration, channelIds: [int(int32)] # List of notification channel IDs.  Leave empty to disable notifications.}
@returns(200) {id: int(int64), scopeId: int(int32), eventTypeName: str, channelIds: [int(int32)]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account
@desc Request user account information
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), more_info: bool # Get more info for this user  e.g. list of user groups}
@returns(200) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, hasManageableRooms: bool, userRoles: map{items: [map]}, language: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, mustSetEmail: bool, needsToAcceptEULA: bool, expireAt: str(date-time), isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), lastLoginFailAt: str(date-time), email: str, phone: str, homeRoomId: int(int64), createdAt: str(date-time), automaticallySubscribeDatarooms: bool, userGroups: [map], userAttributes: map{items: [map]}, title: str, lastLoginSuccessIp: str, lastLoginFailIp: str, gender: str, needsToChangeUserName: bool, authMethods: [map], login: str, lockStatus: int(int32), needsToChangePassword: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint PUT /v4/user/account
@desc Update user account
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), userName: str # Username, acceptEULA: bool # Accept EULA  Present, if EULA is system global active.  cf. `GET system/config/settings/general` - `eulaEnabled`  If accepted can not be undone., firstName: str # User first name, lastName: str # User last name, email: str # Email, phone: str # Phone number, language: str # IETF language tag, automaticallySubscribeDatarooms: bool # Automatically subscribe datarooms when getting permissions, title: str # Job title, login: str # User login name, gender: str=n # Gender  Do NOT use `gender`! It will be ignored.}
@returns(200) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, hasManageableRooms: bool, userRoles: map{items: [map]}, language: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, mustSetEmail: bool, needsToAcceptEULA: bool, expireAt: str(date-time), isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), lastLoginFailAt: str(date-time), email: str, phone: str, homeRoomId: int(int64), createdAt: str(date-time), automaticallySubscribeDatarooms: bool, userGroups: [map], userAttributes: map{items: [map]}, title: str, lastLoginSuccessIp: str, lastLoginFailIp: str, gender: str, needsToChangeUserName: bool, authMethods: [map], login: str, lockStatus: int(int32), needsToChangePassword: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint PUT /v4/user/account/password
@desc Change user's password
@required {oldPassword: str # Old password, newPassword: str # New password}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/user/account/customer
@desc Request customer information for user
@returns(200) {id: int(int64), name: str, isProviderCustomer: bool, spaceLimit: int(int64), spaceUsed: int(int64), accountsLimit: int(int32), accountsUsed: int(int32), cntInternalUser: int(int32), cntGuestUser: int(int32), customerEncryptionEnabled: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/user/account/customer
@desc Activate client-side encryption for customer
@required {enableCustomerEncryption: bool # Set `true` to enable encryption for this customer, dataSpaceRescueKey: map{privateKeyContainer!: map, publicKeyContainer!: map} # Key pair container}
@returns(200) {id: int(int64), name: str, isProviderCustomer: bool, spaceLimit: int(int64), spaceUsed: int(int64), accountsLimit: int(int32), accountsUsed: int(int32), cntInternalUser: int(int32), cntGuestUser: int(int32), customerEncryptionEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group uploads
@endpoint PUT /v4/uploads/{token}
@desc Complete file upload
@required {token: str # Upload token}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., fileName: str # New file name to store with, fileKey: map{key!: str, iv!: str, version!: str, tag!: str} # File key information, userFileKeyList: map{items: [map]} # Mandatory for encrypted shares}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@returns(202) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Accepted
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 507: Insufficient Storage}

@endpoint POST /v4/uploads/{token}
@desc Upload file
@required {token: str # Upload token}
@optional {Content-Range: str # Content-Range   e.g. `bytes 0-999/3980`}
@returns(200) {size: int(int64), hash: str} # OK
@returns(201) {size: int(int64), hash: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 507: Insufficient Storage}

@endpoint DELETE /v4/uploads/{token}
@desc Cancel file upload
@required {token: str # Upload token}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 507: Insufficient Storage}

@endgroup

@group system
@endpoint GET /v4/system/config/storage/s3
@desc Request S3 storage configuration
@returns(200) {bucketUrl: str, accessKeyDefined: bool, secretKeyDefined: bool, region: str} # OK
@errors {401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/storage/s3
@desc Update S3 storage configuration
@optional {bucketUrl: str # S3 object storage bucket URL, accessKey: str # Access Key ID, secretKey: str # Secret Access Key, region: str # S3 region}
@returns(200) {bucketUrl: str, accessKeyDefined: bool, secretKeyDefined: bool, region: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/system/config/storage/s3
@desc Create S3 storage configuration
@required {accessKey: str # Access Key ID, secretKey: str # Secret Access Key}
@optional {bucketUrl: str # S3 object storage bucket URL, region: str # S3 region}
@returns(201) {bucketUrl: str, accessKeyDefined: bool, secretKeyDefined: bool, region: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/syslog
@desc Request syslog settings
@returns(200) {enabled: bool, host: str, port: int(int32), protocol: str, logIpEnabled: bool} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/settings/syslog
@desc Update syslog settings
@optional {enabled: bool # Is syslog enabled?, host: str # Syslog server (IP or FQDN), port: int(int32) # Syslog server port, protocol: str(TCP/UDP) # Protocol to connect to syslog server, logIpEnabled: bool # Determines whether user’s IP address is logged.}
@returns(200) {enabled: bool, host: str, port: int(int32), protocol: str, logIpEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/general
@desc Request general settings
@returns(200) {sharePasswordSmsEnabled: bool, cryptoEnabled: bool, emailNotificationButtonEnabled: bool, eulaEnabled: bool, useS3Storage: bool, s3TagsEnabled: bool, hideLoginInputFields: bool, authTokenRestrictions: map{restrictionEnabled: bool, accessTokenValidity: int(int32), refreshTokenValidity: int(int32)}, mediaServerEnabled: bool, weakPasswordEnabled: bool} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/settings/general
@desc Update general settings
@optional {sharePasswordSmsEnabled: bool # Allow sending of share passwords via SMS, cryptoEnabled: bool # Activation status of client-side encryption.  Can only be enabled once; disabling is not possible., emailNotificationButtonEnabled: bool # Enable email notification button, eulaEnabled: bool # Each user has to confirm the EULA at first login., s3TagsEnabled: bool # Defines if S3 tags are enabled, authTokenRestrictions: map{overwriteEnabled!: bool, accessTokenValidity: int(int32), refreshTokenValidity: int(int32)} # Request model for updating auth token settings, hideLoginInputFields: bool # Defines if login fields should be hidden, mediaServerEnabled: bool # Determines if the media server is enabled, weakPasswordEnabled: bool # Allow weak password  * A weak password has to fulfill the following criteria:     * is at least 8 characters long     * contains letters and numbers  * A strong password has to fulfill the following criteria in addition:     * contains at least one special character     * contains upper and lower case characters  Please use `PUT /system/config/policies/passwords` API to change configured password policies.}
@returns(200) {sharePasswordSmsEnabled: bool, cryptoEnabled: bool, emailNotificationButtonEnabled: bool, eulaEnabled: bool, useS3Storage: bool, s3TagsEnabled: bool, hideLoginInputFields: bool, authTokenRestrictions: map{restrictionEnabled: bool, accessTokenValidity: int(int32), refreshTokenValidity: int(int32)}, mediaServerEnabled: bool, weakPasswordEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/eventlog
@desc Request eventlog settings
@returns(200) {enabled: bool, retentionPeriod: int(int32), logIpEnabled: bool} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/settings/eventlog
@desc Update eventlog settings
@optional {enabled: bool # Is eventlog enabled?, retentionPeriod: int(int32) # Retention period (in days) of event log entries.  After that period, all entries are deleted.  Recommended value: 7, logIpEnabled: bool # Determines whether user’s IP address is logged.}
@returns(200) {enabled: bool, retentionPeriod: int(int32), logIpEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/defaults
@desc Request system defaults
@returns(200) {languageDefault: str, downloadShareDefaultExpirationPeriod: int(int32), uploadShareDefaultExpirationPeriod: int(int32), fileDefaultExpirationPeriod: int(int32), globalRecycleBinRetentionPeriod: int(int32), globalRecycleBinRetentionPeriodLegacy: int(int32), nonmemberViewerDefault: bool, hideLoginInputFields: bool} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/settings/defaults
@desc Update system defaults
@optional {languageDefault: str # Define which language should be default., downloadShareDefaultExpirationPeriod: int(int32) # Default expiration period for Download Shares in days., uploadShareDefaultExpirationPeriod: int(int32) # Default expiration period for Upload Shares in days., fileDefaultExpirationPeriod: int(int32) # Default expiration period for all uploaded files in days., globalRecycleBinRetentionPeriod: int(int32) # Global recycle bin retention period in days., nonmemberViewerDefault: bool # Defines if new users get the role Non Member Viewer by default}
@returns(200) {languageDefault: str, downloadShareDefaultExpirationPeriod: int(int32), uploadShareDefaultExpirationPeriod: int(int32), fileDefaultExpirationPeriod: int(int32), globalRecycleBinRetentionPeriod: int(int32), globalRecycleBinRetentionPeriodLegacy: int(int32), nonmemberViewerDefault: bool, hideLoginInputFields: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/auth
@desc Request authentication settings
@returns(200) {authMethods: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/settings/auth
@desc Update authentication settings
@required {authMethods: [map{name!: str, isEnabled!: bool, priority!: int(int32)}] # List of authentication methods}
@returns(200) {authMethods: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/virus_protection
@desc Request virus protection policies
@returns(200) {isVirusProtectionEnabled: bool} # OK
@errors {401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/virus_protection
@desc Change virus protection policies
@optional {isVirusProtectionEnabled: bool # Determines whether virus protection is enabled for room. To be set by room admins}
@returns(200) {isVirusProtectionEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/passwords
@desc Request password policies
@returns(200) {loginPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map{enabled: bool, maxPasswordAge: int(int32)}, userLockout: map{enabled: bool, maxNumberOfLoginFailures: int(int32), lockoutPeriod: int(int32)}, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, sharesPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, encryptionPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/passwords
@desc Change password policies
@optional {loginPasswordPolicies: map{characterRules: map, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map, userLockout: map} # Request model for updating login password policies, sharesPasswordPolicies: map{characterRules: map, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool} # Request model for updating shares password policies, encryptionPasswordPolicies: map{characterRules: map, minLength: int(int32), rejectUserInfo: bool, rejectKeyboardPatterns: bool} # Request model for updating encryption password policies}
@returns(200) {loginPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map{enabled: bool, maxPasswordAge: int(int32)}, userLockout: map{enabled: bool, maxNumberOfLoginFailures: int(int32), lockoutPeriod: int(int32)}, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, sharesPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, encryptionPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/mfa
@desc Request MFA policies
@returns(200) {isMfaEnforced: bool, enforcedUserTypes: [str]} # OK
@errors {401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/mfa
@desc Change MFA policies
@required {isMfaEnforced: bool # Determines whether multi-factor authentication is enforced}
@returns(200) {isMfaEnforced: bool, enforcedUserTypes: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/mfa/{user_type}
@desc Change MFA policies for internal/external users
@required {user_type: str(guest/internal) # User type, isMfaEnforced: bool # Determines whether multi-factor authentication is enforced}
@returns(200) {isMfaEnforced: bool, enforcedUserTypes: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/guest_users
@desc Request guest user policies
@returns(200) {isInviteUsersEnabled: bool} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/guest_users
@desc Change guest user policies
@required {isInviteUsersEnabled: bool # Determines whether the invite of users to rooms is enabled.}
@returns(200) {isInviteUsersEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/classifications
@desc Request classification policies
@returns(200) {shareClassificationPolicies: map{classificationRequiresSharePassword: int(int32)}} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/policies/classifications
@desc Change classification policies
@optional {shareClassificationPolicies: map{classificationRequiresSharePassword: int(int32)} # Shares classification policies}
@returns(200) {shareClassificationPolicies: map{classificationRequiresSharePassword: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/oauth/clients/{client_id}
@desc Request OAuth client
@required {client_id: str # OAuth client ID}
@returns(200) {clientId: str, clientSecret: str, clientName: str, clientType: str, isStandard: bool, isExternal: bool, isEnabled: bool, grantTypes: [str], redirectUris: [str], accessTokenValidity: int(int32), refreshTokenValidity: int(int32), approvalValidity: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/oauth/clients/{client_id}
@desc Update OAuth client
@required {client_id: str # OAuth client ID, grantTypes: [str](authorization_code/client_credentials/implicit/password/refresh_token) # Authorized grant types  * `authorization_code`  * `implicit`  * `password`  * `client_credentials`  * `refresh_token`    cf. [RFC 6749](https://tools.ietf.org/html/rfc6749)}
@optional {clientSecret: str # Secret, which client uses at authentication., clientName: str # Name, which is shown at the client configuration and authorization., clientType: str(confidential/public) # Determines whether client is a confidential or public client., isEnabled: bool # Determines whether client is enabled., redirectUris: [str] # URIs, to which a user is redirected after authorization., accessTokenValidity: int(int32) # Validity of the access token in seconds., refreshTokenValidity: int(int32) # Validity of the refresh token in seconds., approvalValidity: int(int32) # Validity of the approval interval in seconds.}
@returns(200) {clientId: str, clientSecret: str, clientName: str, clientType: str, isStandard: bool, isExternal: bool, isEnabled: bool, grantTypes: [str], redirectUris: [str], accessTokenValidity: int(int32), refreshTokenValidity: int(int32), approvalValidity: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/system/config/oauth/clients/{client_id}
@desc Remove OAuth client
@required {client_id: str # OAuth client ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/auth/openid/idps/{idp_id}
@desc Request OpenID Connect IDP configuration
@required {idp_id: int(int32) # OpenID Connect IDP configuration ID}
@returns(200) {id: int(int32), name: str, isStandard: bool, isEnabled: bool, issuer: str, authorizationEndPointUrl: str, tokenEndPointUrl: str, userInfoEndPointUrl: str, jwksEndPointUrl: str, clientId: str, clientSecret: str, flow: str, scopes: [str], redirectUris: [str], pkceEnabled: bool, pkceChallengeMethod: str, mappingClaim: str, fallbackMappingClaim: str, userInfoSource: str, userImportEnabled: bool, userImportGroup: int(int64), userUpdateEnabled: bool, userManagementUrl: str, useAuthProxyEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/auth/openid/idps/{idp_id}
@desc Update OpenID Connect IDP configuration
@required {idp_id: int(int32) # OpenID Connect IDP configuration ID}
@optional {name: str # Name of the IDP, isEnabled: bool # Determines whether client is enabled., issuer: str # Issuer identifier of the IDP  The value is a case sensitive URL., authorizationEndPointUrl: str # URL of the authorization endpoint, tokenEndPointUrl: str # URL of the token endpoint, userInfoEndPointUrl: str # URL of the user info endpoint, jwksEndPointUrl: str # URL of the JWKS endpoint, clientId: str # ID of the OpenID client, clientSecret: str # Secret, which client uses at authentication., flow: str(authorization_code/hybrid) # Flow, which is used at authentication, scopes: [str] # List of requested scopes  Usually `openid` and the names of the requested claims., redirectUris: [str] # URIs, to which a user is redirected after authorization., pkceEnabled: bool=false # Determines whether PKCE is enabled.  cf. [RFC 7636](https://tools.ietf.org/html/rfc7636), pkceChallengeMethod: str # PKCE code challenge method.  cf. [RFC 7636](https://tools.ietf.org/html/rfc7636), mappingClaim: str # Name of the claim which is used for the user mapping., fallbackMappingClaim: str # Name of the claim which is used for the user mapping fallback., resetFallbackMappingClaim: bool # Set `true` to reset `fallbackMappingClaim`., userInfoSource: str(user_info_endpoint/id_token) # Source, which is used to get user information at the import or update of a user., userImportEnabled: bool=false # Determines if a DRACOON account is automatically created for a new user  who successfully logs on with his / her AD / IDP account., userImportGroup: int(int64) # User group that is assigned to users who are created by automatic import.  Reset with `0`, userUpdateEnabled: bool=false # Determines if the DRACOON account is updated with data from AD / IDP.  For OpenID Connect, the scopes `email` and `profile` are needed., userManagementUrl: str # URL of the user management UI.  Use empty string to remove., useAuthProxyEnabled: bool=false # Determines if the IDP use the DRACOON Auth Proxy.  For OpenID Connect, the scopes `email` and `profile` are needed.}
@returns(200) {id: int(int32), name: str, isStandard: bool, isEnabled: bool, issuer: str, authorizationEndPointUrl: str, tokenEndPointUrl: str, userInfoEndPointUrl: str, jwksEndPointUrl: str, clientId: str, clientSecret: str, flow: str, scopes: [str], redirectUris: [str], pkceEnabled: bool, pkceChallengeMethod: str, mappingClaim: str, fallbackMappingClaim: str, userInfoSource: str, userImportEnabled: bool, userImportGroup: int(int64), userUpdateEnabled: bool, userManagementUrl: str, useAuthProxyEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/system/config/auth/openid/idps/{idp_id}
@desc Remove OpenID Connect IDP configuration
@required {idp_id: int(int32) # OpenID Connect IDP configuration ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/system/config/auth/ads/{ad_id}
@desc Request Active Directory configuration
@required {ad_id: int(int32) # Active Directory ID}
@returns(200) {id: int(int32), alias: str, serverIp: str, serverPort: int(int32), serverAdminName: str, ldapUsersDomain: str, userFilter: str, userImport: bool, adExportGroup: str, useLdaps: bool, sdsImportGroup: int(int64), sslFingerPrint: str, homeFolderParent: int(int64), createHomeFolder: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/system/config/auth/ads/{ad_id}
@desc Update Active Directory configuration
@required {ad_id: int(int32) # Active Directory ID}
@optional {alias: str # Unique name for an Active Directory configuration, serverIp: str # IPv4 or IPv6 address or host name, serverPort: int(int32) # Port, serverAdminName: str # Distinguished Name (DN) of Active Directory administrative account, serverAdminPassword: str # Password of Active Directory administrative account, ldapUsersDomain: str # Search scope of Active Directory; only users below this node can log on., userFilter: str # Name of Active Directory attribute that is used as login name., userImport: bool # Determines if a DRACOON account is automatically created for a new user  who successfully logs on with his / her AD / IDP account., adExportGroup: str # If `userImport` is set to `true`,  the user must be member of this Active Directory group to receive a newly created DRACOON account., sdsImportGroup: int(int64) # User group that is assigned to users who are created by automatic import.  Reset with `0`, createHomeFolder: bool=false # DEPRECATED, will be ignored  Determines whether a room is created for each user that is created by automatic import (like a home folder).  Room's name will equal the user's login name., homeFolderParent: int(int64) # DEPRECATED, will be ignored  ID of the room in which the individual rooms for users will be created., useLdaps: bool # Determines whether LDAPS should be used instead of plain LDAP., sslFingerPrint: str # SSL finger print of Active Directory server.  Mandatory for LDAPS connections.  Format: `Algorithm/Fingerprint`}
@returns(200) {id: int(int32), alias: str, serverIp: str, serverPort: int(int32), serverAdminName: str, ldapUsersDomain: str, userFilter: str, userImport: bool, adExportGroup: str, useLdaps: bool, sdsImportGroup: int(int64), sslFingerPrint: str, homeFolderParent: int(int64), createHomeFolder: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/system/config/auth/ads/{ad_id}
@desc Remove Active Directory configuration
@required {ad_id: int(int32) # Active Directory ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endgroup

@group shares
@endpoint GET /v4/shares/uploads
@desc Request list of Upload Shares
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), filter: str # Filter string, sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`).}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/shares/uploads
@desc Update List of Upload Shares
@required {objectIds: [int(int64)] # List of ids}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, showCreatorName: bool # Show creator first and last name., showCreatorUsername: bool # Show creator email address., showUploadedFiles: bool # Allow display of already uploaded files, maxSlots: int(int32) # Maximal amount of files to upload, resetMaxSlots: bool # Set 'true' to reset 'maxSlots' for Upload Share, maxSize: int(int64) # Maximal total size of uploaded files (in bytes), resetMaxSize: bool # Set 'true' to reset 'maxSize' for Upload Share, filesExpiryPeriod: int(int32) # Number of days after which uploaded files expire, resetFilesExpiryPeriod: bool # Set 'true' to reset 'filesExpiryPeriod' for Upload Share}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint POST /v4/shares/uploads
@desc Create new Upload Share
@required {targetId: int(int64) # Target room or folder ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Alias name  (default: name of the shared node), password: str # Password, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, filesExpiryPeriod: int(int32) # Number of days after which uploaded files expire, notes: str # User notes, internalNotes: str # Internal notes, showUploadedFiles: bool=false # Allow display of already uploaded files, maxSlots: int(int32) # Maximal amount of files to upload, maxSize: int(int64) # Maximal total size of uploaded files (in bytes), receiverLanguage: str # Language tag for messages to receiver, textMessageRecipients: [str] # List of recipient FQTNs  E.123 / E.164 Format, showCreatorName: bool=false # Show creator first and last name., showCreatorUsername: bool=false # Show creator email address., notifyCreator: bool=false # Notify creator on every upload., creatorLanguage: str # Language tag for messages to creator, sendMail: bool=false # Notify recipients via email  Please use `POST /shares/uploads/{share_id}/email` API instead., mailRecipients: str # CSV string of recipient email addresses, mailSubject: str # Notification email subject, mailBody: str # Notification email content, sendSms: bool=false # Send share password via SMS  Please use `textMessageRecipients` attribute instead., smsRecipients: str # CSV string of recipient MSISDNs}
@returns(201) {id: int(int64), name: str, targetId: int(int64), isProtected: bool, accessKey: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), targetPath: str, isEncrypted: bool, notes: str, internalNotes: str, filesExpiryPeriod: int(int32), cntFiles: int(int32), cntUploads: int(int32), showUploadedFiles: bool, dataUrl: str, maxSlots: int(int32), maxSize: int(int64), targetType: str, showCreatorName: bool, showCreatorUsername: bool, notifyCreator: bool, recipients: str, smsRecipients: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint DELETE /v4/shares/uploads
@desc Remove Upload Shares
@required {shareIds: [int(int64)] # List of share IDs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/shares/uploads/{share_id}
@desc Request Upload Share
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, targetId: int(int64), isProtected: bool, accessKey: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), targetPath: str, isEncrypted: bool, notes: str, internalNotes: str, filesExpiryPeriod: int(int32), cntFiles: int(int32), cntUploads: int(int32), showUploadedFiles: bool, dataUrl: str, maxSlots: int(int32), maxSize: int(int64), targetType: str, showCreatorName: bool, showCreatorUsername: bool, notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/shares/uploads/{share_id}
@desc Update Upload Share
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Alias name, password: str # Password, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, filesExpiryPeriod: int(int32) # Number of days after which uploaded files expire, notes: str # User notes, internalNotes: str # Internal notes, showCreatorName: bool # Show creator first and last name., showCreatorUsername: bool # Show creator email address., showUploadedFiles: bool # Allow display of already uploaded files, maxSlots: int(int32) # Maximal amount of files to upload, maxSize: int(int64) # Maximal total size of uploaded files (in bytes), textMessageRecipients: [str] # List of recipient FQTNs  E.123 / E.164 Format, receiverLanguage: str # Language tag for messages to receiver, defaultCountry: str # Country shorthand symbol (cf. ISO 3166-2), resetPassword: bool # Set 'true' to reset 'password' for Upload Share., resetFilesExpiryPeriod: bool # Set 'true' to reset 'filesExpiryPeriod' for Upload Share, resetMaxSlots: bool # Set 'true' to reset 'maxSlots' for Upload Share, resetMaxSize: bool # Set 'true' to reset 'maxSize' for Upload Share, notifyCreator: bool # Notify creator on every upload.}
@returns(200) {id: int(int64), name: str, targetId: int(int64), isProtected: bool, accessKey: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), targetPath: str, isEncrypted: bool, notes: str, internalNotes: str, filesExpiryPeriod: int(int32), cntFiles: int(int32), cntUploads: int(int32), showUploadedFiles: bool, dataUrl: str, maxSlots: int(int32), maxSize: int(int64), targetType: str, showCreatorName: bool, showCreatorUsername: bool, notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint DELETE /v4/shares/uploads/{share_id}
@desc Remove Upload Share
@required {share_id: int(int64) # Share ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/shares/downloads
@desc Request list of Download Shares
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), filter: str # Filter string, sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`).}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/shares/downloads
@desc Update a list of Download Shares
@required {objectIds: [int(int64)] # List of ids}
@optional {expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, showCreatorName: bool # Show creator first and last name., showCreatorUsername: bool # Show creator email address., maxDownloads: int(int32) # Max allowed downloads, resetMaxDownloads: bool # Set 'true' to reset 'maxDownloads' for Download Share.}
@returns(200) No Content
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint POST /v4/shares/downloads
@desc Create new Download Share
@required {nodeId: int(int64) # Source node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Alias name  (default: name of the shared node), password: str # Access password, not allowed for encrypted shares, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, notes: str # User notes, internalNotes: str # Internal notes, showCreatorName: bool=false # Show creator first and last name., showCreatorUsername: bool=false # Show creator email address., maxDownloads: int(int32) # Max allowed downloads, keyPair: map{privateKeyContainer!: map, publicKeyContainer!: map} # Key pair container, fileKey: map{key!: str, iv!: str, version!: str, tag!: str} # File key information, receiverLanguage: str # Language tag for messages to receiver, textMessageRecipients: [str] # List of recipient FQTNs  E.123 / E.164 Format, hideDownload: bool=false # Whether or not the download is hidden on a public download share, notifyCreator: bool=false # Notify creator on every download., creatorLanguage: str # Language tag for messages to creator, sendMail: bool=false # Notify recipients via email  Please use `POST /shares/downloads/{share_id}/email` API instead., mailRecipients: str # CSV string of recipient email addresses, mailSubject: str # Notification email subject, mailBody: str # Notification email content, sendSms: bool=false # Send share password via SMS  Please use `textMessageRecipients` attribute instead., smsRecipients: str # CSV string of recipient MSISDNs}
@returns(201) {id: int(int64), name: str, nodeId: int(int64), accessKey: str, cntDownloads: int(int32), createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, notes: str, internalNotes: str, showCreatorName: bool, showCreatorUsername: bool, isProtected: bool, expireAt: str(date-time), maxDownloads: int(int32), nodePath: str, dataUrl: str, isEncrypted: bool, nodeType: str, hideDownload: bool, classification: int(int32), notifyCreator: bool, recipients: str, smsRecipients: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint DELETE /v4/shares/downloads
@desc Remove Download Shares
@required {shareIds: [int(int64)] # List of share IDs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/shares/downloads/{share_id}
@desc Request Download Share
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, nodeId: int(int64), accessKey: str, cntDownloads: int(int32), createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, notes: str, internalNotes: str, showCreatorName: bool, showCreatorUsername: bool, isProtected: bool, expireAt: str(date-time), maxDownloads: int(int32), nodePath: str, dataUrl: str, isEncrypted: bool, nodeType: str, hideDownload: bool, classification: int(int32), notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/shares/downloads/{share_id}
@desc Update Download Share
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Alias name, password: str # Access password, not allowed for encrypted shares, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, notes: str # User notes, internalNotes: str # Internal notes, showCreatorName: bool # Show creator first and last name., showCreatorUsername: bool # Show creator email address., maxDownloads: int(int32) # Max allowed downloads, textMessageRecipients: [str] # List of recipient FQTNs  E.123 / E.164 Format, receiverLanguage: str # Language tag for messages to receiver, defaultCountry: str # Country shorthand symbol (cf. ISO 3166-2), resetPassword: bool # Set 'true' to reset 'password' for Download Share., resetMaxDownloads: bool # Set 'true' to reset 'maxDownloads' for Download Share., hideDownload: bool # Whether or not the download is hidden on a public download share, notifyCreator: bool # Notify creator on every download.}
@returns(200) {id: int(int64), name: str, nodeId: int(int64), accessKey: str, cntDownloads: int(int32), createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, notes: str, internalNotes: str, showCreatorName: bool, showCreatorUsername: bool, isProtected: bool, expireAt: str(date-time), maxDownloads: int(int32), nodePath: str, dataUrl: str, isEncrypted: bool, nodeType: str, hideDownload: bool, classification: int(int32), notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 502: Bad Gateway}

@endpoint DELETE /v4/shares/downloads/{share_id}
@desc Remove Download Share
@required {share_id: int(int64) # Share ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group settings
@endpoint GET /v4/settings
@desc Request customer settings
@returns(200) {homeRoomsActive: bool, homeRoomParentId: int(int64), homeRoomParentName: str, homeRoomQuota: int(int64)} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/settings
@desc Set customer settings
@optional {homeRoomParentName: str # Homeroom Parent Name, homeRoomQuota: int(int64) # Homeroom Quota in bytes, homeRoomsActive: bool # Homerooms active}
@returns(200) {homeRoomsActive: bool, homeRoomParentId: int(int64), homeRoomParentName: str, homeRoomQuota: int(int64)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/settings/webhooks/{webhook_id}
@desc Request webhook
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/settings/webhooks/{webhook_id}
@desc Update webhook
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Name, eventTypeNames: [str] # List of names of event types, url: str # URL (must begin with the `HTTPS` scheme), secret: str # Secret; used for event message signatures, isEnabled: bool # Is enabled, triggerExampleEvent: bool # If set to true, an example event is being created}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/settings/webhooks/{webhook_id}
@desc Remove webhook
@required {webhook_id: int(int64) # Webhook ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/settings/notifications/channels
@desc Request list of notification channels
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/settings/notifications/channels
@desc Toggle notification channels
@required {channelId: int(int32) # Channel ID, isEnabled: bool # Determines whether channel is enabled}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group public
@endpoint GET /v4/public/shares/uploads/{access_key}/{upload_id}
@desc Request status of S3 file upload
@required {access_key: str # Access key, upload_id: str # Upload channel ID}
@returns(200) {status: str, fileName: str, size: int(int64), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/public/shares/uploads/{access_key}/{upload_id}
@desc Complete file upload
@required {access_key: str # Access key, upload_id: str # Upload channel ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), items: [map{userId!: int(int64), fileKey!: map}] # List of user file keys}
@returns(201) {name: str, size: int(int64), createdAt: str(date-time), hash: str} # Created
@returns(202) {name: str, size: int(int64), createdAt: str(date-time), hash: str} # Accepted
@errors {400: Bad Request, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint POST /v4/public/shares/uploads/{access_key}/{upload_id}
@desc Upload file
@required {access_key: str # Access key, upload_id: str # Upload channel ID}
@optional {Content-Range: str # Content-Range   e.g. `bytes 0-999/3980`, X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {size: int(int64), hash: str} # OK
@returns(201) {size: int(int64), hash: str} # Created
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint DELETE /v4/public/shares/uploads/{access_key}/{upload_id}
@desc Cancel file upload
@required {access_key: str # Access key, upload_id: str # Upload channel ID}
@returns(204) No Content
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint PUT /v4/public/shares/uploads/{access_key}/{upload_id}/s3
@desc Complete S3 file upload
@required {access_key: str # Access key, upload_id: str # Upload channel ID, parts: [map{partNumber!: int(int32), partEtag!: str}] # List of S3 file upload parts}
@optional {userFileKeyList: [map{userId!: int(int64), fileKey!: map}] # List of user file keys}
@returns(202) Accepted
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group provisioning
@endpoint GET /v4/provisioning/webhooks/{webhook_id}
@desc Request tenant webhook
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint PUT /v4/provisioning/webhooks/{webhook_id}
@desc Update tenant webhook
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token, name: str # Name, eventTypeNames: [str] # List of names of event types, url: str # URL (must begin with the `HTTPS` scheme), secret: str # Secret; used for event message signatures, isEnabled: bool # Is enabled, triggerExampleEvent: bool # If set to true, an example event is being created}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint DELETE /v4/provisioning/webhooks/{webhook_id}
@desc Remove tenant webhook
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Service-Token: str # Service Authentication token}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/provisioning/customers/{customer_id}
@desc Get customer
@required {customer_id: int(int64) # Customer ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), include_attributes: bool # Include custom customer attributes., X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {id: int(int64), companyName: str, customerContractType: str, quotaMax: int(int64), quotaUsed: int(int64), userMax: int(int32), userUsed: int(int32), cntInternalUser: int(int32), cntGuestUser: int(int32), createdAt: str(date-time), isLocked: bool, trialDaysLeft: int(int32), updatedAt: str(date-time), lastLoginAt: str(date-time), customerAttributes: map{items: [map]}, providerCustomerId: str, webhooksMax: int(int64), activationCode: str, lockStatus: bool, customerUuid: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endpoint PUT /v4/provisioning/customers/{customer_id}
@desc Update customer
@required {customer_id: int(int64) # Customer ID, customerContractType: str(demo/free/pay) # Customer type}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token, companyName: str # Company name, quotaMax: int(int64) # Maximal disc space which can be allocated by customer in bytes. -1 for unlimited, userMax: int(int32) # Maximal number of users, isLocked: bool=false # Customer is locked:  * `false` - unlocked  * `true` - locked    All users of this customer will be blocked and can not login anymore., providerCustomerId: str # Provider customer ID, webhooksMax: int(int64) # Maximal number of webhooks, lockStatus: bool=false # Customer lock status:  * `false` - unlocked  * `true` - locked    Please use `isLocked` instead.  All users of this customer will be blocked and can not login anymore.}
@returns(200) {id: int(int64), companyName: str, customerContractType: str, quotaMax: int(int64), userMax: int(int32), customerUuid: str, isLocked: bool, trialDays: int(int32), createdAt: str(date-time), updatedAt: str(date-time), customerAttributes: map{items: [map]}, providerCustomerId: str, webhooksMax: int(int64), activationCode: str, lockStatus: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 404: Not Found, 406: Not Acceptable}

@endpoint DELETE /v4/provisioning/customers/{customer_id}
@desc Remove customer
@required {customer_id: int(int64) # Customer ID}
@optional {X-Sds-Service-Token: str # Service Authentication token}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/provisioning/customers/{customer_id}/customerAttributes
@desc Request customer attributes
@required {customer_id: int(int64) # Customer ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string, X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endpoint PUT /v4/provisioning/customers/{customer_id}/customerAttributes
@desc Add or edit customer attributes
@required {customer_id: int(int64) # Customer ID, items: [map{key!: str, value!: str}] # List of customer attributes}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endpoint POST /v4/provisioning/customers/{customer_id}/customerAttributes
@desc Set customer attributes
@required {customer_id: int(int64) # Customer ID, items: [map{key!: str, value!: str}] # List of customer attributes}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token}
@returns(201) {id: int(int64), companyName: str, customerContractType: str, quotaMax: int(int64), quotaUsed: int(int64), userMax: int(int32), userUsed: int(int32), cntInternalUser: int(int32), cntGuestUser: int(int32), createdAt: str(date-time), isLocked: bool, trialDaysLeft: int(int32), updatedAt: str(date-time), lastLoginAt: str(date-time), customerAttributes: map{items: [map]}, providerCustomerId: str, webhooksMax: int(int64), activationCode: str, lockStatus: bool, customerUuid: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endgroup

@group nodes
@endpoint GET /v4/nodes/{node_id}/node_attributes
@desc Request custom node attributes
@required {node_id: int(int64) # Node ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/{node_id}/node_attributes
@desc Add or edit custom node attributes
@required {node_id: int(int64) # Node ID, items: [map{key!: str, value!: str}] # List of key-value pairs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}
@desc Updates room’s metadata
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Name, quota: int(int64) # Quota in byte, notes: str # User notes  Use empty string to remove., timestampCreation: str(date-time) # Time the node was created on external file system, timestampModification: str(date-time) # Time the content of a node was last modified on external file system}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/webhooks
@desc Request list of webhooks that are assigned or can be assigned to this room
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/webhooks
@desc Assign or unassign webhooks to room
@required {room_id: int(int64) # Room ID, items: [map{webhookId!: int(int64), isAssigned!: bool}] # Assign a webhook to a room to use it for node actions within the room}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/users
@desc Request room granted user(s) or / and user(s) that can be granted
@required {room_id: int(int64) # Room ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/users
@desc Add or change room granted user(s)
@required {room_id: int(int64) # Room ID, items: [map{id!: int(int64), permissions!: map}] # List of room-user mappings}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/rooms/{room_id}/users
@desc Revoke granted user(s) from room
@required {room_id: int(int64) # Room ID, ids: [int(int64)] # List of user IDs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/policies
@desc Request Room Policies
@required {room_id: int(int64) # Room ID}
@returns(200) {defaultExpirationPeriod: int(int32), isVirusProtectionEnabled: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/policies
@desc Set room policies
@required {room_id: int(int64) # Room ID}
@optional {defaultExpirationPeriod: int(int32) # Default policy room expiration period in seconds.  All files in a room will have their expiration date set to this period after their respective upload.   0 means no default expiration policy is set., virusProtectionEnabled: bool # Determines whether virus protection is enabled for room. To be set by room admins}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/guest_users
@desc Add guest users to a room
@required {room_id: int(int64) # Room ID, roomGuestInvitations: [map{firstName!: str, lastName!: str, email!: str}] # List of room-user mappings}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/groups
@desc Request room granted group(s) or / and group(s) that can be granted
@required {room_id: int(int64) # Room ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/groups
@desc Add or change room granted group(s)
@required {room_id: int(int64) # Room ID, items: [map{id!: int(int64), permissions!: map, newGroupMemberAcceptance: str}] # List of room-group mappings}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/rooms/{room_id}/groups
@desc Revoke granted group(s) from room
@required {room_id: int(int64) # Room ID, ids: [int(int64)] # List of group IDs}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/encrypt
@desc Encrypt room
@required {room_id: int(int64) # Room ID, isEncrypted: bool # Encryption state}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), useDataSpaceRescueKey: bool # Use system emergency password (rescue key) for files in this room, dataRoomRescueKey: map{privateKeyContainer!: map, publicKeyContainer!: map} # Key pair container}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/{room_id}/config
@desc Configure room
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), recycleBinRetentionPeriod: int(int32) # Retention period for deleted nodes in days, inheritPermissions: bool # Inherit permissions from parent room  (default: `false` if `parentId` is `0`; otherwise: `true`), takeOverPermissions: bool # Take over existing permissions, adminIds: [int(int64)] # List of user ids  A room requires at least one admin (user or group), adminGroupIds: [int(int64)] # List of group ids  A room requires at least one admin (user or group), newGroupMemberAcceptance: str(autoallow/pending)=autoallow # Behaviour when new users are added to the group:  * `autoallow`  * `pending`    Only relevant if `adminGroupIds` has items., hasActivitiesLog: bool=true # Is activities log active (for rooms only), classification: int(int32)(1/2/3/4)=2 # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential    Provided (or default) classification is taken from room  when file gets uploaded without any classification.}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/pending
@desc Request user-room assignments per group
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/rooms/pending
@desc Handle user-room assignments per group
@required {items: [map{userId!: int(int64), groupId!: int(int64), roomId!: int(int64), roomName!: str, state!: str}] # List of pending assignments}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/folders/{folder_id}
@desc Updates folder’s metadata
@required {folder_id: int(int64) # Folder ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Folder name, notes: str # User notes  Use empty string to remove., classification: int(int32)(1/2/3/4) # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential    Provided (or default) classification is taken from room  when file gets uploaded without any classification., timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format)}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint PUT /v4/nodes/files
@desc Updates a list of  file’s metadata
@required {objectIds: [int(int64)] # List of ids}
@optional {classification: int(int32) # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint PUT /v4/nodes/files/{file_id}
@desc Updates a file’s metadata
@required {file_id: int(int64) # File ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # File name, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, classification: int(int32) # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential, notes: str # User notes  Use empty string to remove., timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format)}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/nodes/files/uploads/{upload_id}
@desc Request status of S3 file upload
@required {upload_id: str # Upload channel ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {status: str, node: map{id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}}, errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/files/uploads/{upload_id}
@desc Complete file upload
@required {upload_id: str # Upload channel ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., fileName: str # New file name to store with, fileKey: map{key!: str, iv!: str, version!: str, tag!: str} # File key information, userFileKeyList: map{items: [map]} # Mandatory for encrypted shares}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@returns(202) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Accepted
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint POST /v4/nodes/files/uploads/{upload_id}
@desc Upload file
@required {upload_id: str # Upload channel ID}
@optional {Content-Range: str # Content-Range   e.g. `bytes 0-999/3980`}
@returns(201) {size: int(int64), hash: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint DELETE /v4/nodes/files/uploads/{upload_id}
@desc Cancel file upload
@required {upload_id: str # Upload channel ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout}

@endpoint PUT /v4/nodes/files/uploads/{upload_id}/s3
@desc Complete S3 file upload
@required {upload_id: str # Upload channel ID, parts: [map{partNumber!: int(int32), partEtag!: str}] # List of S3 file upload parts}
@optional {resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., fileName: str # New file name to store with, fileKey: map{key!: str, iv!: str, version!: str, tag!: str} # File key information, isPrioritisedVirusScan: bool=false # If true prioritises the virus-protection scan higher when in a scanning room and it comes from ms-teams or OAI}
@returns(202) Accepted
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 504: Gateway Timeout}

@endpoint PUT /v4/nodes/favorites
@desc Mark or unmark a list of nodes (room, folder or file) as favorite
@required {isFavorite: bool # Sets the favorite attribute to true or false on each file in an array of nodes., objectIds: [int(int64)] # List of ids}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/nodes/comments/{comment_id}
@desc Edit node comment
@required {comment_id: int(int64) # Comment ID, text: str # Comment text}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), text: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, isChanged: bool, isDeleted: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/comments/{comment_id}
@desc Remove node comment
@required {comment_id: int(int64) # Comment ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group groups
@endpoint GET /v4/groups/{group_id}
@desc Request user group
@required {group_id: int(int64) # Group ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, cntUsers: int(int32), updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), groupRoles: map{items: [map]}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/groups/{group_id}
@desc Update user group's metadata
@required {group_id: int(int64) # Group ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), name: str # Group name, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information}
@returns(200) {id: int(int64), name: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, cntUsers: int(int32), updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), groupRoles: map{items: [map]}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/groups/{group_id}
@desc Remove user group
@required {group_id: int(int64) # Group ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group config
@endpoint GET /v4/config/settings
@desc Request system settings
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint PUT /v4/config/settings
@desc Update system settings
@required {items: [map{key!: str, value!: str}] # List of key-value pairs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group auth
@endpoint GET /v4/auth/reset_password/{token}
@desc Validate information for password reset
@required {token: str # Password reset token}
@returns(200) {firstName: str, lastName: str, loginPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map{enabled: bool, maxPasswordAge: int(int32)}, userLockout: map{enabled: bool, maxNumberOfLoginFailures: int(int32), lockoutPeriod: int(int32)}, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, title: str, gender: str, allowSystemGlobalWeakPassword: bool} # OK
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endpoint PUT /v4/auth/reset_password/{token}
@desc Reset password
@required {token: str # Password reset token, password: str # New password}
@returns(204) No Content
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endgroup

@group users
@endpoint GET /v4/users
@desc Request users
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string, include_attributes: bool # Include custom user attributes., include_roles: bool # Include roles, include_manageable_rooms: bool # Include hasManageableRooms (deprecated)}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/users
@desc Create new user
@required {firstName: str # User first name, lastName: str # User last name}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), userName: str # Username, phone: str # Phone number, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, receiverLanguage: str # IETF language tag, email: str # Email, notifyUser: bool # Notify user about his new account  * default: `true` for `basic` auth type  * default: `false` for `active_directory`, `openid` auth types, authData: map{method!: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)} # User Authentication Data, isNonmemberViewer: bool # Determines whether user has the role NONMEMBER_VIEWER, mfaConfig: map{mfaEnforced: bool} # Multi-factor authentication configuration, title: str # Job title, password: str # An initial password may be preset  use `authData` instead, login: str # User login name, authMethods: [map{authId!: str, isEnabled!: bool, options: [map]}] # Authentication methods:  * `sql`  * `active_directory`  * `openid`  use `authData` instead, needsToChangePassword: bool # Determines whether user has to change his / her initial password.  use `authDate.mustChangePassword` instead, gender: str=n # Gender  Do NOT use `gender`! It will be ignored.}
@returns(201) {id: int(int64), userName: str, firstName: str, lastName: str, isLocked: bool, avatarUuid: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, email: str, phone: str, expireAt: str(date-time), hasManageableRooms: bool, isEncryptionEnabled: bool, lastLoginSuccessAt: str(date-time), homeRoomId: int(int64), publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}, userRoles: map{items: [map]}, isMfaEnabled: bool, isMfaEnforced: bool, userAttributes: map{items: [map]}, title: str, lockStatus: int(int32), login: str, authMethods: [map], gender: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint POST /v4/users/{user_id}/mfa/emergency_code
@desc Request emergency MFA code
@required {user_id: int(int64)}
@returns(200) {code: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group user
@endpoint POST /v4/user/subscriptions/upload_shares/{share_id}
@desc Subscribe Upload Share for notifications
@required {share_id: int(int64) # Share ID}
@returns(201) {id: int(int64), targetNodeId: int(int64)} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/subscriptions/upload_shares/{share_id}
@desc Unsubscribe Upload Share from notifications
@required {share_id: int(int64) # Share ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/subscriptions/nodes/{node_id}
@desc Subscribe node for notifications
@required {node_id: int(int64) # Node ID}
@returns(201) {id: int(int64), type: str, authParentId: int(int64), name: str, parentPath: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/subscriptions/nodes/{node_id}
@desc Unsubscribe node from notifications
@required {node_id: int(int64) # Node ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/subscriptions/download_shares/{share_id}
@desc Subscribe Download Share for notifications
@required {share_id: int(int64) # Share ID}
@returns(201) {id: int(int64), authParentId: int(int64)} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/subscriptions/download_shares/{share_id}
@desc Unsubscribe Download Share from notifications
@required {share_id: int(int64) # Share ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account/mfa/totp
@desc Request information to setup TOTP as second authentication factor
@returns(201) {id: int(int64), qrCode: str, otpUri: str, secret: str} # Created
@errors {401: Unauthorized, 402: Payment Required, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint POST /v4/user/account/mfa/totp
@desc Confirm second factor TOTP setup with a generated OTP
@required {id: int(int64) # ID, otp: str # Generated valid OTP}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account/keypairs
@desc Request all user key pairs
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) OK
@errors {401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/account/keypairs
@desc Create key pair and preserve copy of old private key
@required {privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container, previousPrivateKey: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/user/account/keypair
@desc Request user's key pair
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), version: str # Version (NEW)}
@returns(200) {privateKeyContainer: map{version: str, privateKey: str, createdAt: str(date-time), createdBy: int(int64)}, publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/account/keypair
@desc Set user's key pair
@required {privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/user/account/keypair
@desc Remove user's key pair
@optional {version: str # Version (NEW)}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account/avatar
@desc Request avatar
@returns(200) {avatarUri: str, avatarUuid: str, isCustomAvatar: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/user/account/avatar
@desc Change avatar
@returns(201) {avatarUri: str, avatarUuid: str, isCustomAvatar: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/account/avatar
@desc Reset avatar
@returns(200) {avatarUri: str, avatarUuid: str, isCustomAvatar: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group system
@endpoint GET /v4/system/config/storage/s3/tags
@desc Request list of configured S3 tags
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/system/config/storage/s3/tags
@desc Create S3 tag
@required {key: str # S3 tag key, value: str # S3 tag value}
@optional {isMandatory: bool=false # Determines whether S3 is mandatory or not}
@returns(201) {id: int(int64), key: str, value: str, isMandatory: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint POST /v4/system/config/policies/passwords/enforce_change
@desc Enforce login password change for all users
@returns(200) OK
@returns(204) No Content
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/oauth/clients
@desc Request list of OAuth clients
@optional {filter: str # Filter string, sort: str # Sort string}
@returns(200) OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/system/config/oauth/clients
@desc Create OAuth client
@required {clientName: str # Name, which is shown at the client configuration and authorization., grantTypes: [str](authorization_code/client_credentials/implicit/password/refresh_token) # Authorized grant types  * `authorization_code`  * `implicit`  * `password`  * `client_credentials`  * `refresh_token`    cf. [RFC 6749](https://tools.ietf.org/html/rfc6749), redirectUris: [str] # URIs, to which a user is redirected after authorization.}
@optional {clientId: str # ID of the OAuth client, clientSecret: str # Secret, which client uses at authentication., clientType: str(confidential/public)=confidential # Determines whether client is a confidential or public client., accessTokenValidity: int(int32) # Validity of the access token in seconds., refreshTokenValidity: int(int32) # Validity of the refresh token in seconds., approvalValidity: int(int32) # Validity of the approval interval in seconds.}
@returns(201) {clientId: str, clientSecret: str, clientName: str, clientType: str, isStandard: bool, isExternal: bool, isEnabled: bool, grantTypes: [str], redirectUris: [str], accessTokenValidity: int(int32), refreshTokenValidity: int(int32), approvalValidity: int(int32)} # Created
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/system/config/auth/openid/idps
@desc Request list of OpenID Connect IDP configurations
@optional {filter: str # Filter string, sort: str # Sort string}
@returns(200) OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/system/config/auth/openid/idps
@desc Create OpenID Connect IDP configuration
@required {name: str # Name of the IDP, issuer: str # Issuer identifier of the IDP  The value is a case sensitive URL., authorizationEndPointUrl: str # URL of the authorization endpoint, tokenEndPointUrl: str # URL of the token endpoint, userInfoEndPointUrl: str # URL of the user info endpoint, jwksEndPointUrl: str # URL of the JWKS endpoint, clientId: str # ID of the OpenID client, clientSecret: str # Secret, which client uses at authentication., scopes: [str] # List of requested scopes, redirectUris: [str] # URIs, to which a user is redirected after authorization., mappingClaim: str # Name of the claim which is used for the user mapping.}
@optional {flow: str(authorization_code/hybrid) # Flow, which is used at authentication, pkceEnabled: bool=false # Determines whether PKCE is enabled.  cf. [RFC 7636](https://tools.ietf.org/html/rfc7636), pkceChallengeMethod: str=plain # PKCE code challenge method.  cf. [RFC 7636](https://tools.ietf.org/html/rfc7636), fallbackMappingClaim: str # Name of the claim which is used for the user mapping fallback., userInfoSource: str(user_info_endpoint/id_token) # Source, which is used to get user information at the import or update of a user., userImportEnabled: bool=false # Determines if a DRACOON account is automatically created for a new user  who successfully logs on with his / her AD / IDP account., userImportGroup: int(int64) # User group that is assigned to users who are created by automatic import.  Reset with `0`, userUpdateEnabled: bool=false # Determines if the DRACOON account is updated with data from AD / IDP.  For OpenID Connect, the scopes `email` and `profile` are needed., userManagementUrl: str # URL of the user management UI.  Use empty string to remove., useAuthProxyEnabled: bool=false # Determines if the IDP use the DRACOON Auth Proxy.  For OpenID Connect, the scopes `email` and `profile` are needed.}
@returns(201) {id: int(int32), name: str, isStandard: bool, isEnabled: bool, issuer: str, authorizationEndPointUrl: str, tokenEndPointUrl: str, userInfoEndPointUrl: str, jwksEndPointUrl: str, clientId: str, clientSecret: str, flow: str, scopes: [str], redirectUris: [str], pkceEnabled: bool, pkceChallengeMethod: str, mappingClaim: str, fallbackMappingClaim: str, userInfoSource: str, userImportEnabled: bool, userImportGroup: int(int64), userUpdateEnabled: bool, userManagementUrl: str, useAuthProxyEnabled: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/system/config/auth/ads
@desc Request list of Active Directory configurations
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/system/config/auth/ads
@desc Create Active Directory configuration
@required {alias: str # Unique name for an Active Directory configuration, serverIp: str # IPv4 or IPv6 address or host name, serverPort: int(int32) # Port, serverAdminName: str # Distinguished Name (DN) of Active Directory administrative account, serverAdminPassword: str # Password of Active Directory administrative account, ldapUsersDomain: str # Search scope of Active Directory; only users below this node can log on., userFilter: str # Name of Active Directory attribute that is used as login name.}
@optional {userImport: bool=false # Determines if a DRACOON account is automatically created for a new user  who successfully logs on with his / her AD / IDP account., useLdaps: bool=false # Determines whether LDAPS should be used instead of plain LDAP., adExportGroup: str # If `userImport` is set to `true`,  the user must be member of this Active Directory group to receive a newly created DRACOON account., sdsImportGroup: int(int64) # User group that is assigned to users who are created by automatic import.  Reset with `0`, createHomeFolder: bool=false # DEPRECATED, will be ignored  Determines whether a room is created for each user that is created by automatic import (like a home folder).  Room's name will equal the user's login name., homeFolderParent: int(int64) # DEPRECATED, will be ignored  ID of the room in which the individual rooms for users will be created., sslFingerPrint: str # SSL finger print of Active Directory server.  Mandatory for LDAPS connections.  Format: `Algorithm/Fingerprint`}
@returns(201) {id: int(int32), alias: str, serverIp: str, serverPort: int(int32), serverAdminName: str, ldapUsersDomain: str, userFilter: str, userImport: bool, adExportGroup: str, useLdaps: bool, sdsImportGroup: int(int64), sslFingerPrint: str, homeFolderParent: int(int64), createHomeFolder: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint POST /v4/system/config/actions/test/ad
@desc Test Active Directory configuration
@required {serverIp: str # IPv4 or IPv6 address or host name, serverPort: int(int32) # Port, serverAdminName: str # Distinguished Name (DN) of Active Directory administrative account, serverAdminPassword: str # Password of Active Directory administrative account, ldapUsersDomain: str # Search scope of Active Directory; only users below this node can log on.}
@optional {useLdaps: bool=false # Determines whether LDAPS should be used instead of plain LDAP., sslFingerPrint: str # SSL finger print of Active Directory server.  Mandatory for LDAPS connections.  Format: `Algorithm/Fingerprint`}
@returns(200) {serverIp: str, serverPort: int(int32), serverAdminName: str, ldapUsersDomain: str, useLdaps: bool, sslFingerPrint: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group shares
@endpoint POST /v4/shares/uploads/{share_id}/email
@desc Send an existing Upload Share link via email
@required {share_id: int(int64) # Share ID, recipients: [str] # List of recipient email addresses, body: str # Notification email content}
@optional {receiverLanguage: str # Language tag for messages to receiver}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/shares/downloads/{share_id}/email
@desc Send an existing Download Share link via email
@required {share_id: int(int64) # Share ID, recipients: [str] # List of recipient email addresses, body: str # Notification email content}
@optional {receiverLanguage: str # Language tag for messages to receiver}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group settings
@endpoint GET /v4/settings/webhooks
@desc Request list of webhooks
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/settings/webhooks
@desc Create webhook
@required {name: str # Name, eventTypeNames: [str] # List of names of event types, url: str # URL (must begin with the `HTTPS` scheme)}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), secret: str # Secret; used for event message signatures, isEnabled: bool # Is enabled, triggerExampleEvent: bool # If set to true, an example event is being created}
@returns(201) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/settings/webhooks/{webhook_id}/reset_lifetime
@desc Reset webhook lifetime
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/settings/keypairs
@desc Request all system rescue key pairs
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/settings/keypairs
@desc Create system rescue key pair and preserve copy of old private key
@required {privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container, previousPrivateKey: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/settings/keypair
@desc Request system rescue key pair
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), version: str # Version (NEW)}
@returns(200) {privateKeyContainer: map{version: str, privateKey: str, createdAt: str(date-time), createdBy: int(int64)}, publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/settings/keypair
@desc Activate client-side encryption for customer
@required {privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/settings/keypair
@desc Remove system rescue key pair
@optional {version: str # Version (NEW)}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group roles
@endpoint GET /v4/roles/{role_id}/users
@desc Request users with specific role
@required {role_id: int(int32) # Role ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/roles/{role_id}/users
@desc Assign user(s) to the role
@required {role_id: int(int32) # Role ID, ids: [int(int64)] # List of user IDs}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/roles/{role_id}/users
@desc Revoke granted role from user(s)
@required {role_id: int(int32) # Role ID, ids: [int(int64)] # List of user IDs}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/roles/{role_id}/groups
@desc Request groups with specific role
@required {role_id: int(int32) # Role ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/roles/{role_id}/groups
@desc Assign group(s) to the role
@required {role_id: int(int32) # Role ID, ids: [int(int64)] # List of group IDs}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/roles/{role_id}/groups
@desc Revoke granted role from group(s)
@required {role_id: int(int32) # Role ID, ids: [int(int64)] # List of group IDs}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group public
@endpoint GET /v4/public/shares/uploads/{access_key}
@desc Request public Upload Share information
@required {access_key: str # Access key}
@optional {X-Sds-Share-Password: str # Upload share password. Should be base64-encoded.  Plain X-Sds-Share-Passwords are *deprecated* and will be removed in the future, X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {isProtected: bool, createdAt: str(date-time), name: str, isEncrypted: bool, expireAt: str(date-time), notes: str, uploadedFiles: [map], userUserPublicKeyList: map{items: [map]}, showUploadedFiles: bool, remainingSize: int(int64), remainingSlots: int(int32), creatorName: str, creatorUsername: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint POST /v4/public/shares/uploads/{access_key}
@desc Create new file upload channel
@required {access_key: str # Access key, name: str # File name}
@optional {size: int(int64) # File size in byte, password: str # Password, directS3Upload: bool=false # Upload direct to S3, timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format)}
@returns(201) {uploadId: str, uploadUrl: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint POST /v4/public/shares/uploads/{access_key}/{upload_id}/s3_urls
@desc Generate presigned URLs for S3 file upload
@required {access_key: str # Access key, upload_id: str # Upload channel ID, size: int(int64) # `Content-Length` header size for each presigned URL (in bytes)  *MUST* be >= 5 MB except the last part., firstPartNumber: int(int32) # First part number of a range of requested presigned URLs (for S3 it is: `1`), lastPartNumber: int(int32) # Last part number of a range of requested presigned URLs}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(201) {urls: [map]} # Created
@errors {400: Bad Request, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint GET /v4/public/shares/downloads/{access_key}
@desc Request public Download Share information
@required {access_key: str # Access key}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {isProtected: bool, fileName: str, size: int(int64), limitReached: bool, creatorName: str, createdAt: str(date-time), hasDownloadLimit: bool, mediaType: str, name: str, creatorUsername: str, expireAt: str(date-time), notes: str, isEncrypted: bool, fileKey: map{key: str, iv: str, version: str, tag: str}, privateKeyContainer: map{version: str, privateKey: str, createdAt: str(date-time), createdBy: int(int64)}, virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}, hideDownload: bool} # OK
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endpoint POST /v4/public/shares/downloads/{access_key}
@desc Generate download URL
@required {access_key: str # Access key}
@optional {password: str # Password (only for password-protected shares)}
@returns(201) {downloadUrl: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint HEAD /v4/public/shares/downloads/{access_key}
@desc Check public Download Share password
@required {access_key: str # Access key}
@optional {password: str # Download share password}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endgroup

@group provisioning
@endpoint GET /v4/provisioning/webhooks
@desc Request list of tenant webhooks
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string, X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint POST /v4/provisioning/webhooks
@desc Create tenant webhook
@required {name: str # Name, eventTypeNames: [str] # List of names of event types, url: str # URL (must begin with the `HTTPS` scheme)}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token, secret: str # Secret; used for event message signatures, isEnabled: bool # Is enabled, triggerExampleEvent: bool # If set to true, an example event is being created}
@returns(201) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint POST /v4/provisioning/webhooks/{webhook_id}/reset_lifetime
@desc Reset tenant webhook lifetime
@required {webhook_id: int(int64) # Webhook ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {id: int(int64), name: str, url: str, secret: str, isEnabled: bool, expireAt: str(date-time), eventTypeNames: [str], createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, failStatus: int(int32)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/provisioning/customers
@desc Request list of customers
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string, include_attributes: bool # Include custom customer attributes., X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endpoint POST /v4/provisioning/customers
@desc Create customer
@required {customerContractType: str(demo/free/pay) # Customer type, quotaMax: int(int64) # Maximal disc space which can be allocated by customer in bytes. -1 for unlimited, userMax: int(int32) # Maximal number of users, firstAdminUser: map{firstName!: str, lastName!: str, userName: str, authData: map, receiverLanguage: str, notifyUser: bool, email: str, phone: str, title: str, language: str, authMethods: [map], needsToChangeUserName: bool, password: str, needsToChangePassword: bool, login: str, gender: str} # First administrator user}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), X-Sds-Service-Token: str # Service Authentication token, companyName: str # Company name, trialDays: int(int32) # Number of days left for trial period (relevant only for type `demo`)  (not used), isLocked: bool=false # Customer is locked:  * `false` - unlocked  * `true` - locked    All users of this customer will be blocked and can not login anymore., customerAttributes: map{items!: [map]} # List of customer attributes, providerCustomerId: str # Provider customer ID, webhooksMax: int(int64) # Maximal number of webhooks, lockStatus: bool=false # Customer lock status:  * `false` - unlocked  * `true` - locked    Please use `isLocked` instead.  All users of this customer will be blocked and can not login anymore., activationCode: str # Customer activation code string:  * valid only for types `free` and `demo`  * for `pay` customers it is empty}
@returns(201) {id: int(int64), companyName: str, customerContractType: str, quotaMax: int(int64), userMax: int(int32), isLocked: bool, trialDays: int(int32), createdAt: str(date-time), firstAdminUser: map{firstName: str, lastName: str, userName: str, authData: map{method: str, login: str, password: str, mustChangePassword: bool, adConfigId: int(int32), oidConfigId: int(int32)}, receiverLanguage: str, notifyUser: bool, email: str, phone: str, title: str, language: str, authMethods: [map], needsToChangeUserName: bool, password: str, needsToChangePassword: bool, login: str, gender: str}, customerAttributes: map{items: [map]}, providerCustomerId: str, webhooksMax: int(int64), customerUuid: str, activationCode: str, lockStatus: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 404: Not Found, 406: Not Acceptable, 409: Conflict}

@endgroup

@group nodes
@endpoint POST /v4/nodes/{node_id}/move_to
@desc Move node(s)
@required {node_id: int(int64) # Target parent node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), items: [map{id!: int(int64), name: str, timestampCreation: str(date-time), timestampModification: str(date-time)}] # List of nodes to be moved, resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., nodeIds: [int(int64)] # Node IDs  Please use `items` instead.}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint POST /v4/nodes/{node_id}/favorite
@desc Mark a node (room, folder or file) as favorite
@required {node_id: int(int64) # Node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/{node_id}/favorite
@desc Unmark a node (room, folder or file) as favorite
@required {node_id: int(int64) # Node ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/{node_id}/copy_to
@desc Copy node(s)
@required {node_id: int(int64) # Target parent node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), items: [map{id!: int(int64), name: str, timestampCreation: str(date-time), timestampModification: str(date-time)}] # List of nodes to be copied, resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., nodeIds: [int(int64)] # Node IDs  Please use `items` instead.}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint GET /v4/nodes/{node_id}/comments
@desc Request list of node comments
@required {node_id: int(int64) # Node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., hide_deleted: bool # Hide deleted comments (default: false)}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/{node_id}/comments
@desc Create node comment
@required {node_id: int(int64) # Node ID, text: str # Comment text}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(201) {id: int(int64), text: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, isChanged: bool, isDeleted: bool} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/zip
@desc Generate download URL for ZIP download
@required {nodeIds: [int(int64)] # List of node IDs}
@returns(200) {downloadUrl: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/zip/download
@desc Download files / folders as ZIP archive
@required {nodeIds: [int(int64)] # List of node IDs}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/rooms
@desc Create new room
@required {name: str # Name}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), parentId: int(int64) # Parent room ID or `null` (not 0) to create a top level room, recycleBinRetentionPeriod: int(int32) # Retention period for deleted nodes in days, quota: int(int64) # Quota in byte, inheritPermissions: bool # Inherit permissions from parent room  (default: `false` if `parentId` is `0`; otherwise: `true`), adminIds: [int(int64)] # List of user ids  A room requires at least one admin (user or group), adminGroupIds: [int(int64)] # List of group ids  A room requires at least one admin (user or group), newGroupMemberAcceptance: str(autoallow/pending)=autoallow # Behaviour when new users are added to the group:  * `autoallow`  * `pending`    Only relevant if `adminGroupIds` has items., notes: str # User notes  Use empty string to remove., hasActivitiesLog: bool=true # Is activities log active (for rooms only), classification: int(int32)(1/2/3/4)=2 # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential    Provided (or default) classification is taken from room  when file gets uploaded without any classification., timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format), hasRecycleBin: bool # Is recycle bin active (for rooms only)  Recycle bin is always on (disabling is not possible).}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/s3_tags
@desc Request list of all assigned S3 tags to the room
@required {room_id: int(int64) # Room ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/rooms/{room_id}/s3_tags
@desc Set S3 tags for a room
@required {room_id: int(int64) # Room ID, ids: [int(int64)] # List of S3 tag IDs}
@returns(201) {items: [map]} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/keypairs
@desc Request all room rescue key pairs
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) OK
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/rooms/{room_id}/keypairs
@desc Create key pair and preserve copy of old private key
@required {room_id: int(int64) # Room ID, privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container, previousPrivateKey: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/keypair
@desc Request room rescue key
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), version: str # Version (NEW)}
@returns(200) {privateKeyContainer: map{version: str, privateKey: str, createdAt: str(date-time), createdBy: int(int64)}, publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/rooms/{room_id}/keypair
@desc Set room's rescue key pair
@required {room_id: int(int64) # Room ID, privateKeyContainer: map{version!: str, privateKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Private key container, publicKeyContainer: map{version!: str, publicKey!: str, createdAt: str(date-time), createdBy: int(int64)} # Public key container}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/rooms/{room_id}/keypair
@desc Remove rooms's rescue key pair
@required {room_id: int(int64) # Room ID}
@optional {version: str # Version (NEW)}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/folders
@desc Create new folder
@required {parentId: int(int64) # Parent node ID (room or folder), name: str # Name}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), notes: str # User notes  Use empty string to remove., classification: int(int32)(1/2/3/4) # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential    Provided (or default) classification is taken from room  when file gets uploaded without any classification., timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format)}
@returns(201) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint POST /v4/nodes/files/{file_id}/downloads
@desc Generate download URL
@required {file_id: int(int64) # File ID}
@returns(200) {downloadUrl: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/files/uploads
@desc Create new file upload channel
@required {parentId: int(int64) # Parent node ID (room or folder), name: str # File name}
@optional {classification: int(int32)(1/2/3/4) # Classification ID:  * `1` - public  * `2` - internal  * `3` - confidential  * `4` - strictly confidential    (default: classification from parent room), size: int(int64) # File size in byte, expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information, notes: str # User notes  Use empty string to remove., directS3Upload: bool=false # Upload direct to S3, timestampCreation: str(date-time) # Time the node was created on external file system  (default: current server datetime in UTC format), timestampModification: str(date-time) # Time the content of a node was last modified on external file system  (default: current server datetime in UTC format)}
@returns(201) {uploadUrl: str, uploadId: str, token: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint POST /v4/nodes/files/uploads/{upload_id}/s3_urls
@desc Generate presigned URLs for S3 file upload
@required {upload_id: str # Upload channel ID, size: int(int64) # `Content-Length` header size for each presigned URL (in bytes)  *MUST* be >= 5 MB except the last part., firstPartNumber: int(int32) # First part number of a range of requested presigned URLs (for S3 it is: `1`), lastPartNumber: int(int32) # Last part number of a range of requested presigned URLs}
@returns(201) {urls: [map]} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 504: Gateway Timeout, 507: Insufficient Storage}

@endpoint POST /v4/nodes/files/keys
@desc Set file keys for a list of users and files
@required {items: [map{fileId!: int(int64), userId!: int(int64), fileKey!: map}] # List of user file keys}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/nodes/files/generate_verdict_info
@desc Generate Virus Protection Verdict Information
@required {nodeIds: [int(int64)] # List of node IDs}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 402: Payment Required, 403: Forbidden, 404: Not Found, 412: Precondition Failed}

@endpoint POST /v4/nodes/deleted_nodes/actions/restore
@desc Restore deleted nodes
@required {deletedNodeIds: [int(int64)] # List of deleted node IDs}
@optional {resolutionStrategy: str(autorename/overwrite/fail)=autorename # Node conflict resolution strategy:  * `autorename`  * `overwrite`  * `fail`, keepShareLinks: bool=false # Preserve Download Share Links and point them to the new node., parentId: int(int64) # Node parent ID  (default: previous parent ID)}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 507: Insufficient Storage}

@endgroup

@group groups
@endpoint GET /v4/groups
@desc Request list of user groups
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/groups
@desc Create new user group
@required {name: str # Group name}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), expiration: map{enableExpiration!: bool, expireAt: str(date-time)} # Expiration information}
@returns(201) {id: int(int64), name: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, cntUsers: int(int32), updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), groupRoles: map{items: [map]}} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed}

@endpoint GET /v4/groups/{group_id}/users
@desc Request group member users or / and users who can become a member
@required {group_id: int(int64) # Group ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/groups/{group_id}/users
@desc Add group members
@required {group_id: int(int64) # Group ID, ids: [int(int64)] # List of user IDs}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, cntUsers: int(int32), updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), groupRoles: map{items: [map]}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/groups/{group_id}/users
@desc Remove group members
@required {group_id: int(int64) # Group ID, ids: [int(int64)] # List of user IDs}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, cntUsers: int(int32), updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), groupRoles: map{items: [map]}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group datev
@endpoint GET /v4/datev/mst/{config_id}/taxyears
@desc Request all addable Datev MST tax years
@required {config_id: int(int64) # Configuration ID}
@returns(200) {years: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/datev/mst/{config_id}/taxyears
@desc Create new Datev MST tax year
@required {config_id: int(int64) # Configuration ID, taxYear: str # Datev tax year}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/datev/mst/{config_id}/sync
@desc Execute Datev MST sync
@required {config_id: int(int64) # Configuration ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/datev/mst/authorization/start
@desc Start Datev MST authorization
@required {roomId: int(int64) # Room ID, consultantId: int(int64) # Datev Consultant ID, clientId: int(int64) # Datev Client ID, baseId: int(int64) # Datev Base ID}
@returns(200) {url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 502: Bad Gateway}

@endpoint POST /v4/datev/mst/authorization/complete
@desc Complete Datev MST authorization
@required {state: str # OAuth State, code: str # OAuth Code}
@returns(200) {id: int(int64), datevIntegration: int(int32), roomId: int(int64), consultantId: int(int64), clientId: int(int64), baseId: int(int64), authorizingUserId: int(int64), authorizingUserName: str, refreshTokenExpireAt: str(date-time), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 502: Bad Gateway}

@endpoint POST /v4/datev/duo/{config_id}/sync
@desc Execute Datev DUO sync
@required {config_id: int(int64) # Configuration ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint POST /v4/datev/duo/authorization/start
@desc Start Datev DUO authorization
@required {roomId: int(int64) # Room ID, consultantId: int(int64) # Datev Consultant ID, clientId: int(int64) # Datev Client ID}
@returns(200) {url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 502: Bad Gateway}

@endpoint POST /v4/datev/duo/authorization/complete
@desc Complete Datev DUO authorization
@required {state: str # OAuth State, code: str # OAuth Code}
@returns(200) {id: int(int64), datevIntegration: int(int32), roomId: int(int64), consultantId: int(int64), clientId: int(int64), baseId: int(int64), authorizingUserId: int(int64), authorizingUserName: str, refreshTokenExpireAt: str(date-time), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 409: Conflict, 412: Precondition Failed, 502: Bad Gateway}

@endgroup

@group auth
@endpoint POST /v4/auth/reset_password
@desc Request password reset
@optional {userName: str # Username, creatorLanguage: str # IETF language tag, language: str # Language ID or ISO 639-1 code, login: str # User login name}
@returns(204) No Content
@errors {400: Bad Request, 406: Not Acceptable}

@endpoint POST /v4/auth/recover_username
@desc Recover username
@required {email: str # Email}
@optional {creatorLanguage: str # IETF language tag}
@returns(204) No Content
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endgroup

@group users
@endpoint GET /v4/users/{user_id}/rooms
@desc Request rooms granted to the user or / and rooms that can be granted
@required {user_id: int(int64) # User ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/users/{user_id}/roles
@desc Request user's granted roles
@required {user_id: int(int64) # User ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/users/{user_id}/last_admin_rooms
@desc Request rooms where the user is last admin
@required {user_id: int(int64) # User ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/users/{user_id}/groups
@desc Request groups that user is a member of or / and can become a member
@required {user_id: int(int64) # User ID}
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group user
@endpoint GET /v4/user/ping
@desc (authenticated) Ping
@returns(200) OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/user/oauth/authorizations
@desc Request list of OAuth client authorizations
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), filter: str # Filter string, sort: str # Sort string}
@returns(200) OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/oauth/approvals
@desc Request list of OAuth client approvals
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), sort: str # Sort string}
@returns(200) OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/notifications/config
@desc Request list of notification configurations
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account/mfa
@desc Request information about the user's mfa status
@returns(200) {mfaEnforced: bool, mfaSetups: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/account/mfa
@desc Using emergency-code
@required {emergency_code: str}
@returns(200) OK
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/user/account/customer/keypair
@desc Request customer's key pair
@returns(200) {privateKeyContainer: map{version: str, privateKey: str, createdAt: str(date-time), createdBy: int(int64)}, publicKeyContainer: map{version: str, publicKey: str, createdAt: str(date-time), createdBy: int(int64)}} # OK
@errors {401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group system
@endpoint GET /v4/system/config/storage/s3/tags/{id}
@desc Request S3 tag
@required {id: int(int64) # S3 tag ID}
@returns(200) {id: int(int64), key: str, value: str, isMandatory: bool} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/system/config/storage/s3/tags/{id}
@desc Remove S3 tag
@required {id: int(int64) # S3 tag ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/settings/infrastructure
@desc Request infrastructure properties
@returns(200) {smsConfigEnabled: bool, mediaServerConfigEnabled: bool, s3DefaultRegion: str, s3EnforceDirectUpload: bool, isDracoonCloud: bool, tenantUuid: str} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/system/config/policies/passwords/{password_type}
@desc Request password policies for a certain password type
@required {password_type: str(login/encryption/shares) # Password type}
@returns(200) {loginPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map{enabled: bool, maxPasswordAge: int(int32)}, userLockout: map{enabled: bool, maxNumberOfLoginFailures: int(int32), lockoutPeriod: int(int32)}, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, sharesPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, encryptionPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group shares
@endpoint GET /v4/shares/uploads/{share_id}/qr
@desc Request Upload Share via QR Code
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, targetId: int(int64), isProtected: bool, accessKey: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), targetPath: str, isEncrypted: bool, notes: str, internalNotes: str, filesExpiryPeriod: int(int32), cntFiles: int(int32), cntUploads: int(int32), showUploadedFiles: bool, dataUrl: str, maxSlots: int(int32), maxSize: int(int64), targetType: str, showCreatorName: bool, showCreatorUsername: bool, notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/shares/downloads/{share_id}/qr
@desc Request Download Share via QR Code
@required {share_id: int(int64) # Share ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), name: str, nodeId: int(int64), accessKey: str, cntDownloads: int(int32), createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, notes: str, internalNotes: str, showCreatorName: bool, showCreatorUsername: bool, isProtected: bool, expireAt: str(date-time), maxDownloads: int(int32), nodePath: str, dataUrl: str, isEncrypted: bool, nodeType: str, hideDownload: bool, classification: int(int32), notifyCreator: bool, recipients: str, smsRecipients: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group settings
@endpoint GET /v4/settings/webhooks/event_types
@desc Request list of event types
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group roles
@endpoint GET /v4/roles
@desc Request all roles with assigned rights
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group resources
@endpoint GET /v4/resources/users/{user_id}/avatar/{uuid}
@desc Request user avatar
@required {uuid: str # UUID of the avatar, user_id: int(int64) # User ID}
@returns(200) {avatarUri: str, avatarUuid: str, isCustomAvatar: bool} # OK
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/resources/user/notifications/scopes
@desc Request list of subscription scopes
@returns(200) {items: [map]} # OK
@errors {406: Not Acceptable}

@endgroup

@group public
@endpoint GET /v4/public/time
@desc Request system time
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {time: str(date-time)} # OK
@errors {406: Not Acceptable}

@endpoint GET /v4/public/system/info
@desc Request system information
@optional {is_enabled: bool # Show only enabled authentication methods}
@returns(200) {languageDefault: str, hideLoginInputFields: bool, s3Hosts: [str], s3EnforceDirectUpload: bool, useS3Storage: bool, authMethods: [map]} # OK
@errors {400: Bad Request, 406: Not Acceptable}

@endpoint GET /v4/public/system/info/auth/openid
@desc Request OpenID Connect provider authentication information
@optional {is_global_available: bool # Show only global available items}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 406: Not Acceptable}

@endpoint GET /v4/public/system/info/auth/ad
@desc Request Active Directory authentication information
@optional {is_global_available: bool # Show only global available items}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 406: Not Acceptable}

@endpoint GET /v4/public/software/version
@desc Request software version information
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {restApiVersion: str, sdsServerVersion: str, version: str, buildDate: str(date-time), scmRevisionNumber: str, isDracoonCloud: bool} # OK
@errors {406: Not Acceptable}

@endpoint GET /v4/public/software/third_party_dependencies
@desc Request third-party software dependencies
@returns(200) OK
@errors {406: Not Acceptable}

@endgroup

@group provisioning
@endpoint GET /v4/provisioning/webhooks/event_types
@desc Request list of event types
@optional {X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/provisioning/customers/{customer_id}/users
@desc Request list of customer users
@required {customer_id: int(int64) # Customer ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string, include_attributes: bool # Include custom user attributes., include_roles: bool # Include roles, include_manageable_rooms: bool # Include hasManageableRooms (deprecated), X-Sds-Service-Token: str # Service Authentication token}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endgroup

@group nodes
@endpoint GET /v4/nodes
@desc Request list of nodes
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), depth_level: int(int32) # * `0` - top level nodes only  * `n` (any positive number) - include `n` levels starting from the current node, parent_id: int(int64) # Parent node ID.  Only rooms and folders can be parents.  Parent ID `0` or empty is the root node., room_manager: bool # Show all rooms for management perspective.  Only possible for _Rooms Managers_ / _Room Admins_.  For all other users, it will be ignored., filter: str # Filter string, sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., show_subscription: bool # Show subscription information (default: false)}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request * [-80024] Invalid range parameters, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes
@desc Remove nodes
@required {nodeIds: [int(int64)] # List of node IDs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/{node_id}
@desc Request node
@required {node_id: int(int64) # Node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), referenceId: int(int64), type: str, name: str, timestampCreation: str(date-time), timestampModification: str(date-time), parentId: int(int64), parentPath: str, createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, expireAt: str(date-time), hash: str, fileType: str, mediaType: str, size: int(int64), classification: int(int32), notes: str, permissions: map{manage: bool, read: bool, create: bool, change: bool, delete: bool, manageDownloadShare: bool, manageUploadShare: bool, readRecycleBin: bool, restoreRecycleBin: bool, deleteRecycleBin: bool}, inheritPermissions: bool, isEncrypted: bool, encryptionInfo: map{userKeyState: str, roomKeyState: str, dataSpaceKeyState: str}, cntDeletedVersions: int(int32), cntComments: int(int32), cntDownloadShares: int(int32), cntUploadShares: int(int32), recycleBinRetentionPeriod: int(int32), hasActivitiesLog: bool, quota: int(int64), isFavorite: bool, isSubscribed: bool, branchVersion: int(int64), mediaToken: str, isBrowsable: bool, cntRooms: int(int32), cntFolders: int(int32), cntFiles: int(int32), authParentId: int(int64), cntChildren: int(int32), children: [map], virusProtectionInfo: map{verdict: str, lastCheckedAt: str(date-time), sha256: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/{node_id}
@desc Remove node
@required {node_id: int(int64) # Node ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/{node_id}/parents
@desc Request list of parent nodes
@required {node_id: int(int64) # Node ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/{node_id}/deleted_nodes
@desc Request list of deleted nodes
@required {node_id: int(int64) # Parent ID (can only be a room ID)}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), filter: str # Filter string, sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`).}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/{node_id}/deleted_nodes
@desc Empty recycle bin
@required {node_id: int(int64) # Room ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed, 507: Insufficient Storage}

@endpoint GET /v4/nodes/{node_id}/deleted_nodes/versions
@desc Request deleted versions of nodes
@required {node_id: int(int64) # Parent ID (room or folder ID), type: str # Node type, name: str # Node name}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`).}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/search
@desc Search nodes
@required {search_string: str # Search string}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), depth_level: int(int32) # * `0` - top level nodes only (default)  * `-1` - full tree  * `n` (any positive number) - include `n` levels starting from the current node, parent_id: int(int64) # Parent node ID.  Only rooms and folders can be parents.  Parent ID `0` or empty is the root node., filter: str # Filter string, sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., show_subscription: bool # Show subscription information (default: false)}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/rooms/{room_id}/events
@desc Request events of a room
@required {room_id: int(int64) # Room ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., date_start: str # Filter events from given date   e.g. `2015-12-31T23:59:00`, date_end: str # Filter events until given date   e.g. `2015-12-31T23:59:00`, type: int(int32) # Operation ID   cf. `GET /eventlog/operations`, user_id: int(int64) # User ID, status: int(int32) # Operation status:  * `0` - Success  * `2` - Error}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/missingFileKeys
@desc Request files without user's file key
@optional {offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., room_id: int(int64) # Room ID, file_id: int(int64) # File ID, user_id: int(int64) # User ID, use_key: str(room_rescue_key/system_rescue_key/previous_user_key/previous_room_rescue_key/previous_system_rescue_key) # Determines which key should be used (NEW)}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map], users: [map], files: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/files/{file_id}/user_file_key
@desc Request user's file key
@required {file_id: int(int64) # File ID}
@optional {version: str # Version (NEW)}
@returns(200) {key: str, iv: str, version: str, tag: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/files/{file_id}/data_space_file_key
@desc Request system rescue key
@required {file_id: int(int64) # File ID}
@optional {version: str # Version (NEW)}
@returns(200) {key: str, iv: str, version: str, tag: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/files/{file_id}/data_room_file_key
@desc Request room rescue key
@required {file_id: int(int64) # File ID}
@optional {version: str # Version (NEW)}
@returns(200) {key: str, iv: str, version: str, tag: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/nodes/files/versions/{reference_id}
@desc Request list of file versions
@required {reference_id: int(int64) # Reference ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`).}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {401: Unauthorized, 412: Precondition Failed}

@endpoint GET /v4/nodes/deleted_nodes/{deleted_node_id}
@desc Request deleted node
@required {deleted_node_id: int(int64) # Deleted node ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/))}
@returns(200) {id: int(int64), referenceId: int(int64), parentId: int(int64), parentPath: str, type: str, name: str, expireAt: str(date-time), accessedAt: str(date-time), isEncrypted: bool, notes: str, size: int(int64), classification: int(int32), createdAt: str(date-time), createdBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, updatedAt: str(date-time), updatedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}, deletedAt: str(date-time), deletedBy: map{id: int(int64), userType: str, avatarUuid: str, userName: str, firstName: str, lastName: str, email: str, title: str, displayName: str}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group groups
@endpoint GET /v4/groups/{group_id}/rooms
@desc Request rooms granted to the group or / and rooms that can be granted
@required {group_id: int(int64) # Group ID}
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/groups/{group_id}/roles
@desc Request list of roles assigned to the group
@required {group_id: int(int64) # Group ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/groups/{group_id}/last_admin_rooms
@desc Request rooms where the group is defined as last admin group
@required {group_id: int(int64) # Group ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group eventlog
@endpoint GET /v4/eventlog/operations
@desc Request allowed Log Operations
@optional {is_deprecated: bool # Show only deprecated operations}
@returns(200) {operationList: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/eventlog/events
@desc Request system events
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), sort: str # Sort string, offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., date_start: str # Filter events from given date   e.g. `2015-12-31T23:59:00`, date_end: str # Filter events until given date   e.g. `2015-12-31T23:59:00`, type: int(int32) # Operation ID   cf. `GET /eventlog/operations`, user_id: int(int64) # User ID, status: str(0/2) # Operation status:  * `0` - Success  * `2` - Error, user_client: str # User client}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/eventlog/audits/nodes
@desc Request node assigned users with permissions
@optional {X-Sds-Date-Format: str(UTC/LOCAL/OFFSET/EPOCH/LEET) # Date time format (cf. [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) & [leettime.de](http://leettime.de/)), offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/eventlog/audits/node_info
@desc Request nodes
@optional {parent_id: int(int64) # Parent node ID.  Only rooms can be parents.  Parent ID `0` or empty is the root node., offset: int(int32) # Range offset, limit: int(int32) # Range limit.  Maximum 500.   For more results please use paging (`offset` + `limit`)., filter: str # Filter string, sort: str # Sort string}
@returns(200) {range: map{offset: int(int64), limit: int(int64), total: int(int64)}, items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group downloads
@endpoint GET /v4/downloads/zip/{token}
@desc Download ZIP archive
@required {token: str # Download token}
@returns(200) OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable}

@endpoint GET /v4/downloads/avatar/{user_id}/{uuid}
@desc Download avatar
@required {user_id: int(int64) # User ID, uuid: str # UUID of the avatar}
@returns(200) OK
@errors {400: Bad Request, 404: Not Found, 406: Not Acceptable}

@endgroup

@group datev
@endpoint GET /v4/datev
@desc Request Datev sync configuration for room
@required {room_id: int(int64) # Room ID}
@returns(200) {id: int(int64), datevIntegration: int(int32), roomId: int(int64), consultantId: int(int64), clientId: int(int64), baseId: int(int64), authorizingUserId: int(int64), authorizingUserName: str, refreshTokenExpireAt: str(date-time), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/mst
@desc Request list of Datev MST sync configurations
@optional {room_id: int(int64) # Room ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/mst/{config_id}
@desc Request Datev MST sync configuration
@required {config_id: int(int64) # Configuration ID}
@returns(200) {id: int(int64), datevIntegration: int(int32), roomId: int(int64), consultantId: int(int64), clientId: int(int64), baseId: int(int64), authorizingUserId: int(int64), authorizingUserName: str, refreshTokenExpireAt: str(date-time), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/datev/mst/{config_id}
@desc Remove Datev MST sync configuration
@required {config_id: int(int64) # Configuration ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/mst/{config_id}/files
@desc Request information about Datev MST sync files
@required {config_id: int(int64) # Configuration ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/mst/{config_id}/files/{file_id}
@desc Request information about a Datev MST sync file
@required {config_id: int(int64) # Configuration ID, file_id: int(int64) # File ID}
@returns(200) {syncConfigId: int(int64), fileId: int(int64), datevFileId: str, uploadStatus: str, uploadStartedAt: str(date-time), uploadCompletedAt: str(date-time), uploadErrorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/duo
@desc Request list of Datev DUO sync configurations
@optional {room_id: int(int64) # Room ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/duo/{config_id}
@desc Request Datev DUO sync configuration
@required {config_id: int(int64) # Configuration ID}
@returns(200) {id: int(int64), datevIntegration: int(int32), roomId: int(int64), consultantId: int(int64), clientId: int(int64), baseId: int(int64), authorizingUserId: int(int64), authorizingUserName: str, refreshTokenExpireAt: str(date-time), errorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/datev/duo/{config_id}
@desc Remove Datev DUO sync configuration
@required {config_id: int(int64) # Configuration ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/duo/{config_id}/files
@desc Request information about Datev DUO sync files
@required {config_id: int(int64) # Configuration ID}
@returns(200) {items: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/datev/duo/{config_id}/files/{file_id}
@desc Request information about a Datev DUO sync file
@required {config_id: int(int64) # Configuration ID, file_id: int(int64) # File ID}
@returns(200) {syncConfigId: int(int64), fileId: int(int64), datevFileId: str, uploadStatus: str, uploadStartedAt: str(date-time), uploadCompletedAt: str(date-time), uploadErrorDetails: map{code: int(int32), message: str, debugInfo: str, errorCode: int(int32)}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group config
@endpoint GET /v4/config/info/s3_tags
@desc Request list of configured S3 tags
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/product_packages
@desc Request list of product packages
@returns(200) {packages: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/product_packages/current
@desc Request list of currently enabled product packages
@returns(200) {packages: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/policies/virus_protection
@desc Request virus protection
@returns(200) {isVirusProtectionEnabled: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/config/info/policies/passwords
@desc Request password policies
@returns(200) {loginPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, numberOfArchivedPasswords: int(int32), passwordExpiration: map{enabled: bool, maxPasswordAge: int(int32)}, userLockout: map{enabled: bool, maxNumberOfLoginFailures: int(int32), lockoutPeriod: int(int32)}, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, sharesPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectDictionaryWords: bool, rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}, encryptionPasswordPolicies: map{characterRules: map{mustContainCharacters: [str], numberOfCharacteristicsToEnforce: int(int32)}, minLength: int(int32), rejectUserInfo: bool, rejectKeyboardPatterns: bool, updatedAt: str(date-time), updatedBy: map{id: int(int64)}}} # OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/config/info/policies/guest_users
@desc Request guest users policies
@returns(200) {isInviteUsersEnabled: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/config/info/policies/classifications
@desc Request classification policies
@returns(200) {shareClassificationPolicies: map{classificationRequiresSharePassword: int(int32)}} # OK
@errors {401: Unauthorized, 406: Not Acceptable}

@endpoint GET /v4/config/info/policies/algorithms
@desc Request algorithms
@returns(200) {fileKeyAlgorithms: [map], keyPairAlgorithms: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/notifications/channels
@desc Request list of notification channels
@returns(200) {items: [map]} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/infrastructure
@desc Request infrastructure properties
@returns(200) {smsConfigEnabled: bool, mediaServerConfigEnabled: bool, s3DefaultRegion: str, s3EnforceDirectUpload: bool, isDracoonCloud: bool, tenantUuid: str} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/general
@desc Request general settings
@returns(200) {sharePasswordSmsEnabled: bool, cryptoEnabled: bool, emailNotificationButtonEnabled: bool, eulaEnabled: bool, useS3Storage: bool, s3TagsEnabled: bool, hideLoginInputFields: bool, authTokenRestrictions: map{restrictionEnabled: bool, accessTokenValidity: int(int32), refreshTokenValidity: int(int32)}, mediaServerEnabled: bool, weakPasswordEnabled: bool, homeRoomsActive: bool, homeRoomParentId: int(int64), subscriptionPlan: int(int32)} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endpoint GET /v4/config/info/defaults
@desc Request default values
@returns(200) {languageDefault: str, downloadShareDefaultExpirationPeriod: int(int32), uploadShareDefaultExpirationPeriod: int(int32), fileDefaultExpirationPeriod: int(int32), globalRecycleBinRetentionPeriod: int(int32), globalRecycleBinRetentionPeriodLegacy: int(int32), nonmemberViewerDefault: bool, hideLoginInputFields: bool} # OK
@errors {401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group users
@endpoint DELETE /v4/users/{user_id}/userAttributes/{key}
@desc Remove custom user attribute
@required {user_id: int(int64) # User ID, key: str # Key}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/users/{user_id}/mfa
@desc Reset MFA for user
@required {user_id: int(int64)}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group user
@endpoint DELETE /v4/user/profileAttributes/{key}
@desc Remove user profile attribute
@required {key: str # Key}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/oauth/authorizations/{client_id}
@desc Remove all OAuth authorizations of a client
@required {client_id: str # OAuth client ID}
@returns(204) No Content
@errors {401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/oauth/authorizations/{client_id}/{authorization_id}
@desc Remove a OAuth authorization
@required {client_id: str # OAuth client ID, authorization_id: int(int64) # OAuth authorization ID}
@returns(204) No Content
@errors {401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/oauth/approvals/{client_id}
@desc Remove OAuth client approval
@required {client_id: str # OAuth client ID}
@returns(204) No Content
@errors {401: Unauthorized, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/user/account/mfa/totp/{id}
@desc Disable a MFA TOTP setup with generated OTP
@required {id: int(int64), valid_otp: str}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@group provisioning
@endpoint DELETE /v4/provisioning/customers/{customer_id}/customerAttributes/{key}
@desc Remove customer attribute
@required {customer_id: int(int64) # Customer ID, key: str # Key}
@optional {X-Sds-Service-Token: str # Service Authentication token}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 404: Not Found, 406: Not Acceptable}

@endgroup

@group nodes
@endpoint DELETE /v4/nodes/{node_id}/node_attributes/{key}
@desc Remove custom node attribute
@required {node_id: int(int64) # Node ID, key: str # Key}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/malicious_files/{malicious_file_id}
@desc Remove malicious File
@required {malicious_file_id: int(int64) # Malicious file ID}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endpoint DELETE /v4/nodes/deleted_nodes
@desc Remove nodes from recycle bin
@required {deletedNodeIds: [int(int64)] # List of deleted node IDs}
@returns(204) No Content
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found, 406: Not Acceptable, 412: Precondition Failed}

@endgroup

@end
