npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@outfitcanvas/fitview-sdk

v1.0.3

Published

TypeScript SDK for FitView API - virtual try-on service

Readme

FitView TypeScript SDK

Official TypeScript SDK for the FitView API - virtual try-on service.

Installation

npm install @outfitcanvas/fitview-sdk
# or
yarn add @outfitcanvas/fitview-sdk
# or
pnpm add @outfitcanvas/fitview-sdk

API key

To use the FitView API you need an API key. Purchase and register at https://outfitcanvas.app to acquire your API key. Use it in the client as shown below.

Quick Start

import { FitViewClient, OutfitCanvasModel } from '@outfitcanvas/fitview-sdk';

// Initialize the client
const client = new FitViewClient({
  apiKey: 'pk_live_your_api_key_here',
  baseURL: 'https://api.fitview.io', // Optional, defaults to production
});

// Generate a virtual try-on
const result = await client.generateFitView({
  person_image: 'https://example.com/person.jpg',
  garment_image: 'https://example.com/garment.jpg',
  model: OutfitCanvasModel.CanvasStandard,
  quality: 'high',
});

// Wait for completion
const completed = await result.waitForCompletion();

// Get the result image URL
console.log('FitView URL:', completed.fitviewUrl);

Security: Prefer environment variables for your API key (e.g. process.env.FITVIEW_API_KEY). Never embed API keys in client-side or public code—use the SDK only in server-side or trusted environments.

Quick reference: For a one-page TypeScript method/signature overview (IDE autocomplete and LLM code generation), see Quick Reference — TypeScript.

API Reference

FitViewClient

Main client class for interacting with the FitView API.

Constructor

const client = new FitViewClient({
  apiKey: string,              // Required: Your API key
  baseURL?: string,            // Optional: API base URL (default: https://api.fitview.io)
  timeout?: number,            // Optional: Request timeout in ms (default: 300000)
  apiVersion?: string,         // Optional: API version (default: 'v1')
  maxRetries?: number,        // Optional: Retries for 429/5xx (default: 3, set 0 to disable)
  retryDelay?: number,        // Optional: Base delay in ms between retries (default: 1000)
  authMethod?: 'bearer' | 'apiKey', // Optional: Bearer token (default) or X-API-Key header
  fetch?: typeof fetch,        // Optional: Custom fetch implementation
  headers?: Record<string, string>, // Optional: Additional headers
  validateInputImages?: boolean,   // Optional: Validate image format/size before sending (default: true)
  optimizeImages?: boolean,        // Optional: Optimize base64 images client-side when sharp is available (default: false)
  optimizeImageOptions?: { maxDimension?: number; jpegQuality?: number; outputFormat?: 'jpeg' | 'png' | 'webp' | 'original' },
});

Methods

generateFitView(request: FitViewRequest): Promise<FitViewResult>

Generate a virtual try-on result.

const result = await client.generateFitView({
  person_image: 'https://example.com/person.jpg',
  garment_image: 'https://example.com/garment.jpg',
  model: OutfitCanvasModel.CanvasStandard,
  quality: 'high',
  use_case: 'fashion',
  idempotency_key: '550e8400-e29b-41d4-a716-446655440000',
  webhook_url: 'https://your-app.com/webhook',
});
getFitView(jobId: string): Promise<FitViewResult>

Get the status of a FitView job.

const result = await client.getFitView('fv_abc123');
console.log(result.status); // 'queued' | 'processing' | 'completed' | 'failed'
batchGenerateFitView(requests: FitViewRequest[]): Promise<FitViewBatchResponse>

Generate multiple virtual try-on results in a batch (max 50).

const batch = await client.batchGenerateFitView([
  { person_image: '...', garment_image: '...' },
  { person_image: '...', garment_image: '...' },
]);

console.log(`Success: ${batch.success_count}, Failed: ${batch.failure_count}`);
listModels(): Promise<ModelInfo[]>

List available models for your account tier.

const models = await client.listModels();
models.forEach(model => {
  console.log(`${model.displayName}: ${model.creditCost} credits`);
});
waitForFitView(jobId: string, options?: WaitOptions): Promise<FitViewResult>

Wait for a job to complete with polling. Defaults (used when you omit options): wait 10 seconds before the first status fetch, then poll every 2 seconds until done.

Warning: Consult FitView support before changing initialDelay or interval. Other values may affect rate limits, reliability, and support eligibility.

