Pricing Docs About
Get Started
Ready to start creating map animations? Get Started Free →

Node.js SDK

The official Node.js SDK for Georender. TypeScript support included.

Installation

npm install @georender/sdk

Quick Start

import Georender from '@georender/sdk';

const client = new Georender({ apiKey: 'gr_live_xxxxxxxxxxxx' });

const job = await client.render({
  waypoints: [
    { lat: 29.9792, lng: 32.5731, label: 'Suez Canal' },
    { lat: 1.2644, lng: 103.8176, label: 'Singapore' },
  ],
  style: 'maritime-dark',
  duration: 12,
});

const video = await job.wait();
console.log(video.url);
// https://cdn.georender.io/renders/job_8f3k2m9x.mp4

Client Options

const client = new Georender({
  apiKey: 'gr_live_xxxxxxxxxxxx',
  baseUrl: 'https://api.georender.io/v1', // Optional
  timeout: 30000, // Request timeout in ms
  maxRetries: 3, // Retry failed requests
});

Render Options

const job = await client.render({
  // Required
  waypoints: [
    { lat: 29.9792, lng: 32.5731, label: 'Suez Canal' },
    { lat: 1.2644, lng: 103.8176, label: 'Singapore' },
  ],

  // Optional
  mode: 'route_animation',
  style: 'maritime-dark',
  duration: 15,
  resolution: '4k',
  fps: 60,
  transport: 'ship',

  // Advanced
  routeStyle: {
    color: '#00D4FF',
    width: 4,
    vehicleIcon: 'ship',
  },
  camera: {
    preset: 'global_corridor_reveal',
    intensity: 'bold',
  },
  hud: {
    stats: { showDistance: true },
    progressBar: true,
  },
  webhookUrl: 'https://your-server.com/webhook',
});

Job Management

// Check status without waiting
const job = await client.render({ waypoints: [...] });
console.log(job.id);     // job_8f3k2m9x
console.log(job.status); // "queued"

// Poll for status
await job.refresh();
console.log(job.status); // "processing"

// Wait with timeout
try {
  const video = await job.wait({ timeout: 120000 }); // 2 minutes
} catch (error) {
  if (error instanceof Georender.TimeoutError) {
    console.log('Render took too long');
  }
}

// Wait with callback
const video = await job.wait({
  onProgress: (job) => {
    console.log(`Status: ${job.status}`);
  },
});

Video Object

const video = await job.wait();

console.log(video.url);        // https://cdn.georender.io/renders/job_xxx.mp4
console.log(video.thumbnail);  // https://cdn.georender.io/renders/job_xxx_thumb.jpg
console.log(video.duration);   // 12
console.log(video.resolution); // "1920x1080"
console.log(video.fileSize);   // 18432000
console.log(video.expiresAt);  // Date object

// Download the video
await video.download('output.mp4');

// Get as buffer
const buffer = await video.toBuffer();

Templates

// Create a template
const template = await client.templates.create({
  name: 'suez-cinematic',
  style: 'maritime-dark',
  duration: 15,
  camera: { preset: 'canal_bottleneck' },
});

// List templates
const templates = await client.templates.list();

// Use a template
const job = await client.render({
  templateId: 'suez-cinematic',
  waypoints: [...],
});

Batch Rendering

// Submit multiple jobs at once (Studio tier only)
const batch = await client.renderBatch({
  jobs: [
    { waypoints: [...], style: 'maritime-dark' },
    { waypoints: [...], style: 'satellite' },
    { waypoints: [...], style: 'geopolitics' },
  ],
  webhookUrl: 'https://your-server.com/batch-complete',
});

console.log(batch.id);   // batch_xyz123
console.log(batch.jobs); // Array of job objects

// Wait for all jobs
const results = await batch.wait();
for (const video of results) {
  console.log(video.url);
}

Error Handling

import Georender, {
  AuthenticationError,
  ValidationError,
  RateLimitError,
  RenderLimitError,
} from '@georender/sdk';

try {
  const job = await client.render({ waypoints: [...] });
  const video = await job.wait();
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.log('Invalid API key');
  } else if (error instanceof ValidationError) {
    console.log(`Invalid request: ${error.message}`);
    console.log(`Fields: ${error.fields}`);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof RenderLimitError) {
    console.log('Monthly render limit exceeded');
  } else if (error instanceof Georender.GeoRenderError) {
    console.log(`API error: ${error.message}`);
  }
}

TypeScript

import Georender, { RenderOptions, Video, Job } from '@georender/sdk';

const client = new Georender({ apiKey: 'gr_live_xxx' });

const options: RenderOptions = {
  waypoints: [
    { lat: 29.9792, lng: 32.5731, label: 'Suez Canal' },
  ],
  style: 'maritime-dark',
};

const job: Job = await client.render(options);
const video: Video = await job.wait();

Checking Usage

const usage = await client.usage();

console.log(usage.rendersUsed);      // 35
console.log(usage.rendersLimit);     // 50
console.log(usage.rendersRemaining); // 15
console.log(usage.periodEnd);        // Date object