What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
Assets
Upload, retrieve, organize, and delete media assets and galleries with the Agility Management SDK in JavaScript and .NET.
The asset methods cover uploading files, browsing the media library, organizing assets into folders and galleries, and deleting them. In JavaScript the methods hang off apiClient.assetMethods; in .NET they are on the AssetsClient class, reached through client.Assets.
The .NET examples on this page use
Agility.Management.SDK2.0. If you are on 1.x, see Migrating to 2.0 for the method names.
Note: The upload APIs are not symmetrical. The JavaScript SDK posts a
FormDataobject; the .NET SDK takes a list ofAssetUploadobjects, each pairing a file name with aStreamof the file's bytes.
Returns a paginated list of media assets in the instance.
// Get paginated media list
const mediaList = await apiClient.assetMethods.getMediaList(
50, // pageSize
0, // recordOffset
guid // instance GUID
);
console.log('Total media items:', mediaList.length);
mediaList.forEach(media => {
console.log(`- ${media.fileName} (${media.size} bytes)`);
});
var mediaList = await client.Assets.GetMediaListAsync(
guid,
pageSize: 50,
recordOffset: 0
);
Console.WriteLine($"Total assets: {mediaList?.TotalCount}");
foreach (var media in mediaList?.AssetMedias ?? [])
{
Console.WriteLine($"{media.FileName} - {media.EdgeUrl}");
}
| Parameter | Description |
|---|---|
pageSize | Number of records to return per page. |
recordOffset | Zero-based index of the first record to return. |
guid | Instance GUID. |
.NET signature: Task<AssetMediaList> GetMediaListAsync(string instanceGuid, int pageSize = 20, int recordOffset = 0, DateTime? updatedSince = null, CancellationToken cancellationToken = default)
Looks up a single asset by its numeric media ID.
var asset = await client.Assets.GetAssetAsync(guid, mediaID);
Console.WriteLine($"Asset: {asset?.FileName} - {asset?.EdgeUrl}");
Signature: Task<AssetMedia> GetAssetAsync(string instanceGuid, int mediaId, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
Looks up a single asset by its CDN URL: getAssetByUrl in JavaScript, GetAssetByUrlAsync in .NET.
// Find asset by URL
const asset = await apiClient.assetMethods.getAssetByUrl(
'https://cdn.aglty.io/your-guid/media/image.jpg',
guid
);
if (asset) {
console.log('Found asset:', asset.fileName);
}
var asset = await client.Assets.GetAssetByUrlAsync(
guid,
"https://cdn.aglty.io/your-guid/media/image.jpg"
);
if (asset != null)
{
Console.WriteLine($"Found: {asset.FileName} (ID: {asset.MediaID})");
}
.NET signature: Task<AssetMedia> GetAssetByUrlAsync(string instanceGuid, string url, CancellationToken cancellationToken = default)
Both SDKs upload one or more files into a folder path in the Agility media library, optionally assigning them to a gallery. In JavaScript, pass -1 for the gallery ID when the files do not belong to a gallery; in .NET, leave galleryId out. Use an empty folder path to upload to the root.
const FormData = require('form-data');
const fs = require('fs');
// Create form data
const form = new FormData();
form.append('files', fs.createReadStream('hero-image.jpg'), 'hero-image.jpg');
const uploadedAssets = await apiClient.assetMethods.upload(
form,
'images/heroes', // folderPath ('' for root)
guid,
-1 // galleryId (-1 for no gallery)
);
const uploadedAsset = uploadedAssets[0];
console.log('Asset URL:', uploadedAsset.url);
console.log('Media ID:', uploadedAsset.mediaID);
using Agility.Management.Sdk.Clients;
await using var hero = File.OpenRead("/path/to/directory/hero-image.jpg");
await using var logo = File.OpenRead("/path/to/directory/logo.png");
var uploaded = await client.Assets.UploadAsync(
guid,
"images/heroes", // folder path in Agility
[
new AssetUpload("hero-image.jpg", hero, "image/jpeg"),
new AssetUpload("logo.png", logo, "image/png"),
]
// galleryId: pass a gallery ID to add the files to it
);
foreach (var media in uploaded)
{
Console.WriteLine($"Uploaded: {media.FileName} - {media.EdgeUrl}");
}
| JavaScript parameter | .NET parameter | Description |
|---|---|---|
form | files | JavaScript: a FormData instance with one or more files entries. .NET: a list of AssetUpload(fileName, stream, contentType). |
folderPath | folderPath | Destination folder path in the Agility media library. Empty string uploads to the root. |
guid | instanceGuid | Instance GUID. First argument in .NET. |
galleryId | galleryId | Gallery to add the assets to; -1 for none in JavaScript, omit it in .NET. |
.NET signature: Task<List<AssetMedia>> UploadAsync(string instanceGuid, string folderPath, IReadOnlyCollection<AssetUpload> files, int? galleryId = null, string focalX = null, string focalY = null, CancellationToken cancellationToken = default)
Both SDKs return a collection of the created media items, so the uploaded asset's url / EdgeUrl and mediaID / MediaID are available immediately.
A single .NET UploadAsync call already accepts several files. In JavaScript, loop over the files and upload them individually, collecting successes and failures.
async function uploadMultipleFiles(
filePaths: string[],
folderPath: string,
guid: string
) {
const results = [];
for (const filePath of filePaths) {
try {
const form = new FormData();
const fileName = path.basename(filePath);
form.append('files', fs.createReadStream(filePath), fileName);
const uploadedAssets = await apiClient.assetMethods.upload(
form,
folderPath,
guid,
-1
);
results.push({
success: true,
fileName,
asset: uploadedAssets[0]
});
} catch (error) {
results.push({
success: false,
fileName: path.basename(filePath),
error: error.message
});
}
}
return results;
}
The folder path is just a string, so you can derive it from the file extension and the current date to keep the media library tidy.
// Organize assets by type and date
async function organizeAssetUpload(
filePath: string,
guid: string
) {
const fileName = path.basename(filePath);
const fileExt = path.extname(fileName).toLowerCase();
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
// Determine folder based on file type
let folderPath = '';
if (['.jpg', '.jpeg', '.png', '.webp', '.gif'].includes(fileExt)) {
folderPath = `images/${year}/${month}`;
} else if (['.pdf', '.doc', '.docx'].includes(fileExt)) {
folderPath = `documents/${year}/${month}`;
} else if (['.mp4', '.mov', '.avi'].includes(fileExt)) {
folderPath = `videos/${year}/${month}`;
} else {
folderPath = `other/${year}/${month}`;
}
const form = new FormData();
form.append('files', fs.createReadStream(filePath), fileName);
return await apiClient.assetMethods.upload(form, folderPath, guid, -1);
}
Creates a folder in the Agility media library.
var folder = await client.Assets.CreateFolderAsync(
guid,
originKey: "images/new-folder"
);
Console.WriteLine($"Created folder: {folder?.OriginKey}");
Signature: Task<AssetMedia> CreateFolderAsync(string instanceGuid, string originKey, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK — in JavaScript, uploading to a folder path creates it implicitly.
Moves an asset to a different folder.
var moved = await client.Assets.MoveAssetAsync(
guid,
mediaID,
newFolder: "images/archive"
);
Console.WriteLine($"Moved to: {moved?.OriginKey}");
Signature: Task<AssetMedia> MoveAssetAsync(string instanceGuid, int mediaId, string newFolder, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
Deletes an entire folder, identified by its origin key (the folder path). Pass null for the media ID when deleting a folder rather than a file.
// Delete entire folder
await apiClient.assetMethods.deleteFolder(
'images/old-folder', // originKey (folder path)
guid,
null // mediaId (null for folder deletion)
);
console.log('Folder deleted successfully');
// mediaId is optional: pass the folder's media ID when you know it
await client.Assets.DeleteFolderAsync(guid, "images/old-folder");
.NET signature: Task DeleteFolderAsync(string instanceGuid, string originKey, int? mediaId = null, CancellationToken cancellationToken = default)
Deletes a single asset by media ID.
// Delete asset by media ID
await apiClient.assetMethods.deleteFile(mediaId, guid);
console.log('Asset deleted successfully');
// Returns no value. A failure throws AgilityManagementException.
await client.Assets.DeleteAssetAsync(guid, mediaID);
.NET signature: Task DeleteAssetAsync(string instanceGuid, int mediaId, CancellationToken cancellationToken = default)
Galleries (media groupings) let you group assets together. Both SDKs can list galleries and fetch one by name; the .NET SDK additionally supports fetching by ID, saving, and deleting.
Returns a paginated list of galleries, optionally filtered by a search term.
// Get all galleries
const galleries = await apiClient.assetMethods.getGalleries(
guid,
'', // searchTerm
50, // pageSize
0 // rowIndex
);
galleries.forEach(gallery => {
console.log(`Gallery: ${gallery.galleryName} (${gallery.mediaCount} items)`);
});
var galleries = await client.Assets.GetGalleriesAsync(
guid,
search: null, // optional search term
pageSize: 50,
rowIndex: 0
);
foreach (var gallery in galleries?.AssetMediaGroupings ?? [])
{
Console.WriteLine($"{gallery.Name} (ID: {gallery.MediaGroupingID})");
}
| Parameter | Description |
|---|---|
guid | Instance GUID. |
searchTerm / search | Optional term to filter galleries by name. |
pageSize | Number of galleries to return. |
rowIndex | Zero-based index of the first gallery to return. |
.NET signature: Task<AssetGalleries> GetGalleriesAsync(string instanceGuid, string search = null, int? pageSize = null, int? rowIndex = null, CancellationToken cancellationToken = default)
// Find specific gallery
const gallery = await apiClient.assetMethods.getGalleryByName(
guid,
'Product Images'
);
if (gallery) {
console.log('Gallery ID:', gallery.galleryID);
console.log('Media count:', gallery.mediaCount);
}
var gallery = await client.Assets.GetGalleryByNameAsync(guid, "Product Images");
Console.WriteLine($"Gallery ID: {gallery?.MediaGroupingID}, Name: {gallery?.Name}");
.NET signature: Task<AssetMediaGrouping> GetGalleryByNameAsync(string instanceGuid, string galleryName, CancellationToken cancellationToken = default)
var gallery = await client.Assets.GetGalleryAsync(guid, galleryId);
Console.WriteLine($"Gallery: {gallery?.Name}");
Signature: Task<AssetMediaGrouping> GetGalleryAsync(string instanceGuid, int galleryId, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
Creates or updates a gallery. Use MediaGroupingID = -1 to create a new one.
using Agility.Management.Sdk.Models;
var gallery = new AssetMediaGrouping
{
MediaGroupingID = -1, // -1 for new
Name = "New Gallery"
};
var saved = await client.Assets.SaveGalleryAsync(guid, gallery);
Console.WriteLine($"Saved gallery ID: {saved?.MediaGroupingID}");
Signature: Task<AssetMediaGrouping> SaveGalleryAsync(string instanceGuid, AssetMediaGrouping gallery, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
// Returns no value. A failure throws AgilityManagementException.
await client.Assets.DeleteGalleryAsync(guid, galleryId);
Signature: Task DeleteGalleryAsync(string instanceGuid, int galleryId, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
Retrieves the default asset container configuration for the instance.
var container = await client.Assets.GetDefaultContainerAsync(guid);
Console.WriteLine($"Container ID: {container?.ContainerID}");
Signature: Task<AssetContainer> GetDefaultContainerAsync(string instanceGuid, CancellationToken cancellationToken = default)
Not documented for the JavaScript SDK.
Asset calls throw on failure, so wrap them in a try/catch. In .NET the exception is AgilityManagementException, which carries the HTTP status code, the API's error message and a request ID.
try {
const asset = await apiClient.assetMethods.getAssetByUrl(url, guid);
} catch (error) {
console.error('Error:', error.message);
}
try
{
var asset = await client.Assets.GetAssetAsync(guid, mediaID);
}
catch (AgilityManagementException ex)
{
Console.Error.WriteLine($"Error ({ex.StatusCode}): {ex.ApiMessage ?? ex.Message}");
}