Skip to content

Latest commit

 

History

History
481 lines (368 loc) · 11.1 KB

File metadata and controls

481 lines (368 loc) · 11.1 KB

@sirv/rest-api-js

Official SDK for the Sirv REST API. Works with JavaScript, Node.js, and TypeScript for image management, 360 spins, CDN delivery, and more.

Features

  • 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

Installation

npm install @sirv/rest-api-js

Or with yarn:

yarn add @sirv/rest-api-js

CDN (Browser)

<script src="https://unpkg.com/@sirv/rest-api-js/dist/sirv.min.js"></script>

Quick Start

JavaScript (Browser)

<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>

Node.js

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();

TypeScript

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();

Configuration

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

API Reference

Authentication

// 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)

Account API

// 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']);

User API

// Get current user
const user = await sirv.getUserInfo();

// Get specific user
const user = await sirv.getUserInfo('user-id');

Files API

// 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 & Download

// 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');

File Operations

// 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'
});

Metadata API

// 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);

Folder Options

const options = await sirv.getFolderOptions('/products');

await sirv.setFolderOptions('/products', {
  scanSpins: true,
  allowListing: false
});

JWT API

const jwt = await sirv.generateJwt({
  filename: '/private/document.pdf',
  expiresIn: 3600  // 1 hour
});
console.log('Protected URL:', jwt.url);

Spins/360 API

// 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' });

Points of Interest API

// 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');

Statistics API

// 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'
});

Error Handling

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;
  }
}

TypeScript Types

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';

Requirements

  • Browser: Modern browser with Fetch API support
  • Node.js: Version 14.0.0 or higher
  • TypeScript: Version 4.7+ (recommended)

Getting API Credentials

  1. Log in to your Sirv account
  2. Go to Settings > API
  3. Create a new API client
  4. Copy your Client ID and Client Secret

Security Note

Never expose your Client Secret in client-side code in production. For browser applications, consider using a backend proxy to handle API authentication.

License

MIT License - see LICENSE for details.

Links