TypeScript SDK
The official TypeScript SDK for img-src provides type-safe access to the API with full autocompletion support.
Package: @img-src/sdk | Runtime: Node.js 18+ | npm | GitHub
Installation
Quick Start
import { ImgSrc } from '@img-src/sdk';
const client = new ImgSrc({
apiKey: process.env.IMGSRC_API_KEY
});
// Upload an image
const image = await client.images.upload({
file: fs.createReadStream('photo.jpg'),
path: 'photos/vacation.jpg'
});
console.log(image.url);
// https://img-src.io/i/username/photos/vacation.jpg
Configuration
const client = new ImgSrc({
// Required
apiKey: 'imgsrc_YOUR_API_KEY',
// Optional
baseUrl: 'https://api.img-src.io', // Default
timeout: 30000, // Request timeout in ms
retries: 3, // Number of retries
});
Images
Upload
import fs from 'fs';
// From file path
const image = await client.images.upload({
file: fs.createReadStream('photo.jpg'),
path: 'photos/vacation.jpg'
});
// From buffer
const buffer = await fs.promises.readFile('photo.jpg');
const image = await client.images.upload({
file: buffer,
path: 'photos/vacation.jpg',
contentType: 'image/jpeg'
});
// From URL (fetched server-side)
const image = await client.images.upload({
url: 'https://example.com/photo.jpg',
path: 'photos/external.jpg'
});
List
// List all images
const { images, total } = await client.images.list();
// With pagination
const { images } = await client.images.list({
limit: 20,
offset: 40
});
// Filter by path prefix
const { images } = await client.images.list({
prefix: 'photos/'
});
Search
const { images } = await client.images.search({
query: 'vacation',
limit: 10
});
Get
const image = await client.images.get('img_abc123');
console.log(image.width, image.height);
Delete
await client.images.delete('img_abc123');
Create Signed URL (Pro)
const { signed_url, expires_at } = await client.images.createSignedUrl('img_abc123', {
expiresIn: 3600, // 1 hour
transform: {
w: 800,
h: 600,
fit: 'cover'
}
});
URL Builder
Build transformation URLs without making API calls:
// Simple resize
const url = client.url('username/photo.jpg')
.width(800)
.build();
// https://img-src.io/i/username/photo.jpg?w=800
// Full transformation (output format determined by file extension)
const url = client.url('username/photo.webp')
.width(800)
.height(600)
.fit('cover')
.quality(85)
.build();
// https://img-src.io/i/username/photo.webp?w=800&h=600&fit=cover&q=85
// Using a preset (Pro)
const url = client.url('username/photo.jpg')
.preset('thumbnail')
.build();
// https://img-src.io/i/username/photo.jpg?p:thumbnail
Settings
// Get settings
const { settings } = await client.settings.get();
// Update settings
await client.settings.update({
default_quality: 85,
default_fit_mode: 'cover'
});
API Keys
// List keys
const { api_keys } = await client.apiKeys.list();
// Create key
const { key } = await client.apiKeys.create({
name: 'Production',
scopes: ['read', 'write'],
expiresInDays: 90
});
// Delete key
await client.apiKeys.delete('key_id');
Presets (Pro)
// List presets
const { presets } = await client.presets.list();
// Create preset
const preset = await client.presets.create({
name: 'thumbnail',
params: { w: 200, h: 200, fit: 'cover' }
});
// Update preset
await client.presets.update('preset_id', {
params: { w: 250, h: 250, fit: 'cover' }
});
// Delete preset
await client.presets.delete('thumbnail');
Usage
const { usage, billing_period, plan } = await client.usage.get();
console.log(`Transformations: ${usage.transformations.used}/${usage.transformations.limit}`);
console.log(`Storage: ${usage.storage.used_bytes} bytes`);
Error Handling
import { ImgSrc, ImgSrcError, RateLimitError, NotFoundError } from '@img-src/sdk';
try {
await client.images.get('nonexistent');
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Image not found');
} else if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof ImgSrcError) {
console.log(`API error: ${error.code} - ${error.message}`);
}
}
TypeScript Types
All types are exported:
import type {
Image,
ImageUploadParams,
Settings,
Preset,
ApiKey,
Usage
} from '@img-src/sdk';
Framework Examples
Next.js
// app/api/upload/route.ts
import { ImgSrc } from '@img-src/sdk';
import { NextResponse } from 'next/server';
const client = new ImgSrc({ apiKey: process.env.IMGSRC_API_KEY! });
export async function POST(request: Request) {
const formData = await request.formData();
const file = formData.get('file') as File;
const image = await client.images.upload({
file: Buffer.from(await file.arrayBuffer()),
path: `uploads/${file.name}`,
contentType: file.type
});
return NextResponse.json(image);
}
Express
import express from 'express';
import multer from 'multer';
import { ImgSrc } from '@img-src/sdk';
const app = express();
const upload = multer();
const client = new ImgSrc({ apiKey: process.env.IMGSRC_API_KEY! });
app.post('/upload', upload.single('file'), async (req, res) => {
const image = await client.images.upload({
file: req.file!.buffer,
path: `uploads/${req.file!.originalname}`,
contentType: req.file!.mimetype
});
res.json(image);
});
Browser Usage
Never expose your API key in client-side code. Use a backend proxy.
The SDK is designed for server-side use. For client-side applications, create a backend API endpoint that proxies requests.