// Use defaults: 10s before first fetch, 2s between polls (recommended)
const result = await client.waitForFitView('fv_abc123');

// Or customize (consult support before changing polling defaults)
const result = await client.waitForFitView('fv_abc123', {
  timeout: 300000,
  initialDelay: 10000,   // default: 10s before first fetch
  interval: 2000,       // default: 2s between subsequent polls
  onProgress: (result) => console.log(`Status: ${result.status}`),
});
getRateLimitAddons(): Promise<RateLimitAddonsResponse>

Get active rate limit add-ons and total boost (billing).

const { active_addons, total_boost } = await client.getRateLimitAddons();
healthCheck(): Promise<{ status: string; timestamp?: string }>

Basic health check (no auth). Returns { status, timestamp }.

readinessCheck(): Promise<HealthStatus>

Readiness check with dependency status (no auth). Returns status, version, uptime, checks.

livenessCheck(): Promise<{ status: string }>

Liveness check (no auth). Returns { status: 'alive' }.

verifyWebhook(payload: string | Buffer, signature: string, secret: string): boolean

Verify webhook signature.

const isValid = client.verifyWebhook(
  rawBody,
  signature,
  webhookSecret
);

FitViewResult

Wrapper class for FitView API responses with convenient methods.

Properties

  • jobId: string - Job identifier
  • status: 'queued' | 'processing' | 'completed' | 'failed' - Current status
  • fitviewUrl?: string - URL of the generated image (if completed)
  • thumbnailUrl?: string - URL of the thumbnail (if available)
  • modelUsed?: string - Model used for generation
  • modelVersion?: string - Model version
  • generationTimeMs?: number - Generation time in milliseconds
  • enrichedData?: EnrichedData - Additional enriched data
  • error?: FitViewError - Error information (if failed)
  • metadata: ResponseMetadata - Response metadata

Methods

isCompleted(): boolean

Check if the job is completed.

isFailed(): boolean

Check if the job has failed.

isProcessing(): boolean

Check if the job is still processing.

download(): Promise<Buffer | Blob>

Download the fitview image.

const image = await result.download();
// In Node.js: Buffer
// In browser: Blob
refresh(): Promise<FitViewResult>

Refresh the result by fetching the latest status.

const updated = await result.refresh();
waitForCompletion(options?: WaitOptions): Promise<FitViewResult>

Wait for the job to complete. Uses the same defaults as waitForFitView (10s before first fetch, 2s between polls). Consult FitView support before changing initialDelay or interval.

// Defaults (recommended)
const completed = await result.waitForCompletion();

// With options (consult support before changing polling defaults)
const completed = await result.waitForCompletion({
  timeout: 300000,
  initialDelay: 10000,
  interval: 2000,
  onProgress: (result) => console.log(result.status),
});

Examples

A runnable quick start (same flow as the Python example) is in examples/:

  • TypeScript: npx tsx examples/quickstart.ts (from packages/sdk-typescript)
  • JavaScript: npm run build && node examples/quickstart.mjs

Set FITVIEW_API_KEY and optionally FITVIEW_BASE_URL in the environment.

Basic Generation

import { FitViewClient, OutfitCanvasModel } from '@outfitcanvas/fitview-sdk';

const client = new FitViewClient({
  apiKey: process.env.FITVIEW_API_KEY!,
});

// Generate
const result = await client.generateFitView({
  person_image: 'https://example.com/person.jpg',
  garment_image: 'https://example.com/garment.jpg',
  model: OutfitCanvasModel.CanvasStandard,
});

// Wait for completion
const completed = await result.waitForCompletion();

// Use the result
if (completed.isCompleted()) {
  console.log('Image URL:', completed.fitviewUrl);
  
  // Download the image
  const image = await completed.download();
  // Save or process the image...
}

Image sources (URLs vs device)

  • Images on your servers: Pass a public HTTP or HTTPS URL in person_image and garment_image. FitView fetches the image from that URL; no separate upload step is required. The URL must be reachable by the FitView API (public or allowlisted).
  • Images on user devices: The API accepts base64 (or data URL) directly in person_image and garment_image for generate requests—no upload step required. For very large images or when you prefer to upload once and reuse the URL, use upload first, then generate: call client.uploadImage(base64) or client.uploadImageFromFile(filePath) (Node.js) to get a URL, then pass that URL into generateFitView.

Using Base64 Images

