Official SDK for the Sirv REST API. Works with JavaScript, Node.js, and TypeScript for image management, 360 spins, CDN delivery, and more.
- Works in Browser, Node.js, and TypeScript
- Full TypeScript type definitions included
- Automatic token management with refresh
- Async iterators for pagination (Node.js/TypeScript)
- Retry logic with exponential backoff
- All 40+ API endpoints implemented
npm install @sirv/rest-api-jsOr with yarn:
yarn add @sirv/rest-api-js<script src="https://unpkg.com/@sirv/rest-api-js/dist/sirv.min.js"></script><script src="https://unpkg.com/@sirv/rest-api-js/dist/sirv.min.js"></script>
<script>
const sirv = new SirvClient({
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
});
sirv.connect().then(() => {
sirv.getAccountInfo().then(account => {
console.log('CDN URL:', account.cdnURL);
});
});
</script>const { SirvClient } = require('@sirv/rest-api-js');
const sirv = new SirvClient({
clientId: process.env.SIRV_CLIENT_ID,
clientSecret: process.env.SIRV_CLIENT_SECRET
});
async function main() {
await sirv.connect();
const account = await sirv.getAccountInfo();
console.log('CDN URL:', account.cdnURL);
// Upload from file path (Node.js only)
await sirv.uploadFile('/images/photo.jpg', './local-photo.jpg');
}
main();import { SirvClient, AccountInfo, SearchResult } from '@sirv/rest-api-js';
const client = new SirvClient({
clientId: process.env.SIRV_CLIENT_ID!,
clientSecret: process.env.SIRV_CLIENT_SECRET!
});
async function main(): Promise<void> {
await client.connect();
const account: AccountInfo = await client.getAccountInfo();
console.log('CDN URL:', account.cdnURL);
// Use async iterators for pagination
for await (const file of client.iterateSearchResults({ query: 'product' })) {
console.log(file.filename);
}
}
main();const sirv = new SirvClient({
// Required
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
// Optional
baseUrl: 'https://api.sirv.com', // API base URL
autoRefreshToken: true, // Auto-refresh token before expiry
tokenRefreshBuffer: 60, // Seconds before expiry to refresh
timeout: 30000, // Request timeout in ms
maxRetries: 3 // Retry failed requests
});| Option | Type | Default | Description |
|---|---|---|---|
clientId |
string | - | Your Sirv API client ID (required) |
clientSecret |
string | - | Your Sirv API client secret (required) |
baseUrl |
string | https://api.sirv.com | API base URL |
autoRefreshToken |
boolean | true | Automatically refresh tokens |
tokenRefreshBuffer |
number | 60 | Seconds before expiry to refresh |
timeout |
number | 30000 | Request timeout in milliseconds |
maxRetries |
number | 3 | Max retries for failed requests |
// Connect and obtain token (called automatically when needed)
await sirv.connect();
// Optional: Request a token with custom expiry time (5-604800 seconds)
await sirv.connect(3600); // Token valid for 1 hour
// Check if connected
if (sirv.isConnected()) {
console.log('Connected!');
}
// Get current token
const token = sirv.getAccessToken();The connect() method accepts an optional expiresIn parameter to customize token lifetime:
- Range: 5 to 604800 seconds (7 days)
- Default: 1200 seconds (20 minutes)
// Get account info
const account = await sirv.getAccountInfo();
// Update account settings
await sirv.updateAccount({ minify: { enabled: true } });
// Get rate limits
const limits = await sirv.getAccountLimits();
// Get storage info
const storage = await sirv.getStorageInfo();
// Get account users
const users = await sirv.getAccountUsers();
// Get billing plan
const plan = await sirv.getBillingPlan();
// Search events
const events = await sirv.searchEvents({ level: 'error' });
// Mark events seen
await sirv.markEventsSeen(['event-id-1', 'event-id-2']);// Get current user
const user = await sirv.getUserInfo();
// Get specific user
const user = await sirv.getUserInfo('user-id');// Get file info
const info = await sirv.getFileInfo('/images/photo.jpg');
// Read folder contents
const folder = await sirv.readFolderContents('/images');
// Iterate folder (Node.js/TypeScript - handles pagination)
for await (const file of sirv.iterateFolderContents('/images')) {
console.log(file.filename);
}
// Search files
const results = await sirv.searchFiles({
query: 'product',
size: 20,
sort: { field: 'mtime', order: 'desc' },
filters: { extension: ['jpg', 'png'] }
});
// Iterate search results (Node.js/TypeScript)
for await (const file of sirv.iterateSearchResults({ query: 'product' })) {
console.log(file.filename);
}
// Scroll through results manually
const moreResults = await sirv.scrollSearch(results.scrollId);// Upload - Browser (File or Blob)
const fileInput = document.getElementById('fileInput');
await sirv.uploadFile('/uploads/photo.jpg', fileInput.files[0]);
// Upload - Node.js (file path)
await sirv.uploadFile('/images/photo.jpg', './local-file.jpg');
// Upload - Node.js (Buffer)
const buffer = fs.readFileSync('./photo.jpg');
await sirv.uploadFile('/images/photo.jpg', buffer);
// Upload - Node.js (Stream)
const stream = fs.createReadStream('./large-file.jpg');
await sirv.uploadFile('/images/large.jpg', stream);
// Download to Buffer/ArrayBuffer
const data = await sirv.downloadFile('/images/photo.jpg');
// Download to file (Node.js only)
await sirv.downloadFileTo('/images/photo.jpg', './downloaded.jpg');// Create folder
await sirv.createFolder('/new-folder');
// Delete file
await sirv.deleteFile('/images/old-photo.jpg');
// Batch delete
const result = await sirv.batchDelete(['/img1.jpg', '/img2.jpg']);
// Copy file
await sirv.copyFile({ from: '/a.jpg', to: '/b.jpg' });
// Rename/move
await sirv.renameFile({ from: '/old.jpg', to: '/new.jpg' });
// Fetch from URL
await sirv.fetchUrl({
url: 'https://example.com/image.jpg',
filename: '/fetched/image.jpg',
wait: true
});
// Create ZIP
const zipResult = await sirv.batchZip({
filenames: ['/img1.jpg', '/img2.jpg'],
filename: '/archive.zip'
});// Get all metadata
const meta = await sirv.getFileMeta('/images/photo.jpg');
// Set metadata
await sirv.setFileMeta('/images/photo.jpg', {
title: 'Product Photo',
description: 'Main image',
tags: ['product', 'featured']
});
// Title
const { title } = await sirv.getFileTitle('/images/photo.jpg');
await sirv.setFileTitle('/images/photo.jpg', 'New Title');
// Description
const { description } = await sirv.getFileDescription('/images/photo.jpg');
await sirv.setFileDescription('/images/photo.jpg', 'New description');
// Tags
const { tags } = await sirv.getFileTags('/images/photo.jpg');
await sirv.addFileTags('/images/photo.jpg', ['new', 'tags']);
await sirv.removeFileTags('/images/photo.jpg', ['old']);
// Product metadata
const product = await sirv.getProductMeta('/products/item.jpg');
await sirv.setProductMeta('/products/item.jpg', {
id: 'SKU-123',
name: 'Product Name',
brand: 'Brand'
});
// Approval flag
const { approved } = await sirv.getApprovalFlag('/images/photo.jpg');
await sirv.setApprovalFlag('/images/photo.jpg', true);const options = await sirv.getFolderOptions('/products');
await sirv.setFolderOptions('/products', {
scanSpins: true,
allowListing: false
});const jwt = await sirv.generateJwt({
filename: '/private/document.pdf',
expiresIn: 3600 // 1 hour
});
console.log('Protected URL:', jwt.url);// Convert spin to video
const video = await sirv.spin2Video({
filename: '/spins/product.spin',
options: { width: 1920, height: 1080, loops: 2 }
});
// Convert video to spin
const spin = await sirv.video2Spin({
filename: '/videos/product.mp4',
targetFilename: '/spins/product.spin',
options: { frames: 36 }
});
// Export to marketplaces
await sirv.exportSpinToAmazon({ filename: '/spins/p.spin', asin: 'B08XXX' });
await sirv.exportSpinToWalmart({ filename: '/spins/p.spin', productId: 'xxx' });
await sirv.exportSpinToHomeDepot({ filename: '/spins/p.spin', productId: 'xxx' });
await sirv.exportSpinToLowes({ filename: '/spins/p.spin', productId: 'xxx' });
await sirv.exportSpinToGrainger({ filename: '/spins/p.spin', productId: 'xxx' });// Get POIs
const pois = await sirv.getPointsOfInterest('/spins/product.spin');
// Set POI
await sirv.setPointOfInterest('/spins/product.spin', {
name: 'Feature 1',
x: 0.5,
y: 0.3,
frame: 10
});
// Delete POI
await sirv.deletePointOfInterest('/spins/product.spin', 'Feature 1');// HTTP stats
const httpStats = await sirv.getHttpStats({
from: '2024-01-01',
to: '2024-01-31'
});
// Spin views (max 5-day range)
const spinStats = await sirv.getSpinViewsStats({
from: '2024-01-01',
to: '2024-01-05'
});
// Storage stats
const storageStats = await sirv.getStorageStats({
from: '2024-01-01',
to: '2024-01-31'
});import { SirvApiError } from '@sirv/rest-api-js';
try {
await sirv.uploadFile('/images/photo.jpg', file);
} catch (error) {
if (error instanceof SirvApiError) {
console.error('API Error:', error.message);
console.error('Status:', error.statusCode);
console.error('Code:', error.errorCode);
} else {
throw error;
}
}All types are exported for use in TypeScript projects:
import {
SirvClient,
// Configuration
SirvClientConfig,
TokenResponse,
// Account
AccountInfo,
StorageInfo,
AccountLimits,
AccountUser,
BillingPlan,
AccountEvent,
// Files
FileInfo,
FileMeta,
ProductMeta,
FolderContents,
SearchParams,
SearchResult,
// Spins
SpinConvertParams,
PointOfInterest,
// Stats
HttpStats,
SpinViewStats,
StorageStats,
// Errors
SirvApiError
} from '@sirv/rest-api-js';- Browser: Modern browser with Fetch API support
- Node.js: Version 14.0.0 or higher
- TypeScript: Version 4.7+ (recommended)
- Log in to your Sirv account
- Go to Settings > API
- Create a new API client
- Copy your Client ID and Client Secret
Never expose your Client Secret in client-side code in production. For browser applications, consider using a backend proxy to handle API authentication.
MIT License - see LICENSE for details.