Media
File uploads, image management, and asset handling
The Media module handles file uploads, image processing, and asset management.
Upload Media
/v1/businesses/{businessId}/media sdk.media.uploadBusinessMedia() Upload files to your media library. Supports uploading multiple files and/or URLs.
// Upload from file input (multiple files)
const fileInput = document.querySelector('input[type="file"]');
const files = Array.from(fileInput.files);
const result = await sdk.media.uploadBusinessMedia({
files: files, // Array of File objects
urls: [], // Can also provide URLs to download
folder: 'products',
alt: 'Product images'
});
result.forEach(media => {
console.log('Uploaded:', media.url);
console.log('Media ID:', media.id);
});
// Upload from URLs
const urlResult = await sdk.media.uploadBusinessMedia({
files: [],
urls: [
'https://example.com/image1.jpg',
'https://example.com/image2.png'
],
folder: 'imports'
});Parameters
| Name | Type | Description |
|---|---|---|
files optional | File[] | Array of files to upload |
urls optional | string[] | Array of URLs to download and store |
folder optional | string | Organization folder |
alt optional | string | Alt text for accessibility |
title optional | string | Media title |
At least one of files or urls must be provided with at least one item.
Supported File Types
| Category | Extensions |
|---|---|
| Images | .jpg, .jpeg, .png, .gif, .webp, .svg, .avif |
| Documents | .pdf, .doc, .docx, .xls, .xlsx |
| Video | .mp4, .webm, .mov |
| Audio | .mp3, .wav, .ogg |
Size Limits
- Images: 10MB
- Documents: 25MB
- Video: 100MB
- Audio: 50MB
Get Media
/v1/businesses/{businessId}/media sdk.media.getBusinessMedia() List all media files.
const result = await sdk.media.getBusinessMedia({
mimeType: 'image/jpeg',
query: 'product hero',
limit: 50,
sortField: 'uploadedAt',
sortDirection: 'desc'
});
result.items.forEach(media => {
console.log(media.id, media.url, media.size);
});Parameters
| Name | Type | Description |
|---|---|---|
ids optional | string[] | Filter by specific media IDs |
mimeType optional | string | Filter by MIME type (image/jpeg, image/png, video/mp4, etc.) |
query optional | string | Search in title and alt text |
sortField optional | string | Sort field |
sortDirection optional | asc | desc | Sort direction |
cursor optional | string | Pagination cursor |
limit required | number | Items per page |
Update Media
/v1/businesses/{businessId}/media/{mediaId} sdk.media.updateMedia() Update media metadata.
const result = await sdk.media.updateMedia({
mediaId: 'media_xyz789',
alt: 'Updated alt text',
title: 'Product Photo - Front View',
folder: 'products/featured'
});
Parameters
| Name | Type | Description |
|---|---|---|
mediaId required | string | Media ID to update |
alt optional | string | Alt text |
title optional | string | Media title |
folder optional | string | Move to folder |
Delete Media
/v1/businesses/{id}/media/{mediaId} sdk.media.deleteBusinessMedia() Delete a media file.
Deleting media that’s in use (products, nodes, etc.) may cause broken images. Check references before deleting.
const result = await sdk.media.deleteBusinessMedia({
id: 'biz_abc123',
mediaId: 'media_xyz789'
});
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Business ID |
mediaId required | string | Media ID to delete |
Image Transformations
Arky provides on-the-fly image transformations via URL parameters.
Resize
// Original URL
const originalUrl = media.url;
// https://cdn.arky.io/media/biz_abc123/image.jpg
// Resize to width 400px (height auto)
const resized = `${originalUrl}?w=400`;
// Resize to exact dimensions
const exact = `${originalUrl}?w=400&h=300`;
// Fit within bounds (maintain aspect ratio)
const fit = `${originalUrl}?w=400&h=300&fit=contain`;
// Cover (crop to fill)
const cover = `${originalUrl}?w=400&h=300&fit=cover`;
Quality
// Reduce quality for smaller file size
const compressed = `${originalUrl}?q=75`;
Format Conversion
// Convert to WebP
const webp = `${originalUrl}?format=webp`;
// Convert to AVIF
const avif = `${originalUrl}?format=avif`;
Transformation Parameters
| Parameter | Description | Example |
|---|---|---|
w | Width in pixels | ?w=400 |
h | Height in pixels | ?h=300 |
fit | Resize mode | contain, cover, fill |
q | Quality (1-100) | ?q=80 |
format | Output format | webp, avif, jpg, png |
blur | Blur amount (1-100) | ?blur=10 |
grayscale | Convert to grayscale | ?grayscale=true |
Responsive Images
Generate srcset for responsive images:
function getResponsiveSrcSet(media: Media) {
const baseUrl = media.url;
const widths = [320, 640, 960, 1280, 1920];
return widths
.map(w => `${baseUrl}?w=${w}&format=webp ${w}w`)
.join(', ');
}
// Usage in HTML
const srcSet = getResponsiveSrcSet(productImage);
// <img srcset={srcSet} sizes="(max-width: 768px) 100vw, 50vw" />
Upload with Progress
Track upload progress for large files:
async function uploadWithProgress(
files: File[],
onProgress: (percent: number) => void
) {
const formData = new FormData();
files.forEach((file, i) => {
formData.append(`files[${i}]`, file);
});
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
onProgress(percent);
}
});
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error('Upload failed'));
}
});
xhr.open('POST', `https://api.arky.io/v1/businesses/${businessId}/media`);
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
xhr.send(formData);
});
}
// Usage
await uploadWithProgress(files, (percent) => {
console.log(`Upload progress: ${percent}%`);
progressBar.style.width = `${percent}%`;
});
Bulk Upload
Upload multiple files using the SDK:
async function uploadMultiple(files: File[]) {
// The SDK handles batching automatically
const results = await sdk.media.uploadBusinessMedia({
files: files,
folder: 'bulk-import'
});
console.log(`Uploaded ${results.length} files`);
return results;
}
// Usage
const fileInput = document.querySelector('input[type="file"][multiple]');
const uploaded = await uploadMultiple([...fileInput.files]);
Media in Products/Nodes
Reference media by ID when creating products or content:
// Upload images first
const uploadResult = await sdk.media.uploadBusinessMedia({
files: [heroFile, ...galleryFiles],
folder: 'products'
});
const [heroMedia, ...galleryMedia] = uploadResult;
// Create product with media references
await sdk.eshop.createProduct({
key: 'my-product',
blocks: [
{
key: 'hero-image',
type: 'IMAGE',
content: {
mediaId: heroMedia.id
}
},
{
key: 'gallery',
type: 'GALLERY',
content: {
mediaIds: galleryMedia.map(m => m.id)
}
}
],
status: 'ACTIVE'
});
Use folders to organize media by type (products, blog, team, etc.) for easier management.