const result = await client.generateFitView({
  person_image: {
    type: 'base64',
    data: 'data:image/jpeg;base64,/9j/4AAQSkZJRg...',
  },
  garment_image: {
    type: 'base64',
    data: 'data:image/jpeg;base64,/9j/4AAQSkZJRg...',
  },
});

Upload from file (Node.js)

import { FitViewClient } from '@outfitcanvas/fitview-sdk';

const client = new FitViewClient({ apiKey: process.env.FITVIEW_API_KEY! });

// Upload a local file and get a URL for generate
const { url } = await client.uploadImageFromFile('/path/to/person.jpg');
const result = await client.generateFitView({
  person_image: url,
  garment_image: 'https://example.com/garment.jpg',
});

Idempotency key (safe retries)

To retry a create-job request without creating duplicate jobs, send an idempotency_key. Generate a new UUID per logical request:

import { FitViewClient, generateIdempotencyKey } from '@outfitcanvas/fitview-sdk';

const client = new FitViewClient({ apiKey: process.env.FITVIEW_API_KEY! });

const result = await client.generateFitView({
  person_image: 'https://example.com/person.jpg',
  garment_image: 'https://example.com/garment.jpg',
  idempotency_key: generateIdempotencyKey(), // or FitViewClient.generateIdempotencyKey()
});

Batch Processing

const batch = await client.batchGenerateFitView([
  {
    person_image: 'https://example.com/person1.jpg',
    garment_image: 'https://example.com/garment1.jpg',
  },
  {
    person_image: 'https://example.com/person2.jpg',
    garment_image: 'https://example.com/garment2.jpg',
  },
]);

// Process results
batch.results.forEach((item, index) => {
  if (item.response) {
    console.log(`Request ${index + 1}: ${item.response.job_id}`);
  } else if (item.error) {
    console.error(`Request ${index + 1} failed:`, item.error.message);
  }
});

Error Handling

import {
  FitViewClient,
  FitViewValidationError,
  FitViewInsufficientCreditsError,
  FitViewRateLimitError,
} from '@outfitcanvas/fitview-sdk';

try {
  const result = await client.generateFitView({
    person_image: 'invalid-url',
    garment_image: 'https://example.com/garment.jpg',
  });
} catch (error) {
  if (error instanceof FitViewValidationError) {
    console.error('Validation error:', error.validationErrors);
  } else if (error instanceof FitViewInsufficientCreditsError) {
    console.error(`Need ${error.required} credits, have ${error.available}`);
  } else if (error instanceof FitViewRateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else {
    console.error('Unexpected error:', error);
  }
}

Webhook Verification

import express from 'express';

const app = express();

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-fitview-signature'] as string;
  const secret = process.env.WEBHOOK_SECRET!;
  
  const isValid = client.verifyWebhook(
    req.body,
    signature,
    secret
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  const payload = JSON.parse(req.body.toString());
  // Process webhook...
  
  res.status(200).send('OK');
});

Custom Timeout, Retries, and X-API-Key

const client = new FitViewClient({
  apiKey: process.env.FITVIEW_API_KEY!,
  timeout: 60000,    // 1 minute timeout
  maxRetries: 3,     // Retry 429 and 5xx (default)
  retryDelay: 1000,  // Base delay before retry (exponential backoff)
  authMethod: 'apiKey', // Use X-API-Key header instead of Bearer
});

// With custom wait options (consult support before changing initialDelay/interval)
const result = await client.waitForFitView('fv_abc123', {
  timeout: 600000,
  initialDelay: 10000,
  interval: 5000,
  onProgress: (result) => {
    console.log(`Progress: ${result.status}`);
  },
});

Listing Available Models

const models = await client.listModels();

console.log('Available models:');
models.forEach(model => {
  console.log(`
    ${model.displayName} (${model.id})
    Cost: ${model.creditCost} credits
    Estimated latency: ${model.estimatedLatencyMs}ms
  `);
});

Types

FitViewRequest

interface FitViewRequest {
  person_image: string | ImageInput;
  garment_image: string | ImageInput;
  model?: OutfitCanvasModel;
  quality?: 'fast' | 'balanced' | 'high';
  use_case?: 'casual' | 'fashion' | 'formal';
  user_id?: string;
  session_id?: string;
  product_id?: string;
  idempotency_key?: string;
  webhook_url?: string;
  context?: UserContext;
  metadata?: Record<string, any>;
}

