Get started with Storage API

Introduction

This quick start is going to help you work with using Storage API. Tutorial describes main operations required to create files with folders, retrieving and managing them.

Info

Skill level:

Basic

Duration:

45 minutes

Prerequisites

This tutorial assumes that you already have:

1. Preparing to use Storage API

There are some actions, which should be completed before starting using Storage API.

1.1 Register an Application


To build an application on the iTwin Platform, you will need to register a client.

Optional: Manual Application registration process


To manually register a client:

  1. Go to https://developer.bentley.com
  2. Click the Sign In button and sign-in using your Bentley account credentials
    • If you have not already registered, click Register now and complete the registration process.
  3. Click on your user icon and navigate to the My Apps page
  4. Click the Register New button
  5. Give your application a Name
  6. Select the Data Management API
  7. Select application type SPA (Single Page Web Application)
  8. Enter Redirect URL
    • For this tutorial use https://localhost:3000
  9. Leave post logout redirect URIs empty.
  10. Click the Save button
Note the Client ID that is generated during the registration process. You will need this in a later step.

1.2 Get a token


To make request to API user token is needed. There are several ways to get it.

Implement Authorization Code Flow in the application


Follow this article to implement Authorization code workflow in your application.

Here you can use Client ID generated from previous registration step.

Grab a user token from API reference “Try it” Section


  1. Go to Get top level folders and files by project - Storage
  2. Click “Try it” button.
  3. On Authorization section select “AuthorizationCode”.
  4. After popup closes Authorization header with your user token value should be visible.
  5. Save user token value for this tutorial.
Use user token to replace JWT_TOKEN dynamic parameter in the next steps.

1.3 Get a link to the Storage


Files and folders created via Storage API are associated with project. If project is already existing then root folder, which is parent folder to first level files and folders could be retrieved by getting project. Project will contain the link to Storage. If there is no project then ir should be created by executing create project operation.

Another way of getting link to the storage is by executing HTTP GET https://api.bentley.com/storage?projectId=PROJECT_ID request.

You can execute the request in Get top level folders and files by project documentation page, “Try it” section.

Top level folders with files should be returned if there are any. Response will contain link to the storge, to the root folder.

Request Syntax


1 GET https://api.bentley.com/storage?projectId=PROJECT_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 { "items": [], "_links": { "self": { "href": "https://api.bentley.com/storage?projectId=PROJECT_ID&$skip=0&$top=100" }, "prev": { "href": "https://api.bentley.com/storage?projectId=PROJECT_ID&$skip=0&$top=100" }, "next": { "href": "https://api.bentley.com/storage?projectId=PROJECT_ID&$skip=100&$top=100" }, "folder": { "href": "https://api.bentley.com/storage/folders/TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } } }

2. Get folder

To retrieve root folder, HTTP GET https://api.bentley.com/storage/folders/FOLDER_ID request should be executed by using link from previous section or by existing another root folder ID.

You can execute the request in Get folder documentation page, “Try it” section.

Request Syntax


1 GET https://api.bentley.com/storage/folders/FOLDER_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 { "folder": { "id": "FOLDER_ID", "displayName": "test", "description": "test folder", "path": "folderName/test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

3. Create folder

Organize files in the better way by storing them in folders. To create folder requst, payload should be send to HTTP POST https://api.bentley.com/storage/folders/FOLDER_ID/folders. It is necessary displayName to bet set while description is optional in the payload.

You can execute the request in Create folder documentation page, “Try it” section.

Folder should be created and ready to be used.

Request Syntax


1 POST https://api.bentley.com/storage/folders/FOLDER_ID/folders HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Request Body


