@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api ExaVault API
@base https://accountname.exavault.com/api/v2
@version 2.0
@auth ApiKey ev-api-key in header
@common_fields {ev-api-key: str # API Key required to make the API call., ev-access-token: str # Access token required to make the API call.}
@endpoints 59
@hint download_for_search
@toc email-lists(5), forms(5), activity(2), notifications(5), users(5), resources(15), account(2), email(2), shares(6), recipients(1), ssh-keys(4), webhooks(7)

@group email-lists
@endpoint GET /email-lists
@desc Get all email groups
@optional {include: str # Related record types to include in the response. Valid option is `ownerUser`}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [map]} # Successful operation

@endpoint POST /email-lists
@desc Create new email list
@required {name: str # Name of the email list., emails: [str] # Array of email addresses to include in the email list.}
@returns(201) {responseStatus: int(int32), data: map{id: int, type: str, attributes: map{name: str, emails: [str], created: str(date-time), modified: str(date-time)}, relationships: map{ownerUser: map{data: map}}}, included: [map]} # Successful operation
@example_request {"value":{"name":"ExaVault Test","emails":["exavault@example.com","exavault+1@example.com"]}}

@endpoint GET /email-lists/{id}
@desc Get individual email group
@required {id: int # ID of the email list to return.}
@optional {include: str # Related record types to include in the response. Valid option is `ownerUser`}
@returns(200) {responseStatus: int(int32), data: map{id: int, type: str, attributes: map{name: str, emails: [str], created: str(date-time), modified: str(date-time)}, relationships: map{ownerUser: map{data: map}}}, included: [map]} # Successful Operation

@endpoint PATCH /email-lists/{id}
@desc Update an email group
@required {id: int # ID of the email list to update.}
@optional {name: str # Name of the email list., emails: [str] # Email addresses that replace existing list.}
@returns(200) {responseStatus: int(int32), data: map{id: int, type: str, attributes: map{name: str, emails: [str], created: str(date-time), modified: str(date-time)}, relationships: map{ownerUser: map{data: map}}}, included: [map]} # Successful Operation
@example_request {"name":"Renamed Test Email List","emails":["test@example.com","test+1@example.com","newaddress@example.com"]}

@endpoint DELETE /email-lists/{id}
@desc Delete an email group with given id
@required {id: int # ID of the email list to delete}
@returns(200) {responseStatus: int, data: [str]} # Successful Operation

@endgroup

@group forms
@endpoint GET /forms
@desc Get receive folder form settings
@required {shareHash: str # Share hash to retrieve the form for.}
@optional {include: str # Related record types to include in the response. Valid option is **share**}
@returns(200) {responseStatus: int, data: map{type: str, id: int(int32), attributes: map{formDescription: str, submitButtonText: str, successMessage: str, cssStyles: str, elements: [map]}, relationships: map{share: map{data: map}}}, included: [map]} # successful operation

@endpoint GET /forms/{id}
@desc Get receive folder form by Id
@optional {include: str # Enter "**share**" to get information about associated receive folder.}
@returns(200) {responseStatus: int, data: map{type: str, id: int(int32), attributes: map{formDescription: str, submitButtonText: str, successMessage: str, cssStyles: str, elements: [map]}, relationships: map{share: map{data: map}}}, included: [map]} # successful operation

@endpoint PATCH /forms/{id}
@desc Updates a form with given parameters
@optional {formDescription: str # Set a description for the form that will be visible to recipients., submitButtonText: str # Text to be displayed on the submission button., successMessage: str # Text to be displayed when a recipient has submitted the form., elements: [map{id: int, name: str, order: int, type: str, settings: map}], cssStyles: str}
@returns(200) {responseStatus: int, data: map{type: str, id: int(int32), attributes: map{formDescription: str, submitButtonText: str, successMessage: str, cssStyles: str, elements: [map]}, relationships: map{share: map{data: map}}}, included: [map]} # Successful Operation
@example_request {"formDescription":"hello world","submitButtonText":"goodbye world","successMessage":"thank you","elements":[{"name":"Name","order":0,"type":"name","settings":{"isRequired":true,"senderEmail":false,"useAsFolderName":false,"description":"this is a description test","width":1}},{"id":2331,"name":"Email Address","order":1,"type":"email","settings":{"isRequired":true,"senderEmail":false,"useAsFolderName":false,"description":null,"width":1}},{"id":2333,"name":"Subject","order":2,"type":"text","settings":{"isRequired":true,"senderEmail":false,"useAsFolderName":false,"description":null,"width":1}},{"id":2335,"name":"Message","order":3,"type":"textarea","settings":{"isRequired":false,"senderEmail":false,"useAsFolderName":false,"description":null,"width":1}},{"id":2337,"name":"Upload Area","order":4,"type":"upload_area","settings":{"isRequired":false,"senderEmail":false,"useAsFolderName":false,"description":null,"width":1}}]}

@endpoint GET /forms/entries/{id}
@desc Get form data entries for a receive
@required {id: int # ID of the form to retrieve entries for.}
@optional {limit: int # Limit of records to be returned (for pagination), offset: int # Current offset of records (for pagination)}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map]} # Successful operation

@endpoint DELETE /forms/entries/{id}
@desc Delete a receive form submission
@required {id: int(int64) # ID of the entry to be deleted data for}
@returns(200) {responseStatus: int, data: [str]} # Successful operation

@endgroup

@group activity
@endpoint GET /activity/session
@desc Get activity logs
@optional {startDate: str(date-time) # Start date of the filter data range, endDate: str(date-time) # End date of the filter data range, ipAddress: str # Used to filter session logs by ip address., username: str # Username used for filtering a list, path: str # Path used to filter records, type: str # Filter session logs for operation type (see table above for acceptable values), offset: int # Offset of the records list, limit: int # Limit of the records list, sort: str # Comma separated list sort params}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map]} # Successful operation

@endpoint GET /activity/webhooks
@desc Get webhook logs
@optional {startDate: str(date-time) # Earliest date of entries to include in list, endDate: str(date-time) # Latest date of entries to include in list, endpointUrl: str(uri) # Webhook listener endpoint, event: str # Type of activity that triggered the webhook attempt, statusCode: int # Response code from the webhook endpoint, resourcePath: str # Path of the resource that triggered the webhook attempt, username: str # Filter by triggering username., offset: int # Records to skip before returning results., limit: int # Limit of the records list, sort: str # Comma separated list sort params}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map]} # Successful operation

@endgroup

@group notifications
@endpoint PATCH /notifications/{id}
@desc Update a notification
@required {id: int # ID of the notification. Use [GET /notifications](#operation/listNotifications) if you need to lookup an ID.}
@optional {action: str(upload/download/delete/all) # Type of action be notified about. Notifications will only be sent for the given type of action. Valid choices are **upload**, **download**, **delete** or **all** (upload/download/delete), usernames: [str] # Determines which users' actions should trigger the notification.   Rather than listing  individual users, you can also use 3 special options:  - **notice\_user\_all** for activity by any user or share recipient - **notice\_user\_all\_users** for activity only by user accounts - **notice\_user\_all\_recipients** for activity only by share recipients, sendEmail: bool # Whether an email should be sent to the recipients when matching activity happens., recipients: [str(email)] # Email addresses to send notification emails to. If empty, sends to the current user's email address., message: str # Custom message to insert into the notification emails, along with the matching activity.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{userId: str, type: str, path: str, name: str, action: str, usernames: [str], recipients: [map], sendEmail: bool, readableDescription: str, readableDescriptionWithoutPath: str, shareId: str, message: str, created: str(date-time), modified: str(date-time)}, relationships: map{resource: map{data: map}, share: map{data: map}, ownerUser: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"action":"upload","usernames":["notice_user_all_recipients"],"sendEmail":"true","emails":["exavault@example.com","exavault+1@example.com"]}

@endpoint GET /notifications/{id}
@desc Get notification details
@required {id: int # ID of the notification. Use [GET /notifications](#operation/listNotifications) if you need to lookup an ID.}
@optional {include: str # Related record types to include in the response. You can include multiple types by separating them with commas. Valid options are **ownerUser**, **resource**, and **share**.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{userId: str, type: str, path: str, name: str, action: str, usernames: [str], recipients: [map], sendEmail: bool, readableDescription: str, readableDescriptionWithoutPath: str, shareId: str, message: str, created: str(date-time), modified: str(date-time)}, relationships: map{resource: map{data: map}, share: map{data: map}, ownerUser: map{data: map}}}, included: [any]} # Successful Operation

@endpoint DELETE /notifications/{id}
@desc Delete a notification
@required {id: int(int32) # ID of the notification. Use [GET /notifications](#operation/listNotifications) if you need to lookup an ID.}
@returns(200) {responseStatus: int, data: [str]} # Successful Operation

@endpoint POST /notifications
@desc Create a new notification
@required {type: str(file/folder) # What kind of notification you're making. Valid choices are:  - **file** to monitor activity for a file resource - **folder** to monitor activity for a folder resource, resource: str # Resources for this notification. See details on [how to specify resources](#section/Identifying-Resources) above., action: str(upload/download/delete/all) # Type of action be notified about. Notifications will only be fired for the given type of action. Valid choices are **upload**, **download**, **delete** or **all** (upload/download/delete), usernames: [str] # Determines which users' actions should trigger the notification.   Rather than listing  individual users, you can also use 3 special options:  - **notice\_user\_all** for activity by any user or share recipient - **notice\_user\_all\_users** for activity only by user accounts - **notice\_user\_all\_recipient** for activity only by share recipients, sendEmail: bool # Set to true if the user should be notified by email when the notification is triggered.}
@optional {recipients: [str(email)] # Email addresses to send notification emails to. If not specified, sends to the current user's email address., message: str # Custom message to include in notification emails.}
@returns(201) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{userId: str, type: str, path: str, name: str, action: str, usernames: [str], recipients: [map], sendEmail: bool, readableDescription: str, readableDescriptionWithoutPath: str, shareId: str, message: str, created: str(date-time), modified: str(date-time)}, relationships: map{resource: map{data: map}, share: map{data: map}, ownerUser: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"type":"file","resource":"examplefile.txt","action":"upload","usernames":["exavault","exavalut2"],"sendEmail":true,"recipients":["myemail@example.com"],"message":"hello world"}

@endpoint GET /notifications
@desc Get a list of notifications
@optional {type: str(file/folder/shared_folder/send_receipt/share_receipt/file_drop) # Type of notification include in the list. Valid options are **file**, **folder**, **send_receipt**, **share_receipt**, **file_drop**  If this parameter is not used, only **file** and **folder** type notifications are included in the list., offset: int(int32)=0 # Starting notification record in the result set. Can be used for pagination., sort: str # What order the list of matches should be in. Valid sort fields are **resourcename**, **date**, **action** and **type**. The sort order for each sort field is ascending unless it is prefixed with a minus (“-“), in which case it will be descending.  You can chose multiple options for the sort by separating them with commmas, such as "type,-date" to sort by type, then most recent., limit: int(int32)=25 # Number of notification records to return. Can be used for pagination., include: str(resource/share/user) # Related records to include in the response. Valid options are **ownerUser**, **resource**, **share**, action: str(connect/download/upload/delete/all) # The kind of action which triggers the notification. Valid choices are **connect** (only for delivery receipts), **download**, **upload**, **delete**, or **all**   **Note** The **all** action matches notifications set to "all", not all notifications. For example, notifications set to trigger only on delete are not included if you filter for action=all}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation

@endgroup

@group users
@endpoint POST /users
@desc Create a user
@required {username: str # Username of the user to create. This should follow standard username conventions - spaces are not allowed, etc. We do allow email addresses as usernames.  **Note** Usernames must be unique across all ExaVault accounts., homeResource: str # Resource identifier for the user's home folder. See details on [how to specify resources](#section/Identifying-Resources) above.  The user will be locked to this directory and unable to move 'up' in the account. If the folder does not exist in the account, it will be created when the user is created.   Users with the `role` **admin** should have their homeResource set to '/', email: str(email) # Email address for the user, password: str # Password for the user, role: str(user/admin) # The type of user to create, either **user** or **admin**., permissions: map{list: bool, download: bool, upload: bool, modify: bool, delete: bool, changePassword: bool, share: bool, notification: bool, viewFormData: bool, deleteFormData: bool} # An object containing name/value pairs for each permission. Any permission that is not passed will be set to `false` by default. Note that users will be unable to see any files in the account unless you include `list` permission. When creating a user with the `role` **admin**, you should set all of the permissions to `true`, timeZone: str # Time zone, used for accurate time display within the application. See this page for allowed values.}
@optional {nickname: str # An optional nickname (e.g. 'David from Sales')., expiration: str # Optional timestamp when the user should expire, formatted in date-time., locked: bool # If true, the user will not be able to log in, welcomeEmail: bool # If **true**, send this new user a welcome email upon creation. The content of the welcome email can be configured with the [PATCH /accounts](#operation/updateAccount) method., onboarding: bool # Set this to **true** to enable extra help popups in the web file manager for this user.}
@returns(201) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{status: int(int32), locked: bool, expiration: str, created: str(date-time), modified: str(date-time), accessTimestamp: str, accountName: str, username: str, nickname: str, email: str, homePath: str, permissions: map{download: bool, upload: bool, modify: bool, delete: bool, list: bool, changePassword: bool, share: bool, notification: bool, viewFormData: bool, deleteFormData: bool}, role: str, timeZone: str, onboarding: bool, firstLogin: bool}, relationships: map{homeResource: map{data: map}, ownerAccount: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"username":"testuser","nickname":"testnickname","homeResource":"/","email":"testuser@example.com","password":"string","role":"user","permissions":{"list":true,"download":true,"upload":true,"modify":true,"delete":true,"changePassword":true,"share":true,"notification":true,"viewFormData":true,"deleteFormData":true},"timeZone":"America/Los_Angeles","expiration":"2011-03-21 00:18:56","locked":true,"welcomeEmail":true,"onboarding":true}

@endpoint GET /users
@desc Get a list of users
@optional {username: str # The username of the user you are looking for. Only entries with the same username as this will be in the list of results. Does not support wildcard searches., homeResource: str # Resource identifier for user's home directory. Does not support wildcard searches., nickname: str # Nickname to search for. Ignored if `username` is provided. Supports wildcard searches., email: str # Email to search for. Ignored if `username` is provided. Supports wildcard searches, role: str # Types of users to include the list. Ignored if `username` is provided. Valid options are **admin**, **master** and **user**, status: int # Whether a user is locked. Ignored if `username` is provided. **0** means user is locked, **1** means user is not locked., search: str # Searches the nickname, email, role and homeDir fields for the provided value. Ignored if `username` is provided. Supports wildcard searches., offset: int(int32) # Starting user record in the result set. Can be used for pagination., sort: str # Sort order or matching users. You can sort by multiple columns by separating sort options with a comma; the sort will be applied in the order specified. The sort order for each sort field is ascending unless it is prefixed with a minus (“-“), in which case it will be descending.  Valid sort fields are: **nickname**, **username**, **email**, **homeDir** and **modified**, limit: int(int32) # Number of users to return. Can be used for pagination., include: str # Comma separated list of relationships to include in response. Valid options are **homeResource** and **ownerAccount**.}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation

@endpoint GET /users/{id}
@desc Get info for a user
@optional {include: str # Comma-separated list of relationships to include in response. Possible values include **homeResource** and **ownerAccount**.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{status: int(int32), locked: bool, expiration: str, created: str(date-time), modified: str(date-time), accessTimestamp: str, accountName: str, username: str, nickname: str, email: str, homePath: str, permissions: map{download: bool, upload: bool, modify: bool, delete: bool, list: bool, changePassword: bool, share: bool, notification: bool, viewFormData: bool, deleteFormData: bool}, role: str, timeZone: str, onboarding: bool, firstLogin: bool}, relationships: map{homeResource: map{data: map}, ownerAccount: map{data: map}}}, included: [any]} # Successful Operation

@endpoint DELETE /users/{id}
@desc Delete a user
@returns(200) {responseStatus: int, data: [str]} # Successful Operation

@endpoint PATCH /users/{id}
@desc Update a user
@optional {username: str # New username for the user. This should follow standard username conventions - spaces are not allowed, etc. We do allow email addresses as usernames.  **Note** Usernames must be unique across all ExaVault accounts., nickname: str # An optional nickname (e.g. 'David from Sales')., homeResource: str # Resource identifier for the user's home folder. See details on [how to specify resources](#section/Identifying-Resources) above.  The user will be locked to this directory and unable to move 'up' in the account. If the folder does not exist in the account, it will be created when the user logs in.  This setting is ignored for users with the `role` **admin**., email: str(email) # Email address for the user, password: str # New password for the user, role: str(user/admin) # The type of user (**admin** or **user**). Note that admin users cannot have a `homeResource` other than '/', and will have full permissions, but you must provide at least "download,upload,list,delete" in the `permissions` parameter., permissions: map{download!: bool, upload!: bool, modify!: bool, delete!: bool, list!: bool, changePassword!: bool, share!: bool, notification!: bool, viewFormData!: bool, deleteFormData!: bool}, timeZone: str # Time zone, used for accurate time display within the application. See this page for allowed values., expiration: str # Optional timestamp when the user should expire., locked: bool # If true, the user will be prevented from logging in, onboarding: bool # Set this to **true** to enable extra help popups in the web file manager for this user.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{status: int(int32), locked: bool, expiration: str, created: str(date-time), modified: str(date-time), accessTimestamp: str, accountName: str, username: str, nickname: str, email: str, homePath: str, permissions: map{download: bool, upload: bool, modify: bool, delete: bool, list: bool, changePassword: bool, share: bool, notification: bool, viewFormData: bool, deleteFormData: bool}, role: str, timeZone: str, onboarding: bool, firstLogin: bool}, relationships: map{homeResource: map{data: map}, ownerAccount: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"username":"testuser","nickname":"testnickname","homeResource":"/","email":"testuser@example.com","password":"string","role":"user","permissions":{"list":true,"download":true,"upload":true,"modify":true,"delete":true,"changePassword":true,"share":true,"notification":true,"viewFormData":true,"deleteFormData":true},"timeZone":"America/Los_Angeles","expiration":"2011-03-21 00:18:56","locked":true,"onboarding":true}

@endgroup

@group resources
@endpoint GET /resources/list
@desc Get a list of all resources
@required {resource: str # Resource identifier to get resources for. Can be path/id/name.}
@optional {sort: str # Endpoint support multiple sort fields by allowing array of sort params. Sort fields should be applied in the order specified. The sort order for each sort field is ascending unless it is prefixed with a minus (“-“), in which case it will be descending., offset: int(int32)=0 # Determines which item to start on for pagination. Use zero (0) to start at the beginning of the list. e.g, setting `offset=200` would trigger the server to skip the first 200 matching entries when returning the results., limit: int(int32) # The number of files to limit the result. If you have more files in your directory than this limit, make multiple calls, incrementing the `offset` parameter, above., type: str # Limit types of resources returned to "file" or "dir" only. This is ignored if you are using the `name` parameter to trigger a search., name: str # Text to match resource names. This allows you to filter the results returned. For example, to locate only zip archive files, you can enter `*zip` and only resources ending in "zip" will be included in the list of results., include: str # Comma separated list of relationships to include in response. Possible values are **share**, **notifications**, **directFile**, **parentResource**, **ownerUser**, **ownerAccount**.}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation

@endpoint GET /resources/{id}
@desc Get resource metadata
@optional {include: str # Comma separated list of relationships to include in response. Possible values are **share**, **notifications**, **directFile**, **parentResource**, **ownerUser**, **ownerAccount**.}
@returns(200) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful Operation

@endpoint PATCH /resources/{id}
@desc Rename a resource.
@optional {name: str # The new name for the resource (file or folder).}
@returns(200) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful operation
@example_request {"name":"my-renamed-file.txt"}

@endpoint DELETE /resources/{id}
@desc Delete a Resource
@returns(200) {responseStatus: int, data: [str]} # Successful Operation

@endpoint DELETE /resources
@desc Delete Resources
@required {resources: [str] # Resource identifiers of items to delete.}
@returns(200) {responseStatus: int, data: [str]} # Successful Operation
@returns(207) {responses: [any]} # Multi Response
@example_request {"resources":["exampleFile1.txt","exampleFile2.txt"]}

@endpoint POST /resources
@desc Create a folder
@optional {path: str # Fully-qualified path to the new folder including folder's name, name: str # Name of the folder to create. Required if **path** is not used, parentResource: str # Resource identifier where to create a folder. Required if **path** is not used}
@returns(201) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"path":"/exavault/exampleFile.txt"}

@endpoint GET /resources
@desc Get Resource Properties
@required {resource: str # Resource identifier of the file or folder to get metadata for.}
@optional {include: str # Comma separated list of relationships to include in response. Possible values are **share**, **notifications**, **directFile**, **parentResource**, **ownerUser**, **ownerUser**.}
@returns(200) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful Operation

@endpoint GET /resources/list/{id}
@desc List contents of folder
@required {id: int(int64) # ID of the parent resource to get a list of resources for.}
@optional {sort: str # Endpoint support multiple sort fields by allowing array of sort params. Sort fields should be applied in the order specified. The sort order for each sort field is ascending unless it is prefixed with a minus (“-“), in which case it will be descending., offset: int(int32)=0 # Determines which item to start on for pagination. Use zero (0) to start at the beginning of the list., limit: int(int32) # The number of files to limit the result. Cannot be set higher than 100. If you have more than one hundred files in your directory, make multiple calls, incrementing the `offset parameter, above., type: str # Limit types of resources returned to "file" or "dir" only., include: str # Comma separated list of relationships to include in response. Possible values are **share**, **notifications**, **directFile**, **parentResource**, **ownerUser**, **ownerUser**.}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation

@endpoint POST /resources/compress
@desc Compress resources
@required {resources: [str] # Resource identifiers for file(s)/folder(s) to include in new zip file}
@optional {parentResource: str # Resource identifier of the folder where zip archive should be created., archiveName: str # Name of the zip archive to create. If left blank, current date will be used.}
@returns(201) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful Operation
@example_request {"resources":["exampleFile1.txt","exampleFile2.txt","id:234222"],"parentResource":"/exavault","archiveName":"exampleFiles.zip"}

@endpoint POST /resources/extract
@desc Extract resources
@required {resource: str # Resource identifier of zip archive to be extracted., parentResource: str # Resource identifier for folder files should be extracted to.}
@returns(201) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation
@example_request {"resource":"/exavault/exampleFiles.zip","parentResource":"/extractFolder"}

@endpoint POST /resources/copy
@desc Copy resources
@required {resources: [str] # Resource identifier(s) of items to be copied to a new location, parentResource: str # Resource identifier for folder where items will be copied to.}
@returns(200) {data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, meta: map} # Successful Operation
@returns(207) {responses: [any]} # Multi Response
@example_request {"resources":["/exavault/exampleFile.txt","/exavault/otherFile.txt","id:28282828"],"parentResource":"/exavault/exampleFileFolder"}

@endpoint POST /resources/move
@desc Move resources
@required {resources: [str] # Array containing file/folder paths to move., parentResource: str # Resource identifier of folder to move files/folders to.}
@returns(200) {data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, meta: map} # Successful Operation
@returns(207) {responses: [any]} # Multi Response
@example_request {"resources":["/testone.jpg","/folder"],"parentResource":"/copyhere"}

@endpoint GET /resources/preview
@desc Preview a file
@required {resource: str # Resource identifier for the image file., size: str(small/medium/large) # The size of the image.}
@optional {width: int(int32) # Overrides sizes. Sets to a specific width., height: int(int32) # Overrides sizes. Sets to a specific height., page: int(int32)=0 # Page number to extract from a multi-page document (0 is the first page). Vaild for **.pdf** or **.doc** files.}
@returns(200) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{image: str, size: int(int64), imageHash: str, pageCount: int(int32)}}} # Successful Operation

@endpoint POST /resources/upload
@desc Upload a file
@required {path: str # Destination path for the file being uploaded, including the file name., fileSize: int # File size, in bits, of the file being uploaded.}
@optional {offsetBytes: int # Allows a file upload to resume at a certain number of bytes., resume: bool=true # True if upload resume is supported, false if it isn't., allowOverwrite: bool=false # True if a file with the same name is found in the designated path, should be overwritten. False if different file names should be generated.}
@returns(201) {responseStatus: int, data: map{id: int(int64), type: str, attributes: map{hash: str, name: str, extension: str, type: str, createdBy: str, uploadDate: str(date-time), createdAt: str(date-time), updatedAt: str(date-time), accessedAt: str(date-time), createdTime: int(int32), updatedTime: int(int32), accessedTime: int(int32), path: str, size: int(int64), fileCount: int, previewable: bool}, relationships: map{share: map{data: map}, notifications: [map], directFile: map{data: map}, parentResource: map{data: map}}}, included: [any]} # Successful Operation

@endpoint GET /resources/download
@desc Download a file
@required {resources[]: [str] # Path of file or folder to be downloaded, starting from the root. Can also be an array of paths.}
@optional {downloadArchiveName: str # When downloading multiple files, this will be used as the name of the zip file that is created.}
@returns(200) Content of the file

@endgroup

@group account
@endpoint GET /account
@desc Get account settings
@optional {include: str # Related records to include in the response. Valid option is **masterUser**}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{accountName: str, maxUsers: int(int32), userCount: int(int32), status: int(int32), branding: bool, customDomain: bool, quota: map{diskLimit: int(int64), diskUsed: int(int64), noticeEnabled: bool, noticeThreshold: int(int32), bandwidthLimit: int(int64), bandwidthUsed: int(int64), transactionsLimit: int(int32), transactionsNoticeEnabled: bool, transactionsNoticeThreshold: int(int32)}, secureOnly: bool, complexPasswords: bool, showReferralLinks: bool, externalDomains: [str], allowedIp: [map], brandingSettings: map{companyName: str, customEmail: str(email), logo: str, logoExt: str, theme: str, verifiedDomain: str, verifiedDomainId: str, verifiedDomainValid: bool}, planDetails: map{storageAddOn: int, ipWhitelist: bool, userExpiration: bool, userImport: bool, customDomain: bool, customName: bool, colorSchema: bool, apiKeys: int, apiTokens: int, sshKeys: int, directLinks: bool, sharingOptions: [str], webhookOptions: map, unlimitedUsers: bool}, clientId: int(int32), welcomeEmailContent: str, welcomeEmailSubject: str, customSignature: str, accountOnboarding: bool, created: str(date-time), modified: str(date-time)}, relationships: map{masterUser: map{data: map}}}, included: [map]} # Successful operation

@endpoint PATCH /account
@desc Update account settings
@optional {secureOnly: bool # Whether unencrypted FTP connections should be denied for the account., complexPasswords: bool # Whether to require complex passwords for all passwords., showReferralLinks: bool # Whether to display links for others to sign up on share views and invitation emails, externalDomain: str # Custom address used for web file manager. Not available for all account types., emailContent: str # Content of welcome email template., emailSubject: str # Subject line for welcome emails, allowedIpRanges: [map{ipStart: str(ipv4), ipEnd: str(ipv4)}] # IP Address Ranges for restricting account access, brandingSettings: map{companyName: str, customEmail: str(email), theme: str}, accountOnboarding: bool # Whether extra help popups can be enabled for users in the web file manager., customSignature: str # Signature to be automatically added to the bottom of emails generated by the account., quota: map{noticeEnabled: bool, noticeThreshold: int, transactionsNoticeEnabled: bool, transactionsNoticeThreshold: int}}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{accountName: str, maxUsers: int(int32), userCount: int(int32), status: int(int32), branding: bool, customDomain: bool, quota: map{diskLimit: int(int64), diskUsed: int(int64), noticeEnabled: bool, noticeThreshold: int(int32), bandwidthLimit: int(int64), bandwidthUsed: int(int64), transactionsLimit: int(int32), transactionsNoticeEnabled: bool, transactionsNoticeThreshold: int(int32)}, secureOnly: bool, complexPasswords: bool, showReferralLinks: bool, externalDomains: [str], allowedIp: [map], brandingSettings: map{companyName: str, customEmail: str(email), logo: str, logoExt: str, theme: str, verifiedDomain: str, verifiedDomainId: str, verifiedDomainValid: bool}, planDetails: map{storageAddOn: int, ipWhitelist: bool, userExpiration: bool, userImport: bool, customDomain: bool, customName: bool, colorSchema: bool, apiKeys: int, apiTokens: int, sshKeys: int, directLinks: bool, sharingOptions: [str], webhookOptions: map, unlimitedUsers: bool}, clientId: int(int32), welcomeEmailContent: str, welcomeEmailSubject: str, customSignature: str, accountOnboarding: bool, created: str(date-time), modified: str(date-time)}, relationships: map{masterUser: map{data: map}}}, included: [map]} # Successful operation
@example_request {"secureOnly":true,"complexPasswords":true,"showReferralLinks":false,"externalDomain":"https://example.com/files","emailContent":"Greetings, ExampleUser!  Your account is ready for you to start transferring files right now. Here's your link to set up your account [[setpassword]]  Henceforth, you shall be known as [[username]]","emailSubject":"Welcome to the Example Account","allowedIpRanges":[{"ipStart":"67.208.64.228","ipEnd":"67.208.64.254"}],"customSignature":"Please consider the planet before printing this email","accountOnboarding":true,"brandingSettings":{"companyName":"Example File Transfer","theme":"light"},"quota":{"noticeEnabled":true,"noticeThreshold":90,"transactionsNoticeEnabled":true,"transactionsNoticeThreshold":80}}

@endgroup

@group email
@endpoint POST /email/welcome/{username}
@desc Resend welcome email to specific user
@required {username: str # A username to send the welcome email to.}
@returns(201) {responseStatus: int, data: [str]} # Successful operation

@endpoint POST /email/referral
@desc Send referral email to a given address
@required {emails: [str(email)], message: str}
@returns(201) {responseStatus: int, data: [str]} # Successful Operation
@example_request {"emails":["user@example.com"],"message":"I use ExaVault for secure file sending, and so should you. Follow my link to sign up for a trial."}

@endgroup

@group shares
@endpoint POST /shares
@desc Creates a share
@required {type: str(shared_folder/receive/send) # The type of share to create. See above for a description of each., name: str # A name for the share. This will be visible on the page that recipients visit.}
@optional {resources: [str] # Array of resources for this share. See details on [how to specify resources](#section/Identifying-Resources) above.  **shared_folder** and **receive** shares must have only one `resource`, which is a directory that does not have a current share attached.  **send** shares may have multiple `resource` parameters. You can also leave this parameter null if you are planning to upload files to the send. If you are planning to upload files to the send that are not yet in your account, you will also need to call the [POST /shares/complete-send/{id}](#operation/completeDirectSend) endpoint to finish the send operation., accessMode: map{download: bool, upload: bool, modify: bool, delete: bool} # An object defining what a not-logged-in visitor can do with the share contents, embed: bool # Whether this share can be embedded within a web page., recipients: [map{type: str, email: str(email)}] # People you want to invite to the share. **Note**: unless you also set the `messageSubject` and `messageBody` for the new share, invitation emails will not be sent to these recipients., expiration: str(date-time) # Expiration date for the share. If someone attempts to use the share after this date, they will receive an error that the share is not available., hasNotification: bool # Whether delivery receipts should be sent., isPublic: bool # Whether someone can visit the share without following a personalized recipient link., messageBody: str # The message to be included in email invitations for your recipients. Ignored if you have not also provided `recipients` and `messageSubject`, notificationEmails: [str(email)] # Emails that will receive delivery receipts for this share. `hasNotification` must be **true** for delivery receipts will be sent., password: str # Set a password for recipients to access the share. All recipients will use the same password., requireEmail: bool # True if recipients must provide their email to view the share., messageSubject: str # Subject to use on emails inviting recipients to the share. Ignored if you have not also provided `recipients` and a `messageBody`, fileDropCreateFolders: bool # Only used for **receive** shares. If true, uploads will be automatically placed into sub-folders of the folder, named after the chosen field on your form., sendingLocalFiles: bool # Use this only for **send** shares. Flag to indicate that you are going to upload additional files from your computer to the share. If this is **true**, you will also need to use the [POST /shares/complete-send/{id}](#operation/completeDirectSend) call to finish setting up your share after the files are uploaded.}
@returns(201) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{name: str, hasPassword: bool, public: bool, accessMode: map{download: bool, upload: bool, modify: bool, delete: bool}, accessDescription: str, embed: bool, hash: str, ownerHash: str, expiration: str, expired: bool, resent: str(date-time), type: str, requireEmail: bool, fileDropCreateFolders: bool, paths: [str], recipients: [map], messages: [map], inherited: bool, status: int(int32), hasNotification: bool, created: str(date-time), modified: str(date-time), trackingStatus: str, formId: int}, relationships: map{messages: [map], owner: map{data: map}, resources: [map], notifications: [map]}}, included: [any]} # Successful operation
@example_request {"type":"shared_folder","name":"Shared Folder","resources":["/testfolder"],"accessMode":{"download":true,"upload":true,"modify":true,"delete":true},"embed":false,"recipients":[{"type":"string","email":"user@example.com"}],"expiration":"2017-09-25T14:12:10Z","hasNotification":false,"isPublic":true,"messageBody":null,"notificationEmails":["notify@example.com","notify2@example.com"],"password":null,"requireEmail":false,"messageSubject":"Invitation to a shared folder","fileDropCreateFolders":false,"sendingLocalFiles":true}

@endpoint GET /shares
@desc Get a list of shares
@optional {offset: int # Current offset of records (for pagination), limit: int=100 # Limit of records to be returned (for pagination), scope: str(all/active/currentUser) # Set of shares to return. (**all**=all of them, **active**=shares that are currently active, **curentUser**=shares created by you), sort: str(created/-created) # What order the list of matches should be in., type: str(receive/shared_folder/send) # Limit the list of matches to only certain types of shares., include: str # Comma separated list of relationships to include in response. Possible values are **owner**, **resources**, **notifications**, **activity**., name: str # When provided, only shares whose names include this value will be in the list. Supports wildcards, such as **send\*** to return everything starting with "send".  Use this parameter if you are searching for shares or receives for a specific folder name. For example **/Clients/ACME/To Be Processed**., recipient: str # Filter the results to include only shares that invited a certain email address. Supports wildcard matching so that **\*@example.com** will give back entries shared with addresses ending in "@example.com"., message: str # When provided, only shares with a message that contains the text will be included in the list of matches. Both the subject and the body of all messages will be checked for matches. This will always be a wildcard match, so that searching for **taxes** will return any shares with a message that contains the word "taxes"., username: str # When provided, only shares created by the user with that `username` will be included in the list. Does not support wildcard searching., search: str # Searches the share name, username, recipients, share messages fields for the provided value. Supports wildcard searches.}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful operation

@endpoint GET /shares/{id}
@desc Get a share
@optional {include: str # Comma separated list of relationships to include in response. Possible values are **owner**, **resources**, **notifications**, **activity**.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{name: str, hasPassword: bool, public: bool, accessMode: map{download: bool, upload: bool, modify: bool, delete: bool}, accessDescription: str, embed: bool, hash: str, ownerHash: str, expiration: str, expired: bool, resent: str(date-time), type: str, requireEmail: bool, fileDropCreateFolders: bool, paths: [str], recipients: [map], messages: [map], inherited: bool, status: int(int32), hasNotification: bool, created: str(date-time), modified: str(date-time), trackingStatus: str, formId: int}, relationships: map{messages: [map], owner: map{data: map}, resources: [map], notifications: [map]}}, included: [any]} # Successful operation

@endpoint PATCH /shares/{id}
@desc Update a share
@optional {name: str # Name of the share., resources: [str] # Array of resources for this share. See details on [how to specify resources](#section/Identifying-Resources) above.  **shared_folder** and **receive** shares must have only one `resource`, which is a directory that does not have a current share attached.  **send** shares may have multiple `resource` parameters.   **NOTE**: Sending this parameter will **REPLACE** the existing resources with the resources included in this request., accessMode: map{download: bool, upload: bool, modify: bool, delete: bool} # An object defining what a not-logged-in visitor can do with the share contents, embed: bool # Whether the share can be embedded in another web page., recipients: [map{type: str, email: str(email)}] # People you want to invite to the share.   **Note**: unless you also set the `subject` and `message` for the new share, invitation emails will not be sent to these recipients.  **Note**: Recipients in this list will **REPLACE** the recipients already assigned to this share., expiration: str(date-time) # New expiration date and time for the share, hasNotification: bool # Whether delivery receipts should be sent for this share., isPublic: bool # Whether people can visit the share without following a link from an invitation email, messageBody: str # Message content to use for emails inviting recipients to the share. Ignored if you have not also provided `recipients` and a `subject`, notificationEmails: [str(email)] # List of email addresses to send delivery receipts to. Ignored if `hasNotification` is false., password: str # New password for the share. To leave the password unchanged, do not send this parameter., requireEmail: bool # Whether visitors to the share will be required to enter their email in order to access the share., messageSubject: str # Subject to use on emails inviting recipients to the share. Ignored if you have not also provided `recipients` and a `message`, fileDropCreateFolders: bool # Whether uploads to a receive folder should be automatically placed into subfolders. See our [receive folder documentation](/docs/account/05-file-sharing/05-form-builder#advanced-form-settings), status: int # New status for the share. You can set an active share to inactive by setting the status to **0**}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{name: str, hasPassword: bool, public: bool, accessMode: map{download: bool, upload: bool, modify: bool, delete: bool}, accessDescription: str, embed: bool, hash: str, ownerHash: str, expiration: str, expired: bool, resent: str(date-time), type: str, requireEmail: bool, fileDropCreateFolders: bool, paths: [str], recipients: [map], messages: [map], inherited: bool, status: int(int32), hasNotification: bool, created: str(date-time), modified: str(date-time), trackingStatus: str, formId: int}, relationships: map{messages: [map], owner: map{data: map}, resources: [map], notifications: [map]}}, included: [any]} # Successful operation
@example_request {"name":"Shared Folder","resources":["/testfolder"],"accessMode":{"download":true,"upload":true,"modify":true,"delete":true},"embed":false,"recipients":[{"type":"string","email":"user@example.com"}],"expiration":"2017-09-25T14:12:10Z","hasNotification":false,"isPublic":true,"messageBody":null,"notificationEmails":["notify@example.com","notify2@example.com"],"password":null,"requireEmail":false,"messageSubject":"Invitation to a shared folder","fileDropCreateFolders":false,"status":0}

@endpoint DELETE /shares/{id}
@desc Deactivate a share
@returns(200) {responseStatus: int, data: [str]} # Successful operation

@endpoint POST /shares/complete-send/{id}
@desc Complete send files
@required {id: int # ID of the share to trigger invitations for.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{name: str, hasPassword: bool, public: bool, accessMode: map{download: bool, upload: bool, modify: bool, delete: bool}, accessDescription: str, embed: bool, hash: str, ownerHash: str, expiration: str, expired: bool, resent: str(date-time), type: str, requireEmail: bool, fileDropCreateFolders: bool, paths: [str], recipients: [map], messages: [map], inherited: bool, status: int(int32), hasNotification: bool, created: str(date-time), modified: str(date-time), trackingStatus: str, formId: int}, relationships: map{messages: [map], owner: map{data: map}, resources: [map], notifications: [map]}}, included: [any]} # Successful operation

@endgroup

@group recipients
@endpoint POST /recipients/shares/invites/{shareId}
@desc Resend invitations to share recipients
@required {shareId: int # ID of the share to resend invites for.}
@optional {recipientId: int(int32) # ID number of recipient to send a new invitation to.}
@returns(201) {responseStatus: int, data: [str(email)]} # Successful operation
@example_request {"recipientId":0}

@endgroup

@group ssh-keys
@endpoint GET /ssh-keys
@desc Get metadata for a list of SSH Keys
@optional {userId: str # Only return results for the given user ID. This is not the username, but the numeric ID of the user., limit: int # Limits the results by the given number. Cannot be set higher than 100., offset: int # Determines which item to start on for pagination. Use zero (0) to start at the beginning of the list.}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [map]} # Successful Operation

@endpoint POST /ssh-keys
@desc Create a new SSH Key
@required {userId: int # ID of the user to assign the new key to., publicKey: str # Public Key to provide ExaVault. You can provide the Public Key as formatted from the ssh-keygen command or a standard rfc-4716 format.}
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{fingerprint: str, lastLogin: str(date-time), created: str(date-time)}, relationships: map{ownerUser: map{data: map}}}, included: [map]} # Successful Operation

@endpoint GET /ssh-keys/{id}
@desc Get metadata for an SSH Key
@returns(200) {responseStatus: int, data: map{id: int(int32), type: str, attributes: map{fingerprint: str, lastLogin: str(date-time), created: str(date-time)}, relationships: map{ownerUser: map{data: map}}}, included: [map]} # Successful Operation

@endpoint DELETE /ssh-keys/{id}
@desc Delete an SSH Key
@returns(200) Successful Operation

@endgroup

@group webhooks
@endpoint GET /webhooks
@desc Get Webhooks List
@optional {include: str # List of related record types to include. Valid options are `owningAccount` and `resource`, offset: int # Records to skip before returning results., limit: int # Limit of the records list}
@returns(200) {responseStatus: int, totalResults: int, returnedResults: int, data: [map], included: [any]} # Successful Operation

@endpoint POST /webhooks
@desc Add A New Webhook
@required {endpointUrl: str(uri) # The endpoint is where the webhook request will be sent.}
@optional {triggers: map{resources: map, shares: map}, resource: str # Resource identifier for the top folder this webhook is associated with, responseVersion: str(v1/v2) # What version of webhook request should be sent to the endpoint URL when messages are sent}
@returns(201) {responseStatus: int, data: [map], included: [any]} # Created

@endpoint GET /webhooks/{id}
@desc Get info for a webhook
@optional {include: str # Include metadata for related items; `ownerAccount` and/or `resource`}
@returns(200) {responseStatus: int, data: [map], included: [any]} # Successful Operation

@endpoint PATCH /webhooks/{id}
@desc Update a webhook
@optional {endpointUrl: str(uri) # New endpoint URL to use for the webhook configuration, triggers: map{resources: map, shares: map}, resource: str # Resource identifier of the top folder watched by this webhook., responseVersion: str(v2/v1) # Version of the webhooks message to send to the endpoint}
@returns(200) {responseStatus: int, data: [map], included: [any]} # Successful Operation

@endpoint DELETE /webhooks/{id}
@desc Delete a webhook
@returns(200) {responseStatus: int, data: [str]} # Sucessful operation

@endpoint POST /webhooks/resend/{activityId}
@desc Resend a webhook message
@returns(200) {responseStatus: int, data: [str]} # Successful operation

@endpoint POST /webhooks/regenerate-token/{id}
@desc Regenerate security token
@returns(200) {responseStatus: int, data: [map], included: [any]} # Successful Operation

@endgroup

@end
