Official JavaScript SDK for ConvertHub API v2 - Convert files between 800+ format pairs with a simple, powerful API.
- 800+ Format Conversions - Support for images, documents, audio, video, and more
- Asynchronous Processing - Non-blocking conversion with job-based workflow
- Chunked Uploads - Handle large files (up to 2GB)
- Smart Caching - Automatic caching for repeated conversions
- TypeScript Support - Full type definitions included
- Framework Agnostic - Works with modern JavaScript runtimes (Node.js 18+, Deno, Bun)
- Developer-Friendly - Clean API with detailed error handling
- Node.js 18.0 or higher (uses native fetch API and FormData)
- npm or yarn
- ConvertHub API key (Sign up here)
- TypeScript 4.0+ (optional, for TypeScript projects)
Install via npm:
npm install @converthub/sdkOr with yarn:
yarn add @converthub/sdkconst { ConvertHubClient } = require('@converthub/sdk');
// Initialize the client
const client = new ConvertHubClient({
apiKey: 'YOUR_API_KEY'
});
// Convert a file
const job = await client.convertFile({
file: 'path/to/document.pdf',
targetFormat: 'docx'
});
// Wait for completion
const result = await job.waitForCompletion();
// Download the converted file
if (result.status === 'completed') {
await job.download('output.docx');
console.log('Download URL:', result.result.download_url);
}import { ConvertHubClient, ConversionJob } from '@converthub/sdk';
const client = new ConvertHubClient({
apiKey: process.env.CONVERTHUB_API_KEY as string
});
const job: ConversionJob = await client.convertFile({
file: 'path/to/document.pdf',
targetFormat: 'docx'
});
const result = await job.waitForCompletion();
console.log(result.result?.download_url);- Authentication
- Account Management
- Basic Usage
- Advanced Features
- Format Discovery
- Error Handling
- Examples
Get your API key from the ConvertHub Dashboard:
const client = new ConvertHubClient({
apiKey: 'YOUR_API_KEY'
});const client = new ConvertHubClient({
apiKey: 'YOUR_API_KEY',
baseUrl: 'https://api.converthub.com', // Custom API endpoint
timeout: 600000, // Request timeout in milliseconds (10 minutes)
debug: false // Enable debug logging
});Retrieve your account details including credits remaining, membership plan, and file size limits:
const accountInfo = await client.getAccount();
console.log('Credits Remaining:', accountInfo.credits_remaining);
console.log('Plan:', accountInfo.plan.name);
console.log('Total Credits:', accountInfo.plan.credits);
console.log('File Size Limit:', accountInfo.plan.file_size_limit_mb, 'MB');
// Check if running low on credits
if (accountInfo.credits_remaining < 10) {
console.log('Warning: Running low on credits!');
}// Calculate usage percentage
const account = await client.getAccount();
const usedCredits = account.plan.credits - account.credits_remaining;
const usagePercent = (usedCredits / account.plan.credits * 100).toFixed(1);
console.log(`Credits Used: ${usedCredits}/${account.plan.credits} (${usagePercent}%)`);
// Check file size before conversion
const fileStats = fs.statSync('large-file.pdf');
const fileSizeMB = fileStats.size / 1024 / 1024;
if (fileSizeMB > account.plan.file_size_limit_mb) {
console.log(`File too large for your plan. Max size: ${account.plan.file_size_limit_mb} MB`);
console.log('Please upgrade your plan to convert larger files.');
}// Simple conversion
const job = await client.convertFile({
file: 'path/to/image.png',
targetFormat: 'jpg'
});
console.log('Job ID:', job.jobId);
console.log('Status:', job.status);// Convert a file from URL
const job = await client.convertFromUrl({
fileUrl: 'https://example.com/document.pdf',
targetFormat: 'docx'
});
// Poll for completion
while (job.status === 'processing') {
await new Promise(resolve => setTimeout(resolve, 2000));
await job.getStatus();
}
if (job.status === 'completed') {
console.log('Download:', job.result.download_url);
} else {
console.log('Error:', job.message);
}const status = await client.getJobStatus('job_123e4567-e89b-12d3-a456-426614174000');
if (status.status === 'completed') {
console.log('Conversion completed!');
console.log('Download URL:', status.result.download_url);
console.log('File size:', status.result.file_size, 'bytes');
console.log('Expires at:', status.result.expires_at);
} else if (status.status === 'failed') {
console.log('Conversion failed:', status.error.message);
} else {
console.log('Still processing...');
}// Get download info
const downloadInfo = await client.getDownloadUrl(job.jobId);
console.log('Filename:', downloadInfo.filename);
console.log('Size:', downloadInfo.file_size, 'bytes');
// Download to buffer
const buffer = await client.downloadFile(job.jobId);
fs.writeFileSync('output.docx', buffer);
// Download directly to file
await client.downloadFile(job.jobId, 'path/to/save/converted.docx');
console.log('File downloaded successfully!');// With conversion options
const job = await client.convertFile({
file: 'path/to/file.jpg',
targetFormat: 'pdf',
outputFilename: 'my-document.pdf',
options: {
quality: 90, // Image quality (1-100)
resolution: '1920x1080', // Resolution for images/videos
bitrate: '320k', // Audio/video bitrate
sample_rate: 44100 // Audio sample rate
}
});
// Audio conversion with options
const audioJob = await client.convertFile({
file: 'path/to/audio.wav',
targetFormat: 'mp3',
outputFilename: 'high-quality.mp3',
options: {
bitrate: '320k',
sample_rate: 48000
}
});// For files over 50MB, use chunked upload
const largeFile = 'path/to/large-video.mov';
const fileSize = fs.statSync(largeFile).size;
const chunkSize = 10 * 1024 * 1024; // 10MB chunks
const totalChunks = Math.ceil(fileSize / chunkSize);
// Automatic chunked upload with progress tracking
const session = await client.initChunkedUpload({
filename: 'large-video.mov',
fileSize: fileSize,
totalChunks: totalChunks,
targetFormat: 'mp4',
webhookUrl: 'https://your-app.com/webhook',
metadata: { videoId: '12345' }
});
// Upload file with automatic chunking
const job = await session.uploadFile(largeFile, chunkSize);
console.log('Conversion started:', job.jobId);// For more control over the chunked upload process
const handle = fs.openSync('large-file.mov', 'r');
const buffer = Buffer.alloc(chunkSize);
// 1. Initialize session
const session = await client.initChunkedUpload({
filename: 'large-file.mov',
fileSize: fileSize,
totalChunks: totalChunks,
targetFormat: 'mp4'
});
// 2. Upload chunks
for (let i = 0; i < totalChunks; i++) {
const bytesRead = fs.readSync(handle, buffer, 0, chunkSize, i * chunkSize);
const chunk = buffer.slice(0, bytesRead);
await session.uploadChunk(i, chunk);
console.log(`Uploaded chunk ${i + 1} of ${totalChunks}`);
}
fs.closeSync(handle);
// 3. Complete upload and start conversion
const job = await session.complete();// Set up webhook for async notification
const job = await client.convertFile({
file: 'document.pdf',
targetFormat: 'docx',
webhookUrl: 'https://your-app.com/webhooks/conversion-complete'
});
// In your webhook handler (Express example):
app.post('/webhooks/conversion-complete', (req, res) => {
const payload = req.body;
if (payload.status === 'completed') {
const downloadUrl = payload.result.download_url;
// Process the converted file
} else {
const error = payload.error.message;
// Handle error
}
res.sendStatus(200);
});// Add custom metadata for tracking
const job = await client.convertFile({
file: 'invoice.pdf',
targetFormat: 'png',
metadata: {
user_id: 'user_123',
invoice_id: 'inv_456',
department: 'accounting'
}
});
// Retrieve metadata from completed job
const status = await client.getJobStatus(job.jobId);
const metadata = status.metadata;
console.log('Invoice ID:', metadata.invoice_id);const formats = await client.getSupportedFormats();
console.log('Total formats:', formats.total_formats);
for (const [type, formatList] of Object.entries(formats.formats)) {
console.log(`\n${type}:`);
formatList.forEach(format => {
console.log(` - ${format.extension} (${format.mime_type})`);
});
}// Get all possible conversions for a format
const conversions = await client.getFormatConversions('png');
console.log('PNG can be converted to:');
conversions.available_conversions.forEach(conv => {
console.log(` - ${conv.target_format}`);
});
// Check if a specific conversion is supported
const support = await client.checkConversionSupport('pdf', 'docx');
if (support.supported) {
console.log('PDF to DOCX conversion is available');
}
// Get complete conversion map
const allConversions = await client.getSupportedConversions();
console.log('All formats:', Object.keys(allConversions.formats));
console.log('PDF converts to:', allConversions.conversion_map['pdf']);const { ConvertHubError } = require('@converthub/sdk');
try {
const job = await client.convertFile({
file: 'file.pdf',
targetFormat: 'docx'
});
} catch (error) {
if (error instanceof ConvertHubError) {
// Handle API errors
console.error('API Error:', error.message);
console.error('Error Code:', error.code);
if (error.code === 'VALIDATION_ERROR' && error.details?.validation_errors) {
// Handle validation errors
Object.entries(error.details.validation_errors).forEach(([field, errors]) => {
console.error(` ${field}: ${errors.join(', ')}`);
});
} else if (error.code === 'AUTHENTICATION_REQUIRED') {
// Handle authentication errors
console.error('Check your API key');
} else if (error.statusCode === 429) {
// Handle rate limiting
const retryAfter = error.details?.retry_after || 60;
console.error(`Rate limited. Retry after ${retryAfter} seconds`);
}
} else {
// Handle general errors
console.error('Unexpected error:', error.message);
}
}const { ConvertHubClient, ConvertHubError } = require('@converthub/sdk');
const fs = require('fs');
class DocumentProcessor {
constructor(apiKey) {
this.client = new ConvertHubClient({ apiKey });
}
async processDocument(inputFile, targetFormat) {
try {
console.log(`Starting conversion of ${inputFile} to ${targetFormat}...`);
// Start conversion
const job = await this.client.convertFile({
file: inputFile,
targetFormat: targetFormat,
metadata: {
timestamp: Date.now(),
sourceFile: inputFile
}
});
console.log(`Job created: ${job.jobId}`);
// Wait for completion with timeout
const completedJob = await job.waitForCompletion({
pollingInterval: 2000, // Poll every 2 seconds
maxWaitTime: 120000 // Max wait 2 minutes
});
if (completedJob.status === 'completed') {
// Download the converted file
const outputFile = `output/${completedJob.result.format}/converted.${targetFormat}`;
await job.download(outputFile);
console.log('β
Conversion successful!');
console.log('π Saved to:', outputFile);
console.log('π Size:', completedJob.result.file_size, 'bytes');
// Clean up - delete from server
await job.deleteFile();
return outputFile;
} else {
console.log('β Conversion failed:', completedJob.error?.message);
}
} catch (error) {
if (error instanceof ConvertHubError) {
console.error('β API Error:', error.message);
} else {
console.error('β Unexpected error:', error.message);
}
}
return null;
}
}
// Usage
const processor = new DocumentProcessor('YOUR_API_KEY');
processor.processDocument('documents/report.pdf', 'docx');// Convert multiple files in parallel
const files = [
{ input: 'file1.pdf', format: 'docx' },
{ input: 'file2.png', format: 'jpg' },
{ input: 'file3.mp3', format: 'wav' }
];
const jobs = [];
// Start all conversions
for (const file of files) {
const job = await client.convertFile({
file: file.input,
targetFormat: file.format
});
jobs.push({
job,
input: file.input,
format: file.format
});
console.log(`Started conversion: ${file.input} -> ${file.format}`);
}
// Wait for all to complete
for (const jobInfo of jobs) {
const completedJob = await jobInfo.job.waitForCompletion();
if (completedJob.status === 'completed') {
console.log(`β
${jobInfo.input} converted successfully`);
} else {
console.log(`β ${jobInfo.input} failed:`, completedJob.error?.message);
}
}The SDK includes full TypeScript support with complete type definitions:
import {
ConvertHubClient,
ConversionJob,
ConvertHubError,
ConversionParams,
JobStatus,
ConversionOptions
} from '@converthub/sdk';
class TypedDocumentConverter {
private client: ConvertHubClient;
constructor(apiKey: string) {
this.client = new ConvertHubClient({
apiKey,
timeout: 300000,
debug: process.env.NODE_ENV === 'development'
});
}
async convertWithOptions(
filePath: string,
targetFormat: string,
options?: ConversionOptions
): Promise<JobStatus> {
try {
const params: ConversionParams = {
file: filePath,
targetFormat,
options,
metadata: {
processedAt: new Date().toISOString(),
environment: process.env.NODE_ENV
}
};
const job: ConversionJob = await this.client.convertFile(params);
console.log(`Job started: ${job.jobId}`);
// Type-safe status checking
const result: JobStatus = await job.waitForCompletion({
pollingInterval: 3000,
maxWaitTime: 300000
});
if (result.status === 'completed' && result.result) {
console.log(`Download URL: ${result.result.download_url}`);
console.log(`File size: ${result.result.file_size} bytes`);
console.log(`Expires at: ${result.result.expires_at}`);
}
return result;
} catch (error) {
if (error instanceof ConvertHubError) {
// Type-safe error handling
console.error(`API Error [${error.code}]: ${error.message}`);
console.error('Status Code:', error.statusCode);
if (error.details) {
console.error('Error Details:', error.details);
}
}
throw error;
}
}
async batchConvert(
files: Array<{ path: string; format: string }>
): Promise<Map<string, JobStatus>> {
const results = new Map<string, JobStatus>();
const promises = files.map(async ({ path, format }) => {
const job = await this.client.convertFile({
file: path,
targetFormat: format
});
const result = await job.waitForCompletion();
results.set(path, result);
return result;
});
await Promise.all(promises);
return results;
}
}
// Usage with TypeScript
async function main() {
const converter = new TypedDocumentConverter(process.env.CONVERTHUB_API_KEY!);
// Convert with type-safe options
const result = await converter.convertWithOptions(
'document.pdf',
'docx',
{
quality: 90,
resolution: '1920x1080'
}
);
// Batch convert with typed results
const batchResults = await converter.batchConvert([
{ path: 'file1.pdf', format: 'docx' },
{ path: 'file2.png', format: 'jpg' }
]);
batchResults.forEach((status, filePath) => {
console.log(`${filePath}: ${status.status}`);
});
}
main().catch(console.error);For complete API documentation, visit ConvertHub API Docs.
Run the test suite:
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run in watch mode
npm run test:watch
# Fix code style
npm run lint:fixContributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Documentation: https://converthub.com/api/docs
- Issues: GitHub Issues
- Email: support@converthub.com
This SDK is open-sourced software licensed under the MIT license.
Developed and maintained by ConvertHub.
Ready to start converting? Get your API key and begin transforming files in minutes!