TrimbleCloud.FileService
The Trimble File Service provides capabilities for managing file type of resources organized into folders and related metadata in a secure way with predefined ACL roles.
Getting Started
Installation
This SDK is available as a NuGet package from Trimble Artifactory.
To install, use the following command:
dotnet add package TrimbleCloud.FileService
FileService Endpoints
These are the US region endpoints for File Service:
| Environment | Base URL Endpoint |
|---|---|
| Stage | https://cloud.stage.api.trimblecloud.com/fileservice/api/2.0 |
| Production | https://cloud.api.trimble.com/fileservice/api/2.0 |
For other regions, refer to the Trimble Cloud Console.
Error Handling
All Trimble Cloud .NET SDKs now use a standardized error handling approach based on the TrimbleServiceException class from the TrimbleCloud.FileService package. This provides consistent error information across all services.
TrimbleServiceException
The TrimbleServiceException is the primary exception class used across all Trimble Cloud SDKs. It provides detailed error information including:
- HTTP Status Code - The HTTP status code of the failed request
- Request ID - A unique identifier for tracking and support purposes
- Error Details - Structured error information from the service
- Raw Response - Access to the original HTTP response for advanced debugging
Basic Error Handling
try{ var file = await fileServiceClient.Files.Get(spaceId, fileId); Console.WriteLine($"Retrieved file: {file.Data.Name}");}catch (TrimbleServiceException ex){ Console.WriteLine($"Service error: {ex.Message}"); Console.WriteLine($"Status Code: {ex.StatusCode}"); Console.WriteLine($"Request ID: {ex.RequestId}");
// Serilazable Console.WriteLine(JsonConvert.SerializeObject(ex, Formatting.Indented));}Exception message output example
Service request failed. Status: <STATUS_CODE> <STATUS_MESSAGE> RequestId: <REQUEST_ID> Response Content: <API_ERROR_RESPONSE_BODY>
Create File Service Client
To create a FileServiceClient, you need to provide a token provider and the File Service endpoint. The token provider is used to authenticate the client with Trimble Identity (TID).
using Trimble.ID;using TrimbleCloud.FileService;
//Setup a TID provider for communications with our authorization server TIDvar endpointProvider = new OpenIdEndpointProvider(new Uri("<CONFIG_ENDPOINT>", UriKind.Absolute));
//Setup a token provider to handle the token exchange with TIDvar tokenProvider = new ClientCredentialTokenProvider(endpointProvider, "<CLIENT_ID>", "<CLIENT_SECRET>").WithScopes("<SCOPES>");
var client = new FileServiceClient(new BearerTokenHttpClientProvider(tokenProvider, new Uri("<FILE_SERVICE_ENDPOINT>")));Refer to the Trimble ID SDK documentation for more information on setting up the token provider.
Handling Retries and Timeouts
The FileServiceClient uses a default configuration for retries and timeouts. It is used to handle transient failures and network issues. The following properties can be configured:
Retries- The number of retries for the client. Default is 3.RetryInterval- The retry interval for the client. Default is 5 seconds. We have an exponential backoff strategy for retries which doubles the interval after each retry.HttpTimeout- The timeout for the client. Default is 5 minutes.
To create FileServiceClient with custom configurations, you can use the FileServiceClientConfig class.
var config = new FileServiceClientConfig();
// Set the number of retries for the clientconfig.Retries = 5;
// Set the retry interval for the clientconfig.RetryInterval = TimeSpan.FromSeconds(10);
// Set the timeout for the clientconfig.HttpTimeout = TimeSpan.FromMinutes(6);
var client = new FileServiceClient(new BearerTokenHttpClientProvider(tokenProvider, new Uri("<FILE_SERVICE_ENDPOINT>")), config);Minimal Response Feature
- The minimal response feature provides a streamlined version of response data by including only essential attributes of an entity.
- This reduces the response size, leading to faster data transfer and lower bandwidth usage.
- It is particularly useful when the client does not need all the attributes of an entity.
- The minimal response feature is applicable for all synchronous operation responses, including methods such as Create, Get, Update, Move, Rename, Restore, Lock, Unlock, GetVersion, and List methods.
Spaces
- A space is a container for files and folders.
- It is the top-level entity in the file service.
- A root folder is created automatically when a space is created.
Create
Create a new space.
var aclList = new List<Acl>(){ new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.SpaceManager }, new Acl() { Actor = new AclDeviceIdentity(Guid.Parse("<DEVICE_ID>")), Role = AclRole.ContentManager, AccessExpiresAt = DateTime.UtcNow.AddDays(30) }, new Acl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentContributor }};
// `SpaceMembershipBoundary` allow restrict content access to space members in which `group` is the IAM group identifier and `allowLimitedViewerOutsideBoundaryGroup` if true, users outside the space membership boundary group can be granted limited viewer access.
Response<Space> space = await client.Spaces.Create(new SpaceCreate(){ Name = "<SPACE_NAME>", AccountId = "<ACCOUNT_ID>", PermissionsLocal = new SpacePermissionsLocal() { Acl = aclList }, Provider = Provider.AWS, SoftDeleteRetention = RetentionPeriod.OneYear, SpaceMembershipBoundary = new SpaceMembershipBoundary() { Group = "<GROUP_TRN>", AllowLimitedViewerOutsideBoundaryGroup = true }, AllowAnonymousShares = true});
// To create a space with anonymous access, you must enable AllowAnonymousShares// and add an AclCustomIdentity("anonymous") with LimitedViewer rolevar aclListWithAnonymous = new List<Acl>(){ new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.SpaceManager }, new Acl() { Actor = new AclCustomIdentity("anonymous"), Role = AclRole.LimitedViewer }, // Group "trn:2:iam:us:group:<GROUP_ID>" can be added as an actor only if space has membership boundary new Acl() { Actor = new AclCustomIdentity("trn:2:iam:us:group:<GROUP_ID>"), Role = AclRole.LimitedViewer }};
Response<Space> anonymousSpace = await client.Spaces.Create(new SpaceCreate(){ Name = "<SPACE_NAME>", AccountId = "<ACCOUNT_ID>", PermissionsLocal = new SpacePermissionsLocal() { Acl = aclListWithAnonymous }, Provider = Provider.AWS, AllowAnonymousShares = true});To create a space and get a minimal response, use the CreateWithMinimalResponse method.
Response<MinimalSpace> space = await client.Spaces.CreateWithMinimalResponse(new SpaceCreate(){ Name = "<SPACE_NAME>", AccountId = "<ACCOUNT_ID>", SpaceMembershipBoundary = new SpaceMembershipBoundary() { Group = "<GROUP_TRN>", AllowLimitedViewerOutsideBoundaryGroup = true }, AllowAnonymousShares = false});Get
Get space by ID.
Response<Space> space = await client.Spaces.Get(spaceId);The optional status parameter can be used to filter the spaces based on the status.
Response<Space> space = await client.Spaces.Get(spaceId, status: ResourceStatus.Active);To get a space with minimal response, use the GetWithMinimalResponse method.
Response<MinimalSpace> space = await client.Spaces.GetWithMinimalResponse(spaceId, status: ResourceStatus.Active);Update
Update space by ID. Only the name, ACL details, soft delete retention, space membership boundary, and anonymous shares setting can be updated for a space.
SpaceMembershipBoundaryis space membership boundary settings that allow space managers to restrict content access to space members in which group is the IAM group identifier that defines the space membership boundary and allowLimitedViewerOutsideBoundaryGroupWhen true, users outside the space membership boundary group can be granted limited viewer access. When false, only members of the space membership boundary group are permitted to access content.
// Here, the existing permissions are replaced with the new ACL list.
Response<Space> space = await client.Spaces.Update(spaceId, new SpaceUpdate(){ Name = "<NEW_NAME>", PermissionsLocal = new SpaceUpdatePermissionsLocal() { ReplaceAcl = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentManager, AccessExpiresAt = DateTime.UtcNow.AddDays(30) }, new Acl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentContributor } } }, SoftDeleteRetention = RetentionPeriod.OneYear, SpaceMembershipBoundary = new SpaceMembershipBoundary() { Group = "<GROUP_TRN>", AllowLimitedViewerOutsideBoundaryGroup = false }, AllowAnonymousShares = true});
// To add or remove permissions, use the UpdateAcl field.Response<Space> space = await client.Spaces.Update(spaceId, new SpaceUpdate(){ Name = "<NEW_NAME>", PermissionsLocal = new SpaceUpdatePermissionsLocal() { UpdateAcl = new SpaceUpdateAcl { Add = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentContributor, AccessExpiresAt = DateTime.UtcNow.AddDays(15) }, }, Remove = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentManager }, } } }, SoftDeleteRetention = RetentionPeriod.OneYear, SpaceMembershipBoundary = new SpaceMembershipBoundary() { Group = "<GROUP_TRN>", AllowLimitedViewerOutsideBoundaryGroup = true }, AllowAnonymousShares = false});To update a space and get a minimal response, use the UpdateWithMinimalResponse method.
Response<MinimalSpace> space = await client.Spaces.UpdateWithMinimalResponse(spaceId, new SpaceUpdate(){ Name = "<NEW_NAME>"});Delete
Delete space by ID. By default, it is a non-recursive soft delete operation.
Empty space deletion will not return any job ID. Non-empty space deletion is an asynchronous operation which returns the job ID.
await client.Spaces.Delete(spaceId);The optional recursive parameter can be used to delete the space and its contents recursively. The permanent parameter can be used to delete the space permanently.
Guid? jobId = await client.Spaces.Delete(spaceId, recursive: true, permanent: true);NOTE: A non-empty space can only be deleted with
recursiveparameter set to true.
Restore
The restore space operation is used to restore a deleted space within 30 days of its deletion. Any resources nested under the restored space or folder will be restored through an asynchronous process.
(Response<Space> Space, Guid? JobId) result = await client.Spaces.Restore(spaceId);To restore a space and get a minimal response, use the RestoreWithMinimalResponse method.
(Response<MinimalSpace> Space, Guid? JobId) result = await client.Spaces.RestoreWithMinimalResponse(spaceId);List Children
List spaces that the user has access to.
NOTE: The
ListChildrenmethod returns a minimal response by default, and there is no option to retrieve a full response.
string nextPageToken = "";do{ var response = await client.Spaces.ListChildren(spaceId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page (default is 100, max is 1000).
var response = await client.Spaces.ListChildren(spaceId, maxItems: 50);You can also use the includeSupportFiles parameter to include support files in the response, and provide a SpaceListFilterCriteria for filtering the results.
var listFilter = new SpaceListFilterCriteria { Status = ResourceStatus.All };var response = await client.Spaces.ListChildren(spaceId, maxItems: 50, includeSupportFiles: true, listFilter: listFilter);You can filter by resource type to retrieve only files or only folders:
// Filter to show only filesvar listFilter = new SpaceListFilterCriteria { ResourceType = "FILE" };var response = await client.Spaces.ListChildren(spaceId, listFilter: listFilter);Additionally, you can specify the sort order using the sortOrder parameter:
// Sort by name in ascending ordervar response = await client.Spaces.ListChildren(spaceId, sortOrder: "asc");
// Sort by created date in descending ordervar response = await client.Spaces.ListChildren(spaceId, sortOrder: "desc");Folders
- A folder is a container for files and other folders.
Create
Create a new folder.
Response<Folder> folder = await client.Folders.Create(spaceId, new FolderCreate(){ Name = "<FOLDER_NAME>", ParentId = parentId});NOTE: To create a folder under the root folder of a space, set the
ParentIdas theRootIdof the space.
To create a folder and get a minimal response, use the CreateWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.CreateWithMinimalResponse(spaceId, new FolderCreate(){ Name = "<FOLDER_NAME>", ParentId = parentId});Create Batch Folders
Create multiple folders with a hierarchical structure in a single API call. This is useful for creating complex folder structures efficiently.
var batchRequest = new BatchFolderCreate{ Folders = new List<FolderCreateWithChildren> { new FolderCreateWithChildren { ParentId = new Guid("<PARENT_ID>"), Name = "<PARENT_FOLDER1>", Children = new List<FolderCreateChild> { new FolderCreateChild { Name = "<CHILD_FOLDER1>" }, new FolderCreateChild { Name = "<CHILD_FOLDER2>", Children = new List<FolderCreateChild> { new FolderCreateChild { Name = "<GRAND_CHILD_FOLDER1>" } } } } }, new FolderCreateWithChildren { ParentId = new Guid("<PARENT_ID>"), Name = "<PARENT_FOLDER2>" } }};
Response<BatchFolderList> response = await client.Folders.CreateBatch(new Guid("<SPACE_ID>"), batchRequest);To create batch folders and get a minimal response, use the CreateBatchWithMinimalResponse method.
Response<BatchMinimalFolderList> response = await client.Folders.CreateBatchWithMinimalResponse(new Guid("<SPACE_ID>"), batchRequest);The response contains two lists:
Items: Successfully created foldersInvalidItems: Folders that could not be created, with error details
Get by ID
Get folder by ID.
Response<Folder> folder = await client.Folders.Get(spaceId, folderId);The optional status parameter can be used to filter the folders based on the status.
Response<Folder> folder = await client.Folders.Get(spaceId, folderId, status: ResourceStatus.All);To get a folder with minimal response, use the GetWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.GetWithMinimalResponse(spaceId, folderId, status: ResourceStatus.All);Get by Path
Get folder by path.
Response<Folder> folder = await client.Folders.Get(spaceId, "<FOLDER_PATH>");The optional status parameter can be used to filter the folders based on the status.
Response<Folder> folder = await client.Folders.Get(spaceId, "<FOLDER_PATH>", status: ResourceStatus.All);To get a folder with minimal response, use the GetWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.GetWithMinimalResponse(spaceId, "<FOLDER_PATH>", status: ResourceStatus.All);Update
Update folder by ID. Only the metadata and ACL settings can be updated.
Response<Folder> folder = await client.Folders.Update(spaceId, folderId, new FolderUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" }, { "key2", "value2" } }});You can also include headers in the request
Response<Folder> folder = await client.Folders.Update(spaceId, folderId, new FolderUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" }, { "key2", "value2" } }, new Dictionary<string, string>() { { "If-Match", "2" } }});To update a folder and get a minimal response, use the UpdateWithMinimalResponse method. You can also include headers in the request.
Response<MinimalFolder> folder = await client.Folders.UpdateWithMinimalResponse(spaceId, folderId, new FolderUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" } }});Delete
Delete folder by ID. By default, it is a non-recursive soft delete operation.
Empty folder deletion will not return any job ID. Non-empty folder deletion is an asynchronous operation which returns the job ID.
await client.Folders.Delete(spaceId, folderId);The optional recursive parameter can be used to delete the folder and its contents recursively. The permanent parameter can be used to delete the folder permanently. You can also include headers in the request.
Guid? jobId = await client.Folders.Delete(spaceId, folderId, headers: new Dictionary<string, string>() { { "If-Match", "2" } }, recursive: true, permanent: true);NOTE: A non-empty folder can only be deleted with
recursiveparameter set to true.
Move
Move a folder to a new location within the same space.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Move(spaceId, folderId, targetParentId);The optional name parameter can be used to specify a new name for the moved folder. You can also include headers in the request.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Move(spaceId, folderId, targetParentId, new Dictionary<string, string>() { { "<HEADER>", "<VALUE>" } }, <NEW_NAME>);To move a folder and get a minimal response, use the MoveWithMinimalResponse method. (The optional name parameter can be used to specify a new name for the moved folder. You can also include headers in the request.)
(Response<MinimalFolder> Folder, Guid? JobId) result = await client.Folders.MoveWithMinimalResponse(spaceId, folderId, targetParentId);Rename
Rename a folder with a new name. The folder will be renamed to the target name and the folder ID will remain the same.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Rename(spaceId, folderId, "<NEW_FOLDER_NAME>");You can also include headers in the request
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Rename(spaceId, folderId, "<NEW_FOLDER_NAME>", , new Dictionary<string, string>() { { "<HEADER>", "<VALUE>" } });To rename a folder and get a minimal response, use the RenameWithMinimalResponse method.(You can also include headers in the request)
(Response<MinimalFolder> Folder, Guid? JobId) result = await client.Folders.RenameWithMinimalResponse(spaceId, folderId, "<NEW_FOLDER_NAME>");Copy
Copy a folder to a new location within the same space. The folder will be copied to the target location and a new folder ID will be generated.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Copy(spaceId, folderId, targetParentId);The optional name parameter can be used to specify a new name for the copied folder. The optional includeSupportFiles parameter, if true, copies the support files along with the files in the folder and creates links between the copied main file and the copied support files. The overwriteExisting query parameter, if specified and true, determines whether to overwrite an existing resource by creating a new version with the copied content.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Copy(spaceId, folderId, targetParentId, name: "<NEW_FOLDER_NAME>", includeSupportFiles: true, overwriteExisting: true);You can also use the CopyFolderRequest class to provide all parameters for copying a file, including specifying a version to copy:
CopyFolderRequest copyFolderRequest = new CopyFolderRequest(){ SpaceId = new Guid("<SPACE_ID>"), FolderId = new Guid("<FOLDER_ID>"), TargetParentId = new Guid("<TARGET_PARENT_ID>"), Headers = new Dictionary<string, string>() { {"<HEADER>", "<VALUE>" } }, PermissionsLocal = new FolderUpdatePermissionsLocal() { Acl = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentContributor }, new Acl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentViewer } } }, CopyAcl = false};
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Copy(copyFolderRequest);To copy a folder and get a minimal response, use the CopyWithMinimalResponse method.
(Response<MinimalFolder> Folder, Guid? JobId) result = await client.Folders.CopyWithMinimalResponse(spaceId, folderId, targetParentId);You can also use the CopyFolderRequest class with the minimal response version:
(Response<MinimalFolder> Folder, Guid? JobId) result = await client.Folders.CopyWithMinimalResponse(copyFolderRequest);Restore
Restore a folder and it’s children from the deleted state. By default, the folder will be restored to its original location.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Restore(spaceId, folderId);The optional name parameter can be used to specify a new name for the restored folder and the targetParentId parameter can be used to restore the folder to a new location. You can also include headers in the request.
(Response<Folder> Folder, Guid? JobId) result = await client.Folders.Restore(spaceId, folderId, "<NEW_FOLDER_NAME>", targetParentId, , new Dictionary<string, string>() { { "<HEADER>", "<VALUE>" } });To restore a folder and get a minimal response, use the RestoreWithMinimalResponse method. You can also include headers in the request.
(Response<MinimalFolder> Folder, Guid? JobId) result = await client.Folders.RestoreWithMinimalResponse(spaceId, folderId);List Children by ID
Get list of the folder children by ID.
NOTE: The
ListChildrenmethod returns a minimal response by default, and there is no option to retrieve a full response.
string nextPageToken = "";do{ var response = await client.Folders.ListChildren(spaceId, folderId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page, the listFilter parameter can be used to filter the list of children, the sortBy parameter can be used to sort the list of children by name, size etc., the sortOrder parameter can be used to specify the sort order (asc or desc) and the recursive retrieves all children of the folder recursively, if true. These methods are deprecated.
string nextPageToken = "";do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Folders.ListChildren(spaceId, folderId, nextPageToken, maxItems: 50, listFilter: listFilterCriteria, sortBy: sortByField, sortOrder: asc, recursive: true);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));NOTE: The legacy methods use
ListFilterCriteriawhich does not support filtering by resource type. UseFolderListChildrenRequestwithFolderListFilterCriteriafor full functionality including resource type filtering.
var request = new FolderListChildrenRequest{ SpaceId = spaceId, FolderId = folderId, // alternatively path = <FOLDER_PATH> can be used FilterCriteria = new FolderListFilterCriteria { Status = ResourceStatus.Active, ResourceType = "FILE" // Filter by resource type: "FILE" or "FOLDER" }, MaxItems = 50, SortBy = "name", SortOrder = "asc", Recursive = true};
var response = await client.Folders.ListChildren(request);List Children by Path
Get list of the folder children by path.
NOTE: The
ListChildrenmethod returns a minimal response by default, and there is no option to retrieve a full response.
do{ var response = await client.Folders.ListChildren(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the listFilter parameter can be used to filter the list of children. This method is deprecated.
do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Folders.ListChildren(spaceId, path, nextPageToken, maxItems: 50, listFilter: listFilterCriteria);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));Get Version by ID
Get details for the specified folder version by ID.
Response<Folder> folder = await client.Folders.GetVersion(spaceId, folderId, versionId: 1);NOTE: The version identifier will be a whole number for folders.
The optional status parameter can be used to filter the folder versions based on the status.
Response<Folder> folder = await client.Folders.GetVersion(spaceId, folderId, versionId: 1, status: ResourceStatus.All);To get a folder version with minimal response, use the GetVersionWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.GetVersionWithMinimalResponse(spaceId, folderId, versionId: 1, status: ResourceStatus.All);Get Version by Path
Get details for the specified folder version by path.
Response<Folder> folder = await client.Folders.GetVersion(spaceId, "<FOLDER_PATH>", versionId: 1);The optional status parameter can be used to filter the folder versions based on the status.
Response<Folder> folder = await client.Folders.GetVersion(spaceId, "<FOLDER_PATH>", versionId: 1, status: ResourceStatus.All);To get a folder version with minimal response, use the GetVersionWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.GetVersionWithMinimalResponse(spaceId, "<FOLDER_PATH>", versionId: 1, status: ResourceStatus.All);List Versions by ID
Get list of the folder versions by ID.
do{ var response = await client.Folders.ListVersions(spaceId, folderId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the status parameter can be used to filter the folder versions based on the status.
do{ var response = await client.Folders.ListVersions(spaceId, folderId, nextPageToken, maxItems: 10, status: ResourceStatus.All);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the folder versions with minimal response, use the ListVersionsWithMinimalResponse method.
do{ var response = await client.Folders.ListVersionsWithMinimalResponse(spaceId, folderId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));List Versions by Path
Get list of the folder versions by path.
do{ var response = await client.Folders.ListVersions(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the status parameter can be used to filter the folder versions based on the status.
do{ var response = await client.Folders.ListVersions(spaceId, path, nextPageToken, maxItems: 20, status: ResourceStatus.All);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the folder versions with minimal response, use the ListVersionsWithMinimalResponse method.
do{ var response = await client.Folders.ListVersionsWithMinimalResponse(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));Check Out Folder
Check out a folder within a space. Checking out a folder will lock it and prevent other users from making changes while you are working on it.
Response<Folder> folder = await client.Folders.CheckOutFolder(spaceId, folderId, "Reason for check out");You can also include headers in the request
Response<Folder> folder = await client.Folders.CheckOutFolder(spaceId, folderId, "Reason for check out", new Dictionary<string, string>(){ { "<HEADER1>", "VALUE1" }});To check out a folder and get a minimal response, use the CheckOutFolderWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.CheckOutFolderWithMinimalResponse(spaceId, folderId, "Reason for check out");Check In Folder
Check in a folder that was previously checked out. This will unlock the folder and make it available for other users to modify.
Response<Folder> folder = await client.Folders.CheckInFolder(spaceId, folderId);To check in a folder and get a minimal response, use the CheckInFolderWithMinimalResponse method.
Response<MinimalFolder> folder = await client.Folders.CheckInFolderWithMinimalResponse(spaceId, folderId);Files
- A file is a binary object that resides under a folder.
Get by ID
Get file by ID.
Response<File> file = await client.Files.Get(spaceId, fileId);The optional status parameter can be used to filter the files based on the status, the urlDuration parameter can be used to specify the download URL validity duration and the responseContentType parameter can be used to specify the content type of the response. The default value for urlDuration is 1 hour.
Response<File> file = await client.Files.Get(spaceId, fileId, status: ResourceStatus.All, urlDuration: TimeSpan.FromMinutes(300), responseContentType = "application/json");To get a file with minimal response, use the GetWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.GetWithMinimalResponse(spaceId, fileId, status: ResourceStatus.All);Get by Path
Get file by path.
Response<File> file = await client.Files.Get(spaceId, "<FILE_PATH>");The optional status parameter can be used to filter the files based on the status, the urlDuration parameter can be used to specify the download URL validity duration and the responseContentType parameter can be used to specify the content type of the response. The default value for urlDuration is 1 hour.
Response<File> file = await client.Files.Get(spaceId, "<FILE_PATH>", status: ResourceStatus.All, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get a file with minimal response, use the GetWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.GetWithMinimalResponse(spaceId, "<FILE_PATH>", status: ResourceStatus.All);Create File Upload
Generates a pre-signed upload url for the given name and parent ID. The returned upload ID is used to upload the file.
If Multipart is set to true, the file will be uploaded in parts and it is handled by the SDK.
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new FileUploadCreate{ Name = "<FILE_NAME>", ParentId = parentId, Multipart = true});File Creation with Permissions
You can set file permissions during creation using either the new FileAcl property with version support or the deprecated Acl property for backward compatibility.
Using the new FileAcl with version support:
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new FileUploadCreate{ Name = "<FILE_NAME>", ParentId = parentId, PermissionsLocal = new FilePermissionsLocal() { Inherits = false, FileAcl = new List<FileAcl>() { new FileAcl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentViewer, Versions = new List<string>() { "1", "2" }, // Access only to versions 1 and 2 AccessExpiresAt = DateTime.UtcNow.AddDays(30) }, new FileAcl() { Actor = new AclCustomIdentity("anonymous"), Role = AclRole.LimitedViewer, AccessExpiresAt = DateTime.UtcNow.AddDays(7) } } }});Using the deprecated Acl property for backward compatibility:
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new FileUploadCreate{ Name = "<FILE_NAME>", ParentId = parentId, PermissionsLocal = new FilePermissionsLocal() { Inherits = true, Acl = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.SupportFileAdmin, AccessExpiresAt = DateTime.UtcNow.AddDays(30) } } }});The optional urlDuration parameter can be used to specify the upload URL validity duration and the includeLinks parameter can be used to specify whether to include the links from the last version during a file’s major version change. The default value for urlDuration is 1 hour. You can also include headers in the request.
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new FileUploadCreate{ Name = "<FILE_NAME>", ParentId = parentId, Multipart = true,},new Dictionary<string, string>(){ { "If-Match", "1.*" }},urlDuration: TimeSpan.FromMinutes(300), includeLinks: true);Create Support File Upload
Generates a pre-signed upload url for the given name and parent ID (parent should be file for support files). The returned upload ID is used to upload the support file.
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new SupportFileUploadCreate{ Name = "<SUPPORT_FILE_NAME>", ParentId = parentId});The optional urlDuration parameter can be used to specify the upload URL validity duration. The default value for urlDuration is 1 hour. You can also include headers in the request.
Response<UploadDetails> upload = await client.Files.CreateFileUpload(spaceId, new SupportFileUploadCreate{ Name = "<SUPPORT_FILE_NAME>", ParentId = parentId},new Dictionary<string, string>(){ { "If-Match", "*" }},urlDuration: TimeSpan.FromMinutes(300));Create Package Upload
Package upload allows for the simultaneous uploading of a main file along with its associated support files. A maximum of 10 support files can be included in the package upload and by default, the support file are linked to the main file.
var resources = new List<SupportFileResource>(){ new SupportFileResource() { Name = "<SUPPORT_FILE_NAME>", SupportFileKey = "<SUPPORT_FILE_KEY>" }, new SupportFileResource() { Name = "<SUPPORT_FILE_NAME>" }};
var packageUploadCreate = new PackageUploadCreate(){ Name = "<FILE_NAME>", ParentId = parentId, SupportFileResources = resources};
Response<UploadDetails> upload = await client.Files.CreatePackageUpload(spaceId, packageUploadCreate);You can also include headers in the request:
Response<UploadDetails> upload = await client.Files.CreatePackageUpload(spaceId, packageUploadCreate,new Dictionary<string, string>(){ { "<HEADER>", "<VAALUE>" }},urlDuration: TimeSpan.FromMinutes(300));Get Upload Details
Retrieve the upload details by ID.
Response<UploadDetails> upload = await client.Files.GetUploadDetails(spaceId, uploadId);The optional urlDuration parameter can be used to specify the upload URL validity duration.
Response<UploadDetails> upload = await client.Files.GetUploadDetails(spaceId, uploadId, urlDuration: TimeSpan.FromMinutes(300));The optional parameters can be added using GetUploadDetailsQueryParams
Response<UploadDetails> upload = await client.Files.GetUploadDetails(spaceId, uploadId, new GetUploadDetailsQueryParams(){ LongPoll = false, FastCheck = false});Important Note: Calling
GetUploadDetailsgenerates a new upload URL with the specifiedurlDuration. If you previously created an upload with a custom URL duration (e.g., viaCreateFileUpload), callingGetUploadDetailswill reset the URL expiry to the new duration specified (or the default 60 minutes if not specified). To avoid this, use theUpload(UploadDetails, Stream)method with pre-fetched upload details.
Create or Update Links
Link support files to a specific version of a file. The support files will be linked to the target main file and the main file’s minor version will be incremented.
var links = new Dictionary<string, SupportFileLink>() { {"<KEY>", new SupportFileLink() { Id = new Guid("<SUPPORT_FILE_ID>") } }, {"<KEY>", new SupportFileLink() { Id = new Guid("<SUPPORT_FILE_ID>"), Version = "<VERSION>"} }};
Response<File> file = await client.Files.CreateOrUpdateLinks(new Guid("<SPACE_ID>"), new Guid("<FILE_ID>"), fileMajorVersion: 1, links: links);To create or update links and get a minimal response, use the CreateOrUpdateLinksWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.CreateOrUpdateLinksWithMinimalResponse(new Guid("<SPACE_ID>"), new Guid("<FILE_ID>"), fileMajorVersion: 1, links: links);Upload File
Upload a file to an existing upload using upload ID and upload URL.
The chunk size in bytes and the maximum number of concurrent requests can be specified. The default chunk size is 15 MB and the default max concurrent requests is 8.
The optional UrlDuration property specifies the upload URL validity duration when calling GetUploadDetails internally. If not specified, defaults to 60 minutes (or 2 days for files larger than 10GB).
using (var stream = System.IO.File.OpenRead("<FILE_PATH>")){ UploadRequest uploadRequest = new UploadRequest { SpaceId = new Guid("<SPACE_ID>"), UploadId = new Guid("<UPLOAD_ID>"), Stream = stream, UrlDuration = TimeSpan.FromHours(5) // Optional };
await client.Files.Upload(uploadRequest, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Upload File with UploadDetails
Upload a file using the UploadDetails response from CreateFileUpload or GetUploadDetails.
This method uses the existing URL and urlDuration in the uploadDetails
// Using response from CreateFileUpload or GetUploadDetailsusing (var stream = System.IO.File.OpenRead("<FILE_PATH>")){ await client.Files.Upload(uploadDetails, stream, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Upload Package
Upload a file along with support files to the given package upload ID.
Maximum of 10 support files can be included in the package upload. The support files will be linked to the main file by default.
The optional UrlDuration property specifies the upload URL validity duration when calling GetUploadDetails internally.
using (var mainStream = System.IO.File.OpenRead("<FILE_PATH>"))using (var supportStream1 = System.IO.File.OpenRead("<SUPPORT_FILE_PATH>"))using (var supportStream2 = System.IO.File.OpenRead("<SUPPORT_FILE_PATH>")){ var supportFiles = new List<SupportFileResourceUploadItem>() { new SupportFileResourceUploadItem() { SupportFileKey = "<SUPPORT_FILE_KEY>", SupportFileStream = supportStream1}, new SupportFileResourceUploadItem() { SupportFileKey = "<SUPPORT_FILE_KEY>", SupportFileStream = supportStream2} };
PackageUploadRequest uploadRequest = new PackageUploadRequest { SpaceId = new Guid("<SPACE_ID>"), UploadId = new Guid("<UPLOAD_ID>"), MainFileStream = mainStream, SupportFiles = supportFiles, UrlDuration = TimeSpan.FromHours(5) // Optional };
await client.Files.Upload(uploadRequest, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Upload Package with UploadDetails
Upload a package using the UploadDetails response from CreatePackageUpload or GetUploadDetails.
// Using response from CreatePackageUpload or GetUploadDetailsusing (var mainStream = System.IO.File.OpenRead("<FILE_PATH>"))using (var supportStream1 = System.IO.File.OpenRead("<SUPPORT_FILE_PATH>")){ var supportFiles = new List<SupportFileResourceUploadItem>() { new SupportFileResourceUploadItem() { SupportFileKey = "<SUPPORT_FILE_KEY>", SupportFileStream = supportStream1} };
await client.Files.Upload(uploadDetails, mainStream, supportFiles, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Download File by ID
Download a file by ID.
The chunk size in bytes and the maximum number of concurrent requests can be specified. The default chunk size is 15 MB and the default max concurrent requests is 8.
using (var stream = System.IO.File.OpenWrite("<FILE_NAME>")){ await client.Files.Download(spaceId, fileId, stream, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}The optional urlDuration parameter can be used to specify the download URL validity duration.
using (var stream = System.IO.File.OpenWrite("<FILE_NAME>")){ await client.Files.Download(spaceId, fileId, stream, urlDuration: TimeSpan.FromHours(2), chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Download File by Path
Download a file by path.
The chunk size in bytes and the maximum number of concurrent requests can be specified. The default chunk size is 15 MB and the default max concurrent requests is 8.
using (var stream = System.IO.File.OpenWrite("<FILE_NAME>")){ await client.Files.Download(spaceId, path, stream, chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}The optional urlDuration parameter can be used to specify the download URL validity duration.
using (var stream = System.IO.File.OpenWrite("<FILE_NAME>")){ await client.Files.Download(spaceId, path, stream, urlDuration: TimeSpan.FromHours(2), chunkSize: 50 * 1024 * 1024, maxConcurrentRequests: 4);}Complete Multipart Upload
Complete the multipart upload for the given upload ID.
List<FilePart> partsList = new List<FilePart> { new FilePart { ETag = "etag1", PartNumber = 1 }, new FilePart { ETag = "etag2", PartNumber = 2 }};
Response<UploadDetails> upload = await client.Files.CompleteMultipartUpload(spaceId, uploadId, partsList);Wait for Upload
Poll the upload status.
// Define a callback action to process the upload detailsAction<UploadDetails> callback = (response) =>{ Console.WriteLine($"Upload status: {response.Result.Status}");};
try{ // Call WaitForUpload with a specific timeout and interval var timeout = TimeSpan.FromSeconds(300); // 5 minutes var interval = TimeSpan.FromSeconds(10); // 10 seconds between checks
Console.WriteLine("Waiting for upload to complete..."); var upload = await client.Files.WaitForUpload(new Guid("<SPACE_ID>"), new Guid("<UPLOAD_ID>"), timeout, interval, callback);
// Process the final upload details if (!upload.GetResponse().IsError) { Console.WriteLine($"Upload completed successfully: {upload.Data.Result.Message}"); } else { Console.WriteLine("Upload completion check failed or timed out."); }}catch (Exception ex){ Console.WriteLine($"An error occurred: {ex.Message}");}The optional urlDuration parameter can be used to specify the upload URL validity duration when polling. This ensures the URL remains valid throughout the polling period.
var urlDuration = TimeSpan.FromHours(2); // Custom URL durationvar timeout = TimeSpan.FromSeconds(300);var interval = TimeSpan.FromSeconds(10);
var upload = await client.Files.WaitForUpload( new Guid("<SPACE_ID>"), new Guid("<UPLOAD_ID>"), urlDuration, timeout, interval, callback);Poll for Malware Scan Completion
Poll the malware scan status of a file until it is completed.
// Define a callback action to process the malware scan statusAction<MalwareScanStatus?> callback = (status) =>{ Console.WriteLine($"Malware scan status: {status}");};
try{ // Call PollForMalwareScanCompletion with a specific timeout and interval var timeout = TimeSpan.FromSeconds(300); // 5 minutes var interval = TimeSpan.FromSeconds(5); // 5 seconds between checks
Console.WriteLine("Polling for malware scan completion..."); await client.Files.PollForMalwareScanCompletion(new Guid("<SPACE_ID>"), new Guid("<FILE_ID>"), timeout, interval, callback);}catch (Exception ex){ Console.WriteLine($"An error occurred: {ex.Message}");}Update
Update file by ID. Only the metadata, ACL settings and links can be updated.
Response<File> file = await client.Files.Update(spaceId, fileId, new FileUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" }, { "key2", "value2" } }, PermissionsLocal = new FileUpdatePermissionsLocal() { ReplaceAcl = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentContributor }, new Acl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentViewer } } }, Links = new Dictionary<string, SupportFileLink>() { { "<KEY>", new SupportFileLink() { Id = new Guid("<SUPPORT_FILE_ID>") } } }});File Permissions with Version Support
The File Service supports file-level permissions with version restrictions using the new FileAcl property. This allows you to specify which file versions an actor can access.
Using the new FileAcl with version support:
Response<File> file = await client.Files.Update(spaceId, fileId, new FileUpdate(){ PermissionsLocal = new FileUpdatePermissionsLocal() { ReplaceFileAcl = new List<FileAcl>() { new FileAcl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentViewer, Versions = new List<string>() { "1", "2" }, // Access only to versions 1 and 2 AccessExpiresAt = DateTime.UtcNow.AddDays(30) }, new FileAcl() { Actor = new AclCustomIdentity("anonymous"), Role = AclRole.LimitedViewer, AccessExpiresAt = DateTime.UtcNow.AddDays(7) } } }});Using FileUpdateAcl for adding/removing permissions:
Response<File> file = await client.Files.Update(spaceId, fileId, new FileUpdate(){ PermissionsLocal = new FileUpdatePermissionsLocal() { UpdateAcl = new FileUpdateAcl() { AddFileAcl = new List<FileAcl>() { new FileAcl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentContributor, Versions = new List<string>() { "1.1" }, // Access to only minor version AccessExpiresAt = DateTime.UtcNow.AddDays(30) } }, Remove = new List<AclActor>() { new AclActor() { Actor = new AclCustomIdentity("old-user") } } } }});Backward compatibility with deprecated Acl property:
Response<File> file = await client.Files.Update(spaceId, fileId, new FileUpdate(){ PermissionsLocal = new FileUpdatePermissionsLocal() { ReplaceAcl = new List<Acl>() { new Acl() { Actor = new AclApplicationIdentity(Guid.Parse("<APPLICATION_ID>")), Role = AclRole.ContentContributor }, new Acl() { Actor = new AclUserIdentity(Guid.Parse("<USER_ID>")), Role = AclRole.ContentViewer } } }});Version Format for FileAcl
The Versions property in FileAcl accepts version strings in the following formats:
- Specific version:
"1","2.0","1.5"- Access to a specific version - Major version wildcard:
"1","2"- Access to all minor versions of a major version - Multiple versions:
["1", "2", "3.2"]- Access to multiple specific versions
NOTE: The
Versionsproperty is only available with the newFileAclproperty and is not supported by the deprecatedAclproperty.
You can also include headers in the request, such as If-Match for conditional updates:
var file = await client.Files.Update(spaceId, fileId, new FileUpdate(){ Metadata = new Dictionary<string, object>() { { "new", "value1" }, { "newKey", "value2" } },}, new Dictionary<string, string>(){ { "<HEADER1>", "VALUE1" }});To update a file and get a minimal response, use the UpdateWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.UpdateWithMinimalResponse(spaceId, fileId, new FileUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" } }});You can also include headers with the minimal response version:
Response<MinimalFile> file = await client.Files.UpdateWithMinimalResponse(spaceId, fileId, new FileUpdate(){ Metadata = new Dictionary<string, object> { { "key1", "value1" } }}, new Dictionary<string, string>(){ { "<HEADER1>", "<VALUE1>" }});Delete
Deletes the file. By default, it is a soft delete operation.
Delete for files that have support files is an asynchronous operation which returns the job ID.
Guid? jobId = await client.Files.Delete(spaceId, fileId);The optional permanent parameter can be used to delete the file permanently.
Guid? jobId = await client.Files.Delete(spaceId, fileId, permanent: true);You can also include headers in the request
Move
Move a file to a new location within the same space. The file will be moved to the target location and the file identifier will remain the same.
The move operation is immediate and the response contains the updated parent ID.
Response<File> file = await client.Files.Move(spaceId, folderId, targetParentId);To move a file and get a minimal response, use the MoveWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.MoveWithMinimalResponse(spaceId, folderId, targetParentId);Rename
Rename a file within the same space. The file identifier will remain the same.
The rename operation is immediate and the response contains the updated file name.
Response<File> file = await client.Files.Rename(spaceId, fileId, "<NEW_FILE_NAME>");To rename a file and get a minimal response, use the RenameWithMinimalResponse method.
You can also include headers in the request.
Response<File> file = await client.Files.Move(spaceId, fileId, targetParentId, new Dictionary<string, string>(){ { "<HEADER1>", "VALUE1" }}, name: "NewFileName");Copy
Copies a file from one folder to another within the given space. The copy operation is asynchronous and returns a job.
(Response<File> File, Guid? JobId) result = await client.Files.Copy(spaceId, fileId, targetParentId);NOTE: The copy operation is not supported across different spaces and copies only the latest version.
The optional name parameter can be used to specify a new name for the copied folder. The optional includeSupportFiles parameter, if true, copies the support files along with the file and creates links between the copied file and the copied support files. The overwriteExisting query parameter, if specified and true, determines whether to overwrite an existing resource by creating a new version with the copied content.
(Response<File> File, Guid? JobId) result = await client.Files.Copy(spaceId, fileId, targetParentId, name: "<NEW_FILE_NAME>", includeSupportFiles: true, overwriteExisting: true);To copy a file and get a minimal response, use the CopyWithMinimalResponse method.
(Response<MinimalFile> File, Guid? JobId) result = await client.Files.CopyWithMinimalResponse(spaceId, fileId, targetParentId);Restore
Restore a file from the deleted state.
(Response<File> File, Guid? JobId) result = await client.Files.Restore(spaceId, fileId);The optional name parameter can be used to specify a new name for the restored file and the targetParentId parameter can be used to restore the file to a new location. You can also include headers in the request.
(Response<File> File, Guid? JobId) result = await client.Files.Restore(spaceId, fileId, new Dictionary<string, string>(){ { "<HEADER1>", "VALUE1" }}, name: "<NEW_FILE_NAME>", targetParentId: targetParentId);To restore a file and get a minimal response, use the RestoreWithMinimalResponse method.
(Response<MinimalFile> File, Guid? JobId) result = await client.Files.RestoreWithMinimalResponse(spaceId, fileId);List Manifest Files
List all files from inside an unpacked fileset. This method retrieves the manifest files contained within a fileset, allowing you to access individual files within an archive or container file.
var fileManifest = await client.Files.ListManifestFiles(spaceId, fileId);The optional maxItems parameter can be used to limit the number of items returned in each page, the nextPageToken parameter can be used to get the next list of items, and the urlDuration parameter can be used to specify the URL validity duration.
var fileManifest = await client.Files.ListManifestFiles(spaceId, fileId, nextPageToken: "<NEXT_PAGE_TOKEN>", maxItems: 50, urlDuration: TimeSpan.FromHours(2));Lock
Lock a file within a space. Locking a file will prevent other actors from creating a new version or deleting the file.
A locked file will be deleted in a recursive parent deletion. Support files cannot be locked.
Response<File> file = await client.Files.Lock(spaceId, fileId);The optional reason parameter can be used to specify the reason for locking the file.
Response<File> file = await client.Files.Lock(spaceId, fileId, reason: "Reason for locking the file");To lock a file and get a minimal response, use the LockWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.LockWithMinimalResponse(spaceId, fileId);Unlock
Unlock a file within a space. Unlocking a file will allow other actors to create a new version or delete the file.
The actor who locked the file or an actor with the ContentManager role attached to the file or parent resource is allowed to unlock the file.
Response<File> file = await client.Files.Unlock(spaceId, fileId);To unlock a file and get a minimal response, use the UnlockWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.UnlockWithMinimalResponse(spaceId, fileId);Get Version by ID
Get a specific version of a file by ID.
Response<File> file = await client.Files.GetVersion(spaceId, fileId, versionId: "2.0");NOTE: To get the latest minor version of a major version series, the versionId should be provided as
major_version.*which will return the details of the latest minor version of the major version.
For example: To get the latest minor version of the major version 2, the versionId should be provided as2.*.
The optional status parameter can be used to filter the file versions based on the status, the urlDuration parameter can be used to specify the download URL validity duration and the responseContentType parameter can be used to specify the content type of the response. The default value for urlDuration is 1 hour.
Response<File> file = await client.Files.GetVersion(spaceId, fileId, versionId: "2.0", status: ResourceStatus.All, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get a file version with minimal response, use the GetVersionWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.GetVersionWithMinimalResponse(spaceId, fileId, versionId: "2.0");Get Version by Path
Get a specific version of a file by path.
Response<File> file = await client.Files.GetVersion(spaceId, "<FILE_PATH>", versionId: "1.2");NOTE: To get the latest minor version of a major version series, the versionId should be provided as
major_version.*which will return the details of the latest minor version of the major version.
For example: To get the latest minor version of the major version 2, the versionId should be provided as2.*.
The optional status parameter can be used to filter the file versions based on the status, the urlDuration parameter can be used to specify the download URL validity duration and the responseContentType parameter can be used to specify the content type of the response. The default value for urlDuration is 1 hour.
Response<File> file = await client.Files.GetVersion(spaceId, "<FILE_PATH>", versionId: "1.2", status: ResourceStatus.All, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get a file version with minimal response, use the GetVersionWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.GetVersionWithMinimalResponse(spaceId, "<FILE_PATH>", versionId: "1.2");List Versions by ID
Get list of the file versions by ID.
do{ var response = await client.Files.ListVersions(spaceId, fileId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the listFilter parameter can be used to filter the list of versions.
do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Files.ListVersions(spaceId, fileId, nextPageToken, maxItems: 10, listFilter: listFilterCriteria);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the file versions with minimal response, use the ListVersionsWithMinimalResponse method.
do{ var response = await client.Files.ListVersionsWithMinimalResponse(spaceId, fileId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));List Versions by Path
Get list of the file versions by path.
do{ var response = await client.Files.ListVersions(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the listFilter parameter can be used to filter the list of versions.
do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Files.ListVersions(spaceId, path, nextPageToken, maxItems: 20, listFilter: listFilterCriteria);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the file versions with minimal response, use the ListVersionsWithMinimalResponse method.
do{ var response = await client.Files.ListVersionsWithMinimalResponse(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));List Support Files by ID
Get list of the support files by file ID.
do{ var response = await client.Files.ListSupportFiles(spaceId, fileId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the listFilter parameter can be used to filter the list of support files.
do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Files.ListSupportFiles(spaceId, fileId, nextPageToken, maxItems: 10, listFilter: listFilterCriteria);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the support files with minimal response, use the ListSupportFilesWithMinimalResponse method.
do{ var response = await client.Files.ListSupportFilesWithMinimalResponse(spaceId, fileId, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));List Support Files by Path
Get list of the support files by file path.
do{ var response = await client.Files.ListSupportFiles(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));The optional maxItems parameter can be used to limit the number of items returned in each page and the listFilter parameter can be used to filter the list of support files.
do{ var listFilterCriteria = new ListFilterCriteria { Status = ResourceStatus.All, UrlDuration = TimeSpan.FromMinutes(300) }; var response = await client.Files.ListSupportFiles(spaceId, path, nextPageToken, maxItems: 20, listFilter: listFilterCriteria);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));To get the support files with minimal response, use the ListSupportFilesWithMinimalResponse method.
do{ var response = await client.Files.ListSupportFilesWithMinimalResponse(spaceId, path, nextPageToken);
foreach (var item in response) { Console.WriteLine(item.Id); Console.WriteLine(item.Name); }
nextPageToken = response.NextPageToken;
} while (!string.IsNullOrEmpty(nextPageToken));Check Out File
Check out a file within a space. Checking out a file will lock it and prevent other users from making changes while you are working on it.
Response<File> file = await client.Files.CheckOutFile(spaceId, fileId, "Reason for check out");You can also include headers in the request
Response<File> file = await client.Files.CheckOutFile(spaceId, fileId, "Reason for check out", new Dictionary<string, string>() { { "<HEADER1>", "VALUE1" }});To check out a file and get a minimal response, use the CheckOutFileWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.CheckOutFileWithMinimalResponse(spaceId, fileId, "Reason for check out");Check In File
Check in a file that was previously checked out. This will unlock the file and make it available for other users to modify.
Response<File> file = await client.Files.CheckInFile(spaceId, fileId);To check in a file and get a minimal response, use the CheckInFileWithMinimalResponse method.
Response<MinimalFile> file = await client.Files.CheckInFileWithMinimalResponse(spaceId, fileId);Jobs
- A job is a background process that is triggered by the user.
- Async operations will return a job ID which can be used to track the status of the operation.
Get
Get job by ID.
Response<Job> job = await client.Jobs.Get(new Guid("<JOB_ID>"));The optional parameters can be added using GetJobQueryParams
### Wait for JobPoll job status by ID.
```c#// Define a callback action to process the job responseAction<Job> callback = (response) =>{ Console.WriteLine($"Job status: {response.Status}");};
try{ // Call WaitForJob with a specific timeout and interval var timeout = TimeSpan.FromSeconds(300); // 5 minutes var interval = TimeSpan.FromSeconds(10); // 10 seconds between checks
Console.WriteLine("Waiting for job to complete..."); var job = await client.Jobs.WaitForJob(new Guid("<JOB_ID>"), timeout, interval, callback);
// Process the final job response if (!job.GetResponse().IsError) { Console.WriteLine($"Job completed successfully: {job.Data.Message}"); } else { Console.WriteLine("Job completion check failed or timed out."); }}catch (Exception ex){ Console.WriteLine($"An error occurred: {ex.Message}");}Exports
Export is used to zip all children of a folder into a single file. Exports persist for 30 days and capture the state of the folder and its children at the time of creation, with no subsequent changes reflected. It is created in the same cloud provider as the space.
Create
Create an export.
Guid exportId = await client.Exports.Create(spaceId, folderId);Get
Get an export by ID.
Response<Export> export = await client.Exports.Get(spaceId, exportId);The optional urlDuration parameter can be used to specify the download URL validity duration. The default value for urlDuration is 1 hour.
Response<Export> export = await client.Exports.Get(spaceId, exportId, urlDuration: TimeSpan.FromMinutes(120));Resources
- Resources in File Service represent either files or folders.
- This API provides methods to retrieve resources by ID, path, or in batches.
Get by ID
Get resource by ID.
Response<ResourceBase> resource = await client.Resources.Get(spaceId, resourceId);if (resource.Data.Type.Equals(ResourceType.File)){ if (resource.Data is MinimalFile minimalFile) { MinimalFile minimalFile = (MinimalFile)resource.Data; } else if (resource.Data is File) { File file = (File)resource.Data; }}The optional status parameter can be used to filter the resources based on the status, the urlDuration parameter can be used to specify the download URL validity duration, and the responseContentType parameter can be used to specify the content type of the response. The default value for urlDuration is 1 hour.
Response<ResourceBase> resource = await client.Resources.Get(spaceId, resourceId, status: ResourceStatus.Active, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get a resource with minimal response, use the GetWithMinimalResponse method.
Response<ResourceBase> resource = await client.Resources.GetWithMinimalResponse(spaceId, resourceId, status: ResourceStatus.Active);Get by Path
Get resource by path.
Response<ResourceBase> resource = await client.Resources.Get(spaceId, "<RESOURCE_PATH>");The optional parameters work the same as for the Get by ID method.
Response<ResourceBase> resource = await client.Resources.Get(spaceId, "<RESOURCE_PATH>", status: ResourceStatus.Active, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get a resource with minimal response, use the GetWithMinimalResponse method.
Response<ResourceBase> resource = await client.Resources.GetWithMinimalResponse(spaceId, "<RESOURCE_PATH>", status: ResourceStatus.Active);Batch Get by IDs
Get multiple resources by their IDs in a single request.
IList<Guid> resourceIds = new List<Guid> { resourceId1, resourceId2, resourceId3 };Response<BatchResourceListResponse> resources = await client.Resources.BatchGet(spaceId, resourceIds);
IList<ResourceBase> list = resources.Data.Items;The optional parameters can be used as with the individual resource retrieval methods.
Response<BatchResourceListResponse> resources = await client.Resources.BatchGet(spaceId, resourceIds, status: ResourceStatus.Active, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get batch resources with minimal response, use the BatchGetWithMinimalResponse method.
Response<BatchResourceListResponse> resources = await client.Resources.BatchGetWithMinimalResponse(spaceId, resourceIds, status: ResourceStatus.Active);Batch Get by Paths
Get multiple resources by their paths in a single request.
IList<string> resourcePaths = new List<string> { "<RESOURCE_PATH_1>", "<RESOURCE_PATH_2>", "<RESOURCE_PATH_3>" };Response<BatchResourceListResponse> resources = await client.Resources.BatchGet(spaceId, resourcePaths);The optional parameters can be used as with the other methods.
Response<BatchResourceListResponse> resources = await client.Resources.BatchGet(spaceId, resourcePaths, status: ResourceStatus.Active, urlDuration: TimeSpan.FromMinutes(300), responseContentType: "application/json");To get batch resources with minimal response, use the BatchGetWithMinimalResponse method.
Response<BatchResourceListResponse> resources = await client.Resources.BatchGetWithMinimalResponse(spaceId, resourcePaths, status: ResourceStatus.Active);Object Types
- An object type defines the schema and actions for objects. It acts as a template that objects must conform to.
Create
Create a new object type definition.
Response<ObjectType> objectType = await client.ObjectTypes.Create(new ObjectTypeCreate(){ Name = "<OBJECT_TYPE_NAME>", DisplayName = "<DISPLAY_NAME>", Schema = "<JSON_SCHEMA_STRING>", Actions = "<ACTIONS_JSON_STRING>"});Get
Get an object type by ID.
Response<ObjectType> objectType = await client.ObjectTypes.Get(new Guid("<OBJECT_TYPE_ID>"));Objects
- Objects are containers for external resources made accessible through Connect.
- Each object conforms to an object type schema.
Create
Create a new object.
Response<ObjectEntity> obj = await client.Objects.Create(spaceId, new ObjectCreate(){ ParentId = new Guid("<PARENT_FOLDER_ID>"), Name = "<OBJECT_NAME>", ObjectTypeId = new Guid("<OBJECT_TYPE_ID>"), Content = new Dictionary<string, object> { { "id", "<CONTENT_ID>" }, { "detailsId", "<CONTENT_DETAILS_ID>" } }});To create an object and get a minimal response, use the CreateWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.CreateWithMinimalResponse(spaceId, new ObjectCreate(){ ParentId = new Guid("<PARENT_FOLDER_ID>"), Name = "<OBJECT_NAME>", ObjectTypeId = new Guid("<OBJECT_TYPE_ID>"), Content = new Dictionary<string, object> { { "id", "<CONTENT_ID>" }, { "detailsId", "<CONTENT_DETAILS_ID>" } }});Get by ID
Get an object by ID.
Response<ObjectEntity> obj = await client.Objects.Get(spaceId, objectId);Optional parameters can be passed using GetObjectParams:
Response<ObjectEntity> obj = await client.Objects.Get(spaceId, objectId, new GetObjectParams { Status = ResourceStatus.Active });To get an object with minimal response, use the GetWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.GetWithMinimalResponse(spaceId, objectId);Get by Path
Get an object by path.
Response<ObjectEntity> obj = await client.Objects.Get(spaceId, "<OBJECT_PATH>");To get an object with minimal response, use the GetWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.GetWithMinimalResponse(spaceId, "<OBJECT_PATH>");Update
Update an object by ID. Only the content can be updated.
Response<ObjectEntity> obj = await client.Objects.Update(spaceId, objectId, new ObjectUpdate(){ Content = new Dictionary<string, object> { { "id", "<UPDATED_CONTENT_ID>" }, { "detailsId", "<UPDATED_CONTENT_DETAILS_ID>" } }});You can also include headers in the request for conditional updates:
Response<ObjectEntity> obj = await client.Objects.Update(spaceId, objectId, new ObjectUpdate(){ Content = new Dictionary<string, object> { { "id", "<UPDATED_CONTENT_ID>" }, { "detailsId", "<UPDATED_CONTENT_DETAILS_ID>" } }}, new Dictionary<string, string>(){ { "If-Match", "2" }});To update an object and get a minimal response, use the UpdateWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.UpdateWithMinimalResponse(spaceId, objectId, new ObjectUpdate(){ Content = new Dictionary<string, object> { { "id", "<UPDATED_CONTENT_ID>" } }});Delete
Delete an object by ID. By default, it is a soft delete operation.
await client.Objects.Delete(spaceId, objectId);The optional permanent parameter can be used to delete the object permanently.
await client.Objects.Delete(spaceId, objectId, permanent: true);You can also include headers in the request.
await client.Objects.Delete(spaceId, objectId, permanent: false, new Dictionary<string, string>(){ { "If-Match", "2" }});Check Out Object
Check out an object within a space. Checking out an object will lock it and prevent other users from making changes while you are working on it.
Response<ObjectEntity> obj = await client.Objects.Checkout(spaceId, objectId, reason: "<CHECKOUT_REASON>");You can also include headers in the request.
Response<ObjectEntity> obj = await client.Objects.Checkout(spaceId, objectId, reason: "<CHECKOUT_REASON>", new Dictionary<string, string>(){ { "<HEADER>", "<VALUE>" }});To check out an object and get a minimal response, use the CheckoutWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.CheckoutWithMinimalResponse(spaceId, objectId, reason: "<CHECKOUT_REASON>");Check In Object
Check in an object that was previously checked out. This will unlock the object and make it available for other users to modify.
Response<ObjectEntity> obj = await client.Objects.Checkin(spaceId, objectId);To check in an object and get a minimal response, use the CheckinWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.CheckinWithMinimalResponse(spaceId, objectId);Move
Move an object to a new location within the same space.
Response<ObjectJobResponse> result = await client.Objects.Move(spaceId, objectId, targetParentId);The optional name parameter can be used to specify a new name for the moved object. You can also include headers in the request.
Response<ObjectJobResponse> result = await client.Objects.Move(spaceId, objectId, targetParentId, "<NEW_OBJECT_NAME>", new Dictionary<string, string>(){ { "<HEADER>", "<VALUE>" }});To move an object and get a minimal response, use the MoveWithMinimalResponse method.
Response<MinimalObjectJobResponse> result = await client.Objects.MoveWithMinimalResponse(spaceId, objectId, targetParentId);Rename
Rename an object with a new name. The object ID will remain the same.
Response<ObjectJobResponse> result = await client.Objects.Rename(spaceId, objectId, "<NEW_OBJECT_NAME>");You can also include headers in the request.
Response<ObjectJobResponse> result = await client.Objects.Rename(spaceId, objectId, "<NEW_OBJECT_NAME>", new Dictionary<string, string>(){ { "<HEADER>", "<VALUE>" }});To rename an object and get a minimal response, use the RenameWithMinimalResponse method.
Response<MinimalObjectJobResponse> result = await client.Objects.RenameWithMinimalResponse(spaceId, objectId, "<NEW_OBJECT_NAME>");Restore
Restore a deleted object. By default, the object will be restored to its original location.
Response<ObjectJobResponse> result = await client.Objects.Restore(spaceId, objectId);The optional targetParentId parameter can be used to restore the object to a new location, and the name parameter can be used to specify a new name. You can also include headers in the request.
Response<ObjectJobResponse> result = await client.Objects.Restore(spaceId, objectId, targetParentId: targetParentId, name: "<NEW_OBJECT_NAME>", new Dictionary<string, string>(){ { "<HEADER>", "<VALUE>" }});To restore an object and get a minimal response, use the RestoreWithMinimalResponse method.
Response<MinimalObjectJobResponse> result = await client.Objects.RestoreWithMinimalResponse(spaceId, objectId);List Versions by ID
Get list of the object versions by ID.
var versions = await client.Objects.ListVersions(spaceId, objectId);foreach (var version in versions){ Console.WriteLine(version.Id);}Optional parameters can be passed using ListObjectVersionsParams:
var versions = await client.Objects.ListVersions(spaceId, objectId, new ListObjectVersionsParams { MaxItems = 10 });To get object versions with minimal response, use the ListVersionsWithMinimalResponse method.
var versions = await client.Objects.ListVersionsWithMinimalResponse(spaceId, objectId);List Versions by Path
Get list of the object versions by path.
var versions = await client.Objects.ListVersions(spaceId, "<OBJECT_PATH>");To get object versions with minimal response, use the ListVersionsWithMinimalResponse method.
var versions = await client.Objects.ListVersionsWithMinimalResponse(spaceId, "<OBJECT_PATH>");Get Version by ID
Get a specific version of an object by ID.
Response<ObjectEntity> version = await client.Objects.GetVersion(spaceId, objectId, versionId: 1);Optional parameters can be passed using GetObjectVersionParams:
Response<ObjectEntity> version = await client.Objects.GetVersion(spaceId, objectId, versionId: 1, new GetObjectVersionParams { Status = ResourceStatus.Active });Get Version by Path
Get a specific version of an object by path.
Response<ObjectEntity> version = await client.Objects.GetVersion(spaceId, "<OBJECT_PATH>", versionId: 1);Link Support Files
Link support files to a specific version of an object. The support files will be associated with the specified object version and the updated object entity is returned.
Response<ObjectEntity> obj = await client.Objects.LinkSupportFiles(spaceId, objectId, versionId: 1, new ObjectLink(){ Links = new Dictionary<string, ObjectSupportFileDetails> { { "<LINK_NAME>", new ObjectSupportFileDetails() { Id = new Guid("<SUPPORT_FILE_ID>") } } }});The optional parentMajorVersion property on ObjectSupportFileDetails can be used to link the support file to a specific major version of the object.
Response<ObjectEntity> obj = await client.Objects.LinkSupportFiles(spaceId, objectId, versionId: 1, new ObjectLink(){ Links = new Dictionary<string, ObjectSupportFileDetails> { { "<LINK_NAME>", new ObjectSupportFileDetails() { Id = new Guid("<SUPPORT_FILE_ID>"), ParentMajorVersion = 1 } } }});To link support files and get a minimal response, use the LinkSupportFilesWithMinimalResponse method.
Response<MinimalObjectEntity> obj = await client.Objects.LinkSupportFilesWithMinimalResponse(spaceId, objectId, versionId: 1, new ObjectLink(){ Links = new Dictionary<string, ObjectSupportFileDetails> { { "<LINK_NAME>", new ObjectSupportFileDetails() { Id = new Guid("<SUPPORT_FILE_ID>") } } }});List Resources by ID
Get list of the support files (resources) associated with an object by ID.
var resources = await client.Objects.ListResources(spaceId, objectId);foreach (var resource in resources){ Console.WriteLine(resource.Id);}Optional parameters can be passed using ListObjectResourcesParams:
var resources = await client.Objects.ListResources(spaceId, objectId, new ListObjectResourcesParams { MaxItems = 20 });List Resources by Path
Get list of the support files (resources) associated with an object by path.
var resources = await client.Objects.ListResources(spaceId, "<OBJECT_PATH>");