Skip to content

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:

EnvironmentBase URL Endpoint
Stagehttps://cloud.stage.api.trimblecloud.com/fileservice/api/2.0
Productionhttps://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 TID
var endpointProvider = new OpenIdEndpointProvider(new Uri("<CONFIG_ENDPOINT>", UriKind.Absolute));
//Setup a token provider to handle the token exchange with TID
var 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 client
config.Retries = 5;
// Set the retry interval for the client
config.RetryInterval = TimeSpan.FromSeconds(10);
// Set the timeout for the client
config.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 role
var 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 recursive parameter 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 ListChildren method 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 files
var 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 order
var response = await client.Spaces.ListChildren(spaceId, sortOrder: "asc");
// Sort by created date in descending order
var 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 ParentId as the RootId of 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 folders
  • InvalidItems: 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 recursive parameter 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 ListChildren method 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 ListFilterCriteria which does not support filtering by resource type. Use FolderListChildrenRequest with FolderListFilterCriteria for 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 ListChildren method 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 GetUploadDetails generates a new upload URL with the specified urlDuration. If you previously created an upload with a custom URL duration (e.g., via CreateFileUpload), calling GetUploadDetails will reset the URL expiry to the new duration specified (or the default 60 minutes if not specified). To avoid this, use the Upload(UploadDetails, Stream) method with pre-fetched upload details.

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 GetUploadDetails
using (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 GetUploadDetails
using (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 details
Action<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 duration
var 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 status
Action<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 Versions property is only available with the new FileAcl property and is not supported by the deprecated Acl property.

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 as 2.*.

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 as 2.*.

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 Job
Poll job status by ID.
```c#
// Define a callback action to process the job response
Action<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 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>");