1 2 3 4 { "displayName": "test", "description": "test folder" }

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 { "folder": { "id": "TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI", "displayName": "test", "description": "test folder", "path": "test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

Response headers


1 Location: https://api.bentley.com/storage/folders/TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI

4. Create file

Create file is three steps operation. Metadata needs to be created first then actual file should be uploaded and finally confirmation request needs to be sent. Created files can be synchronized with iModels. Try Synchronization API.

4.1 Create file’s metadata


Use roof folder ID from preivous step to crate file in the same directory as previously created folder and execute HTTP POST https://api.bentley.com/storage/folders/FOLDER_ID/files request. It is necessary displayName to bet set while description is optional in the payload.

You can execute the request in Create file documentation page, “Try it” section.

File’s metadata should be created and links from the response will be used in the further steps to create file.

Request Syntax


1 POST https://api.bentley.com/storage/folders/FOLDER_ID/files HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Request Body


1 2 3 4 { "displayName": "test.txt", "description": "test file" }

Response Body


1 2 3 4 5 6 7 8 9 10 { "_links": { "completeUrl": { "href": "https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc/complete" }, "uploadUrl": { "href": "https://projectshareprodeussa01.blob.core.windows.net/azuresqldbecpluginstorage/ProjectShare/File/b6145b7f-fee9-4a13-b1e4-5d061970373e?sv=2017-04-17&sr=b&sig=4NfdEriAONQhbHGkrTAL4bNMzjW8Qm5l%2FoEPiSQl%2BPo%3D&se=2020-10-19T15:12:51Z&sp=rw&rscd=attachment%3B%20filename%3D%22test.txt%22&userid=b905387c-a685-4d27-aab7-468c9ff0c9a6" } } }

4.2 Upload actual file


This request is used to upload actual file. Url should be picked from preivious request’s response where uploadUrl is specified. The maximum size of the file is 256 MiB. If bigger file needs to be uploaded there are possibility to use Azure libraries to upload file via given Azure SAS url or by uploading file with multiple requests.

Request Syntax


1 PUT https://projectshareprodeussa01.blob.core.windows.net/azuresqldbecpluginstorage/ProjectShare/File/b6145b7f-fee9-4a13-b1e4-5d061970373e?sv=2017-04-17&sr=b&sig=4NfdEriAONQhbHGkrTAL4bNMzjW8Qm5l%2FoEPiSQl%2BPo%3D&se=2020-10-19T15:12:51Z&sp=rw&rscd=attachment%3B%20filename%3D%22test.txt%22&userid=b905387c-a685-4d27-aab7-468c9ff0c9a6 HTTP/1.1

Request Headers


1 x-ms-blob-type: BlockBlob

Request Body


1 test

4.3 Complete file creation


After uploading actual file confirmation is needed. That will make file visible and it could be used further. Url should be picked from the first step of file’s metadata creation where completeUrl is specified.

You can execute the request in Complete file upload page, “Try it” section.

Your file should be placed in the storage and be ready to be used.

Request Syntax


1 POST https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc/complete HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 14 { "file": { "id": "TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc", "displayName": "test.txt", "description": "test file", "path": "folderName/test.txt", "size": 8, "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

5. Download file

Created files can be downloaded by executing HTTP GET https://api.bentley.com/storage/files/FILE_ID/download request.

You can execute the request in Complete file upload page, “Try it” section.

Your file should be downloaded with the content specified in the previous request.

This query returns `302` redirect response and follow up request should be executed by using link from `Location` header.

Request Syntax


1 GET https://api.bentley.com/storage/files/FILE_ID/download HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Headers


1 Location: https://projectshareprodeussa01.blob.core.windows.net/azuresqldbecpluginstorage/ProjectShare/File/b6145b7f-fee9-4a13-b1e4-5d061970373e?sv=2017-04-17&sr=b&sig=4NfdEriAONQhbHGkrTAL4bNMzjW8Qm5l%2FoEPiSQl%2BPo%3D&se=2020-10-19T15:12:51Z&sp=rw&rscd=attachment%3B%20filename%3D%22test.txt%22&userid=b905387c-a685-4d27-aab7-468c9ff0c9a6

6. Get folders and files in the folder

Ussually for navigating through folders and files request for getting the is send. HTTP GET https://api.bentley.com/storage/folders/FOLDER_ID/list with root folder id as folder id should be used to retrieve the items of root folder. It is possible to set page size by specifying $skip and $top query parameters. $top default is set to 100 if it is not changed.

You can execute the request in Get folders and files in folder documentation page, “Try it” section.

Your created folder and file should retrieved.

Request Syntax


1 GET https://api.bentley.com/storage/folders/FOLDER_ID/list HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 { "items": [ { "type": "folder", "id": "TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI", "displayName": "test", "description": "test folder", "path": "test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" }, { "type": "file", "id": "TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc", "displayName": "test.txt", "description": "test file", "path": "folderName/test.txt", "size": 8, "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } ], "_links": { "self": { "href": "https://api.bentley.com/storage/folders/TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s/list?$skip=0&$top=100" }, "prev": { "href": "https://api.bentley.com/storage/folders/TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s/list?$skip=0&$top=100" }, "next": { "href": "https://api.bentley.com/storage/folders/TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s/list?$skip=100&$top=100" } } }

7. Update folder

To update folder’s metadata requst with payload should be send to HTTP PATCH https://api.bentley.com/storage/files/FOLDER_ID. displayName and description properties can be updated by sending this request.

You can execute the request in Update folder documentation page, “Try it” section.

Folder’s properties should be updated.

Request Syntax


1 PATCH https://api.bentley.com/storage/folders/FOLDER_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Request Body


1 2 3 4 { "displayName": "test update", "description": "test folder update" }

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 { "folder": { "id": "TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI", "displayName": "test", "description": "test folder", "path": "test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:09:02.0954397Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

8. Update file

To update file’s metadata requst with payload should be send to HTTP PATCH https://api.bentley.com/storage/files/FILE_ID. displayName and description properties can be updated by sending this request same as wilth folder update.

You can execute the request in Update file documentation page, “Try it” section.

Files’s properties should be updated.

Request Syntax


1 PATCH https://api.bentley.com/storage/files/FILE_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Request Body


1 2 3 4 { "displayName": "test update.txt", "description": "test file update" }

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 { "folder": { "id": "TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI", "displayName": "test", "description": "test folder", "path": "test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:15:02.0954397Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

9. Update file’s content

Update file’s content is three steps operation. Request for initiating update need to be made first then actual file should be uploaded and finally confirmation request needs to be sent.

9.1 Initiate file’s content update


Use file ID from preivous step and execute HTTP POST https://api.bentley.com/storage/files/FILE_ID/updateContent request.

You can execute the request in Update file’s content documentation page, “Try it” section.

Hyperlinks will be created, which should be used be used in the further steps to update file’s content.

Request Syntax


1 POST https://api.bentley.com/storage/files/FILE_ID/updateContent HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 { "_links": { "completeUrl": { "href": "https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc/complete" }, "uploadUrl": { "href": "https://projectshareprodeussa01.blob.core.windows.net/azuresqldbecpluginstorage/ProjectShare/File/b6145b7f-fee9-4a13-b1e4-5d061970373e?sv=2017-04-17&sr=b&sig=4NfdEriAONQhbHGkrTAL4bNMzjW8Qm5l%2FoEPiSQl%2BPo%3D&se=2020-10-19T15:12:51Z&sp=rw&rscd=attachment%3B%20filename%3D%22test.txt%22&userid=b905387c-a685-4d27-aab7-468c9ff0c9a6" } } }

9.2 Upload actual file


This request is used to upload actual file. Url should be picked from preivious request’s response where uploadUrl is specified. The maximum size of the file is 256 MiB. If bigger file needs to be uploaded there are possibility to use Azure libraries to upload file via given Azure SAS url or by uploading file with multiple requests.

Request Syntax


1 PUT https://projectshareprodeussa01.blob.core.windows.net/azuresqldbecpluginstorage/ProjectShare/File/b6145b7f-fee9-4a13-b1e4-5d061970373e?sv=2017-04-17&sr=b&sig=4NfdEriAONQhbHGkrTAL4bNMzjW8Qm5l%2FoEPiSQl%2BPo%3D&se=2020-10-19T15:12:51Z&sp=rw&rscd=attachment%3B%20filename%3D%22test.txt%22&userid=b905387c-a685-4d27-aab7-468c9ff0c9a6 HTTP/1.1

Request Headers


1 x-ms-blob-type: BlockBlob

Request Body


1 test update

9.3 Complete file’s content upload


After uploading actual file confirmation is needed. Url should be picked from the first step where completeUrl is specified.

You can execute the request in Complete file upload page, “Try it” section.

File’s content should be updated.

Request Syntax


1 POST https://api.bentley.com/storage/files/TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc/complete HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 14 { "file": { "id": "TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc", "displayName": "test.txt", "description": "test file", "path": "folderName/test.txt", "size": 8, "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:25:46.8659753Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } }

10. Recycle bin operations

Files and folders can be deleted and restored. Deleted items can be queried as well because they will be only soft deleted and kept in the recycle bin. Items from recycle bin can be deleted manually if there is no reason to keep them longer otherwise they will be removed automatically after 30 days.

10.1 Delete folder


Let’s delete created folder. Execute HTTP DELETE https://api.bentley.com/storage/folders/FOLDER_ID request.

You can execute the request in Delete folder page, “Try it” section.

Folder should be soft deleted.

Request Syntax


1 DELETE https://api.bentley.com/storage/folders/FOLDER_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

10.2 Delete file


Let’s delete created file as well. Execute HTTP DELETE https://api.bentley.com/storage/files/FILE_ID request.

You can execute the request in Delete file page, “Try it” section.

File should be soft deleted.

Request Syntax


1 DELETE https://api.bentley.com/storage/files/FILE_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

10.3. Get folders and files in recycle bin


Soft deleted files and folders can be retrieve. Send HTTP GET https://api.bentley.com/recycleBin?projectId=PROJECT_ID. It is possible to set page size by specifying $skip and $top query parameters. $top default is set to 100 if it is not changed.

You can execute the request in Get folders and files in recycle bin documentation page, “Try it” section.

File and folder, which were deleted previously should be showed.

Request Syntax


1 GET https://api.bentley.com/storage/recycleBin?projectId=PROJECT_ID HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Response Body


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 { "items": [ { "type": "folder", "id": "TYJsPN0xtkWId0yUrXkS5pN5AQzuullIkxz5aDnDJSI", "displayName": "test", "description": "test folder", "path": "test", "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:05:11.0133549Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" }, { "type": "file", "id": "TYJsPN0xtkWId0yUrXkS5s4FlCroosBMlyDhZZmlzoc", "displayName": "test.txt", "description": "test file", "path": "folderName/test.txt", "size": 8, "createdBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "lastModifiedBy": "1140f95b-1ba0-49d9-bbf4-b53e54d80387", "createdDateTime": "2020-05-03T11:05:11.0133549Z", "lastModifiedDateTime": "2020-05-03T11:25:46.8659753Z", "parentFolderId": "TYJsPN0xtkWId0yUrXkS5g0CIYaGZLxEozrWBCOcS_s" } ], "_links": { "self": { "href": "https://api.bentley.com/storage/recycleBin?projectId=PROJECT_ID&$skip=0&$top=100" }, "prev": { "href": "https://api.bentley.com/storage/recycleBin?projectId=PROJECT_ID&$skip=0&$top=100" }, "next": { "href": "https://api.bentley.com/storage/recycleBin?projectId=PROJECT_ID&$skip=100&$top=100" } } }

10.4 Restore folder


It is time to restore deleted folder. Execute HTTP POST https://api.bentley.com/storage/recycleBin/folders/FOLDER_ID/restore request.

You can execute the request in Restore folder page, “Try it” section.

Folder should be successfully restored.

Request Syntax


1 POST https://api.bentley.com/storage/recycleBin/folders/FOLDER_ID/restore HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

10.5 Restore file


Finally file can be restored as well. Execute HTTP POST https://api.bentley.com/storage/recycleBin/files/FILE_ID/restore request.

You can execute the request in Restore file page, “Try it” section.

File should be successfully restored.

Request Syntax


1 POST https://api.bentley.com/storage/recycleBin/files/FILE_ID/restore HTTP/1.1

Request Headers


1 2 Accept: application/vnd.bentley.itwin-platform.v1+json Authorization: Bearer JWT_TOKEN

Continue learning

Congratulation for completing Storage API tutorial! You should be able to manage your securely stored files, which can be integrated to other service.

More resources that you may like

Storage API

There are more capabilities, which could be used for reatrieving files, folders and more.

Projects API

Project is necessary for using Storage API. You can check its posibilities.

Synchronization API

Files can be synchronized to iModel via Synchronization API.

Export issue

Issues can be exported as pdfs to Storage.

Export form

Forms can be exported as pdfs to Storage.