Official Node.js SDK for the ToSVG API — Image to SVG conversion, background removal, and image resizing.
import { ToSVGClient } from "tosvg-api";
const client = new ToSVGClient("tosvg_live_your_api_key");
const result = await client.imageToSvg("./photo.png");
// result.svg → <svg xmlns="http://www.w3.org/2000/svg">...</svg>- TypeScript-first — Full type definitions for all methods, options, and responses
- Zero dependencies — Uses native
fetchandFormData(Node 18+) - Flexible file input — Pass a file path (
string),Buffer, orReadStream - Auto retry — Automatic retry on rate limit (429) with exponential backoff
- Typed errors — 7 specific error classes for precise error handling
- Rate limit aware — Parse rate limit headers and query remaining quota
- Dual output — ESM and CommonJS builds included
- Installation
- Quick Start
- Authentication
- Client Configuration
- File Input Types
- Core Methods
- Info Methods
- Rate Limiting
- Error Handling
- TypeScript
- Examples
- License
npm install tosvg-api# or with yarn
yarn add tosvg-api
# or with pnpm
pnpm add tosvg-apiRequires Node.js 18 or later. TypeScript type definitions are included — no
@types/package needed.
import { ToSVGClient } from "tosvg-api";
const client = new ToSVGClient("tosvg_live_your_api_key");
// Convert image to SVG
const result = await client.imageToSvg("./photo.png");
console.log(result.svg); // SVG XML string
console.log(result.fileSize); // SVG size in bytes
// Remove background
const bg = await client.removeBackground("./photo.png", {
returnBase64: true,
});
console.log(bg.image); // base64 encoded image
// Resize image
const resized = await client.resizeImage("./photo.png", {
width: 800,
height: 600,
});
console.log(resized.dimensions); // { width: 800, height: 600 }Get your API key from the ToSVG Dashboard.
API keys use the format:
- Production:
tosvg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Sandbox:
tosvg_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Direct
const client = new ToSVGClient("tosvg_live_your_api_key");
// From environment variable (recommended)
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);The SDK automatically sends the key via the X-API-Key header with every request.
const client = new ToSVGClient("tosvg_live_your_api_key", {
baseUrl: "https://tosvg.com/api/v1", // API base URL
timeout: 30000, // Request timeout (ms)
retryOnRateLimit: true, // Auto-retry on 429
maxRetries: 3, // Max retry attempts
});| Option | Type | Default | Description |
|---|---|---|---|
baseUrl |
string |
https://tosvg.com/api/v1 |
API base URL |
timeout |
number |
30000 |
Request timeout in milliseconds |
retryOnRateLimit |
boolean |
true |
Automatically retry on 429 responses |
maxRetries |
number |
3 |
Maximum number of retry attempts |
All core methods accept three types of file input:
const result = await client.imageToSvg("./images/photo.png");import { readFileSync } from "node:fs";
const buffer = readFileSync("./images/photo.png");
const result = await client.imageToSvg(buffer);import { createReadStream } from "node:fs";
const stream = createReadStream("./images/photo.png");
const result = await client.imageToSvg(stream);Supported formats: PNG, JPEG, BMP, GIF, TIFF, WebP (max 10 MB, max 4096×4096 px)
Converts a raster image to SVG format.
const result = await client.imageToSvg(image, options?);| Option | Type | Default | Description |
|---|---|---|---|
colorMode |
'color' | 'bw' |
'color' |
Color or black-and-white |
mode |
'polygon' | 'spline' |
'polygon' |
Conversion algorithm |
filterSpeckle |
number (0–20) |
8 |
Noise filter size |
cornerThreshold |
number (0–180) |
30 |
Corner threshold angle (deg) |
colorPrecision |
number (1–10) |
4 |
Color precision level |
| Field | Type | Description |
|---|---|---|
svg |
string |
Raw SVG content (XML) |
fileSize |
number |
SVG file size in bytes |
conversionTime |
number |
Conversion time (seconds) |
// Black & white, spline mode
const result = await client.imageToSvg("./logo.png", {
colorMode: "bw",
mode: "spline",
colorPrecision: 8,
});
// Write SVG to file
import { writeFileSync } from "node:fs";
writeFileSync("./logo.svg", result.svg);Removes the background from an image using AI models.
const result = await client.removeBackground(image, options?);| Option | Type | Default | Description |
|---|---|---|---|
provider |
'rembg' | 'withoutbg' |
'rembg' |
Background removal provider |
model |
'u2net' | 'silueta' | 'u2net_human_seg' | 'isnet-general-use' |
'u2net' |
AI model (only with rembg) |
format |
'png' | 'jpg' | 'jpeg' |
'png' |
Output format |
returnBase64 |
boolean |
false |
Return base64 instead of file path |
When returnBase64: false (default):
| Field | Type | Description |
|---|---|---|
filename |
string |
Generated filename (UUID) |
path |
string |
Storage-relative file path |
fileSize |
number |
File size in bytes |
processingTime |
number |
Processing time (seconds) |
provider |
string |
Provider used |
When returnBase64: true:
| Field | Type | Description |
|---|---|---|
image |
string |
Base64-encoded image data |
format |
string |
Output format |
fileSize |
number |
File size in bytes |
processingTime |
number |
Processing time (seconds) |
provider |
string |
Provider used |
// Get base64 result with high-accuracy model
const result = await client.removeBackground("./portrait.jpg", {
provider: "rembg",
model: "isnet-general-use",
returnBase64: true,
});
// Decode and save
import { writeFileSync } from "node:fs";
writeFileSync("./portrait-nobg.png", Buffer.from(result.image, "base64"));Resizes an image to the specified dimensions.
const result = await client.resizeImage(image, options);| Option | Type | Default | Required | Description |
|---|---|---|---|---|
width |
number (1–4096) |
— | ✅ | Target width in pixels |
height |
number (1–4096) |
— | ✅ | Target height in pixels |
quality |
number (1–100) |
90 |
❌ | Output quality |
format |
'png' | 'jpg' | 'jpeg' | 'webp' |
'png' |
❌ | Output format |
maintainAspectRatio |
boolean |
true |
❌ | Keep original aspect ratio |
| Field | Type | Description |
|---|---|---|
path |
string |
Resized file path |
size |
number |
File size in bytes |
dimensions |
{ width: number, height: number } |
Output dimensions |
quality |
number |
Quality value used |
format |
string |
Output format |
processingTime |
number |
Processing time (seconds) |
const result = await client.resizeImage("./photo.png", {
width: 1200,
height: 630,
format: "webp",
quality: 80,
maintainAspectRatio: true,
});
console.log(result.dimensions); // { width: 1200, height: 630 }
console.log(result.size); // file size in bytesChecks the health of all ToSVG services. No authentication required.
const health = await client.healthCheck();
console.log(health.status); // 'healthy'
console.log(health.services); // { image_conversion: 'operational', ... }Returns supported input image formats. Requires authentication.
const formats = await client.getSupportedFormats();
console.log(formats.formats); // { png: { max_size: '10MB', ... }, ... }
console.log(formats.maxDimensions); // '4096x4096 pixels'Returns available AI models for background removal. Requires authentication.
const models = await client.getModels();
console.log(models.models); // ['u2net', 'silueta', ...]
console.log(models.availableProviders); // ['rembg', 'withoutbg']
// Filter by provider
const rembgModels = await client.getModels("rembg");Returns resize dimension and quality limits. Requires authentication.
const limits = await client.getResizeLimits();
console.log(limits.maxDimensions); // { width: 4096, height: 4096 }
console.log(limits.qualityRange); // { min: 1, max: 100, default: 90 }The ToSVG API enforces daily rate limits based on your subscription plan:
| Plan | Daily Limit |
|---|---|
| Free | 100 requests |
| Starter | 1,000 requests |
| Pro | 10,000 requests |
| Enterprise | 100,000 requests |
// After any API call, check remaining quota
const info = client.getRateLimitInfo();
if (info) {
console.log(`Remaining: ${info.remaining}/${info.limit}`);
console.log(`Resets at: ${info.resetAt.toISOString()}`);
}When retryOnRateLimit is true (default), the SDK automatically:
- Catches 429 responses
- Reads the
Retry-Afterheader - Waits with exponential backoff
- Retries up to
maxRetriestimes
// Disable auto retry
const client = new ToSVGClient("tosvg_live_key", {
retryOnRateLimit: false,
});The SDK provides 7 typed error classes, all extending ToSVGError:
| Error Class | HTTP Status | When |
|---|---|---|
AuthenticationError |
401 | Invalid, missing, or expired API key |
ForbiddenError |
403 | IP restriction or subscription required |
ValidationError |
422 | Invalid parameters |
RateLimitError |
429 | Daily quota exceeded |
BadRequestError |
400 | Unsupported format, file too large |
ServerError |
500 | Internal server error |
NetworkError |
— | Connection timeout, DNS failure |
import {
ToSVGClient,
AuthenticationError,
ValidationError,
RateLimitError,
ToSVGError,
} from "tosvg-api";
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);
try {
const result = await client.imageToSvg("./photo.png");
console.log(result.svg);
} catch (error) {
if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter} seconds.`);
} else if (error instanceof ValidationError) {
console.log("Validation failed:", error.errors);
// { image: ['The image field is required.'], ... }
} else if (error instanceof AuthenticationError) {
console.log("Invalid API key");
} else if (error instanceof ToSVGError) {
console.log(`API error [${error.statusCode}]: ${error.message}`);
}
}All errors inherit from ToSVGError:
error.message; // Human-readable error message
error.statusCode; // HTTP status code (undefined for NetworkError)
error.code; // API error code (e.g. 'INVALID_API_KEY')
error.response; // Raw API error response bodySpecial properties:
ValidationError.errors—Record<string, string[]>with field-level errorsRateLimitError.retryAfter— Seconds to wait before retryingNetworkError.cause— The original underlying error
All types are exported for direct use:
import type {
ClientOptions,
ImageToSvgOptions,
ImageToSvgResult,
RemoveBackgroundOptions,
RemoveBackgroundResult,
RemoveBackgroundFileResult,
RemoveBackgroundBase64Result,
ResizeImageOptions,
ResizeImageResult,
RateLimitInfo,
HealthCheckResult,
SupportedFormatsResult,
BackgroundModelsResult,
ResizeLimitsResult,
FileInput,
} from "tosvg-api";import { ToSVGClient } from "tosvg-api";
import type { ImageToSvgOptions, ImageToSvgResult } from "tosvg-api";
async function convertToSvg(
filePath: string,
options?: ImageToSvgOptions,
): Promise<ImageToSvgResult> {
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);
return client.imageToSvg(filePath, options);
}import { readdirSync, writeFileSync } from "node:fs";
import { join, parse } from "node:path";
import { ToSVGClient } from "tosvg-api";
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);
const inputDir = "./images";
const outputDir = "./svgs";
const files = readdirSync(inputDir).filter((f) => /\.(png|jpg|jpeg)$/i.test(f));
for (const file of files) {
const result = await client.imageToSvg(join(inputDir, file));
const outputName = `${parse(file).name}.svg`;
writeFileSync(join(outputDir, outputName), result.svg);
console.log(`✓ ${file} → ${outputName} (${result.conversionTime}s)`);
// Check rate limit
const info = client.getRateLimitInfo();
if (info && info.remaining < 5) {
console.log("Rate limit approaching, pausing...");
await new Promise((r) => setTimeout(r, 60_000));
}
}import { ToSVGClient } from "tosvg-api";
import { writeFileSync } from "node:fs";
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);
// Step 1: Remove background
const nobg = await client.removeBackground("./product.jpg", {
model: "isnet-general-use",
returnBase64: true,
format: "png",
});
// Step 2: Save the result
const imageBuffer = Buffer.from(nobg.image, "base64");
writeFileSync("./product-nobg.png", imageBuffer);
// Step 3: Resize for thumbnails
const thumb = await client.resizeImage(imageBuffer, {
width: 200,
height: 200,
format: "webp",
quality: 85,
});
console.log(`Thumbnail: ${thumb.dimensions.width}x${thumb.dimensions.height}`);import express from "express";
import multer from "multer";
import { ToSVGClient, ValidationError } from "tosvg-api";
const app = express();
const upload = multer();
const client = new ToSVGClient(process.env.TOSVG_API_KEY!);
app.post("/convert", upload.single("image"), async (req, res) => {
try {
if (!req.file) {
return res.status(400).json({ error: "No image uploaded" });
}
const result = await client.imageToSvg(req.file.buffer, {
colorMode: (req.body.colorMode as "color" | "bw") || "color",
});
res.type("image/svg+xml").send(result.svg);
} catch (error) {
if (error instanceof ValidationError) {
res.status(422).json({ errors: error.errors });
} else {
res.status(500).json({ error: "Conversion failed" });
}
}
});
app.listen(3000);For the full API specification, see the ToSVG API Documentation.
- Node.js 18 or later
- A ToSVG API key (get one here)
MIT © ToSVG