OutfitCanvasModel

enum OutfitCanvasModel {
  CanvasPro = 'canvas-pro',
  CanvasProFast = 'canvas-pro-fast',
  CanvasStandard = 'canvas-standard',
  CanvasPlus = 'canvas-plus',
  CanvasExpress = 'canvas-express',
  CanvasInstant = 'canvas-instant',
  CanvasFashion = 'canvas-fashion',
  CanvasCasual = 'canvas-casual',
  CanvasFormal = 'canvas-formal',
  Canvas4K = 'canvas-4k',
  CanvasVideo = 'canvas-video',
}

Image validation and optimization

To reduce unnecessary backend compute, the SDK can validate and optionally optimize images on the client:

  • Validation (default: on)
    Before each request, the SDK checks that base64 images are valid, within the 20MB limit, and in a supported format (JPEG, PNG, WebP, HEIC/HEIF). Invalid inputs throw FitViewValidationError immediately, so you get clear errors without calling the API. Set validateInputImages: false in the client to disable.

  • Optimization (default: off)
    With optimizeImages: true, base64 images are resized (default max 2048px) and recompressed (e.g. JPEG 85%) on the client when sharp is installed. This sends smaller payloads and can reduce backend processing. URL inputs are not optimized. Install sharp optionally: npm install sharp.

Best practices

  • Pre-optimize images when possible: max dimension ~2048px, under ~5MB, JPEG/PNG/WebP. The API accepts up to 20MB and the same formats; smaller, well-formatted images are faster and cheaper to process.
  • Use validation (default) to fail fast on bad input.
  • Enable optimizeImages in Node.js if you often send large base64 images and have sharp installed.
import { FitViewClient, validateBase64Image, optimizeBase64Image } from '@outfitcanvas/fitview-sdk';

// Optional: validate or optimize a single image before building the request
const result = validateBase64Image('data:image/jpeg;base64,...');
if (!result.valid) {
  console.error(result.message);
}
const optimized = await optimizeBase64Image('data:image/jpeg;base64,...', { maxDimension: 2048, jpegQuality: 85 });

// Client with validation (default) and optional optimization
const client = new FitViewClient({
  apiKey: process.env.FITVIEW_API_KEY!,
  validateInputImages: true,
  optimizeImages: true,
  optimizeImageOptions: { maxDimension: 2048, jpegQuality: 85 },
});

Error Handling

The SDK provides specific error classes for different scenarios:

  • FitViewError - Base error class
  • FitViewAPIError - API errors (4xx, 5xx)
  • FitViewValidationError - Validation errors (400)
  • FitViewAuthenticationError - Authentication errors (401)
  • FitViewInsufficientCreditsError - Insufficient credits (402)
  • FitViewRateLimitError - Rate limit errors (429)
  • FitViewTimeoutError - Timeout errors
  • FitViewNetworkError - Network errors

Troubleshooting

getaddrinfo ENOTFOUND api.fitview.io (or similar)

This means the hostname of the API could not be resolved (DNS failure). Common causes:

  1. Wrong or placeholder base URL – The default baseURL is https://api.fitview.io. If your API is hosted elsewhere (e.g. your own Cloud Run URL), set the correct URL when creating the client:

    const client = new FitViewClient({
      apiKey: process.env.FITVIEW_API_KEY!,
      baseURL: process.env.FITVIEW_BASE_URL || 'https://your-actual-api.run.app',
    });

    Or set the FITVIEW_BASE_URL environment variable (e.g. https://fitview-api-xxxxx-uc.a.run.app without /api/v1).

  2. Network or DNS issues – Firewall, VPN, or local DNS may block or fail to resolve the host. Try from another network or verify the API URL in a browser/curl.

  3. Custom domain not set up – If api.fitview.io is not yet configured in DNS for your environment, use the actual API URL provided by your dashboard or deployment (e.g. Cloud Run URL) as baseURL.

Requirements

  • Node.js 18.0.0 or higher
  • TypeScript 5.0.0 or higher (for TypeScript projects)

Publishing (maintainers)

To publish to npm via GitHub Actions, push a tag matching sdk-ts-v* (e.g. sdk-ts-v1.0.1). Ensure the repository secret NPM_TOKEN is set (npm Automation or Classic token with publish permission). The workflow runs build, type-check, and npm publish --access public.

License

MIT

Support

For issues and questions: