Node.js SDK
Official Node.js SDK for Qalib's image generation API.
Installation
npm install qalib-node
yarn add qalib-node
pnpm add qalib-node
Quick Start
const Qalib = require("qalib-node");
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
});
const render = await qalib.renderImage("tmp_template_id", [
{ name: "title", text: "Hello World!" },
{ name: "logo", image_url: "https://example.com/logo.png" },
]);
console.log(render.id);
Configuration
Initialize the Client
const qalib = new Qalib({
apiKey: string, // Required
mode: "async" | "sync", // Optional, default: 'async'
timeout: number, // Optional, default: 30000ms
baseURL: string, // Optional
});
Always use environment variables for your API key
Rendering Modes
The SDK supports two rendering modes:
Async Mode
Returns immediately, poll for results.
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
});
// Create render
const render = await qalib.renderImage("tmp_abc123", variables);
console.log(render.id); // Save for polling
// Poll for completion
const completed = await qalib.getRender(render.id);
console.log(completed.image_url);
Use for: Production, high-volume, batch processing
Sync Mode
Returns when the image is ready.
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
mode: "sync",
});
const render = await qalib.renderImage("tmp_abc123", variables);
console.log(render.image_url); // Ready immediately
Use for: Testing, low-volume requests
Override Mode Per Request
// Override to sync for this request
const render = await qalib.renderImage("tmp_abc123", variables, {
mode: "sync",
});
Change Mode Dynamically
qalib.setMode("sync");
console.log(qalib.mode); // 'sync'
Best Practices
1. Environment Variables
// ✅ Good
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
});
// ❌ Bad
const qalib = new Qalib({
apiKey: "qk_live_abc123...",
});
2. Error Handling
Always wrap SDK calls in try-catch blocks:
try {
const render = await qalib.renderImage(templateId, variables);
return render.image_url;
} catch (error) {
console.error("Render failed:", error);
// Handle appropriately
}
3. Choose the Right Mode
- Sync: Development and testing
- Async: Production and high volume
Complete Example
const Qalib = require("qalib-node");
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
mode: "async",
});
async function waitForRender(renderId) {
let attempts = 0;
const maxAttempts = 30;
while (attempts < maxAttempts) {
attempts++;
await new Promise((resolve) => setTimeout(resolve, 1000));
const status = await qalib.getRender(renderId);
if (status.status === "completed") return status;
if (status.status === "failed") {
throw new Error(status.error_message);
}
}
throw new Error("Timeout");
}
async function generateImage(data) {
try {
const variables = [
{
name: "title",
text: data.title,
color: "#1e40af",
},
{
name: "image",
image_url: data.imageUrl,
},
{
name: "rating",
rating: data.rating,
},
];
// Create render
const render = await qalib.renderImage("tmp_template", variables);
console.log("Queued:", render.id);
// Poll for completion
const completed = await waitForRender(render.id);
console.log("Generated:", completed.image_url);
console.log("Credits remaining:", completed.remaining_credits);
return completed.image_url;
} catch (error) {
if (error instanceof Qalib.InsufficientCreditsError) {
console.error("Out of credits");
}
throw error;
}
}
// Usage
await generateImage({
title: "Product Launch",
imageUrl: "https://example.com/product.jpg",
rating: 4.8,
});
const Qalib = require("qalib-node");
const qalib = new Qalib({
apiKey: process.env.QALIB_API_KEY,
mode: "sync",
});
async function generateImage(data) {
try {
const variables = [
{
name: "title",
text: data.title,
color: "#1e40af",
},
{
name: "image",
image_url: data.imageUrl,
},
{
name: "rating",
rating: data.rating,
},
];
const render = await qalib.renderImage("tmp_template", variables);
console.log("Generated:", render.image_url);
console.log("Credits remaining:", render.remaining_credits);
return render.image_url;
} catch (error) {
if (error instanceof Qalib.InsufficientCreditsError) {
console.error("Out of credits");
}
throw error;
}
}
// Usage
await generateImage({
title: "Product Launch",
imageUrl: "https://example.com/product.jpg",
rating: 4.8,
});
Error Handling
The SDK provides specialized error classes:
| Error Class | Status | When |
|---|---|---|
AuthenticationError |
401 | Invalid API key |
ValidationError |
400 | Invalid request |
InsufficientCreditsError |
402 | No credits |
NotFoundError |
404 | Resource not found |
RateLimitError |
429 | Rate limited |
RenderError |
500 | Render failed |
APIError |
500+ | Server error |
try {
const render = await qalib.renderImage("tmp_abc123", variables);
} catch (error) {
if (error instanceof Qalib.AuthenticationError) {
console.error("Invalid API key");
} else if (error instanceof Qalib.ValidationError) {
console.error("Invalid request:", error.details);
} else if (error instanceof Qalib.InsufficientCreditsError) {
console.error("No credits:", error.details.creditBalance);
} else if (error instanceof Qalib.RateLimitError) {
console.error("Rate limited, retry later");
}
}
All errors include:
error.message; // Human-readable message
error.statusCode; // HTTP status code
error.code; // Error code
error.details; // Additional details (optional)
TypeScript Support
Full TypeScript definitions included:
import Qalib, { Variable, Render, Template, QalibConfig } from "qalib-node";
const config: QalibConfig = {
apiKey: process.env.QALIB_API_KEY!,
mode: "sync",
};
const qalib = new Qalib(config);
const variables: Variable[] = [
{ name: "title", text: "Hello TypeScript" },
{ name: "logo", image_url: "https://example.com/logo.png" },
{ name: "rating", rating: 4.5 },
];
const render: Render = await qalib.renderImage("tmp_abc123", variables);
Reference
renderImage()
renderImage(
templateId: string,
variables: Variable[],
options?: { mode?: 'sync' | 'async' }
): Promise<Render>
Create a new image render.
getRender()
getRender(renderId: string): Promise<Render>
Get render status and result by ID.
listTemplates()
listTemplates(options?: {
limit?: number, // Max 100, default 10
offset?: number // Default 0
}): Promise<TemplatesListResponse>
List templates with pagination.
getTemplate()
getTemplate(templateId: string): Promise<Template>
Get template by ID.
listAllTemplates()
listAllTemplates(options?: {
maxResults?: number
}): Promise<Template[]>
Auto-paginated template listing.
health()
health(): Promise<{ status: string }>
API health check.
setMode()
setMode(mode: 'sync' | 'async'): void
Change rendering mode.