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.