Getting Started
TongoRender is a REST API for generating PDFs, images, and screenshots from HTML or URLs. It runs headless Chromium under the hood so you get pixel-perfect output every time.
Base URL: https://api.tongorender.io/v1
All API requests must include your API key in the Authorization header. You can create API keys from the dashboard.
Authentication
Authenticate your requests by including your API key in the Authorization header using the Bearer scheme.
Authorization: Bearer rf_live_sk_your_api_key_hereAPI keys come in two types:
- Live keys (
rf_live_sk_...) — for production use, renders count against your quota. - Test keys (
rf_test_sk_...) — for development, renders are watermarked and don't count against quota.
Quick Start
Generate your first PDF in under a minute. Here is a complete example:
curl -X POST https://api.tongorender.io/v1/pdf \
-H "Authorization: Bearer rf_live_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Hello World</h1><p>My first PDF</p>",
"format": "A4",
"margin": {
"top": "20mm",
"bottom": "20mm",
"left": "15mm",
"right": "15mm"
}
}'The API returns a JSON response with the render job details:
{
"id": "rj_550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"type": "pdf",
"url": "https://files.tongorender.io/rj_550e8400.pdf",
"pages": 1,
"file_size": 24576,
"created_at": "2026-03-24T10:30:00Z",
"completed_at": "2026-03-24T10:30:01Z"
}Generate PDF
/v1/pdfGenerate a PDF from HTML content or a URL.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
html | string | * | HTML content to render. Required if url is not provided. |
url | string | * | URL to render. Required if html is not provided. |
format | string | No | Page format: A4, Letter, Legal, A3. Default: A4. |
margin | object | No | Page margins with top, bottom, left, right (CSS units). |
header_html | string | No | HTML for page header. |
footer_html | string | No | HTML for page footer. Use pageNumber and totalPages classes for dynamic numbering. |
const response = await fetch('https://api.tongorender.io/v1/pdf', {
method: 'POST',
headers: {
'Authorization': 'Bearer rf_live_sk_your_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: '<h1>Invoice #1042</h1><table>...</table>',
format: 'A4',
margin: { top: '20mm', bottom: '25mm' },
footer_html: '<div style="text-align:center;font-size:10px">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
}),
});
const data = await response.json();
console.log(data.url); // https://files.tongorender.io/rj_...pdfGenerate Image
/v1/imageGenerate a PNG, JPEG, or WebP image from HTML.
curl -X POST https://api.tongorender.io/v1/image \
-H "Authorization: Bearer rf_live_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"html": "<div style=\"width:1200px;height:630px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#667eea,#764ba2);color:white;font-size:48px;font-family:sans-serif\">My Blog Post Title</div>",
"type": "png",
"viewport": { "width": 1200, "height": 630 }
}'URL Screenshot
/v1/screenshotCapture a screenshot of any webpage.
curl -X POST https://api.tongorender.io/v1/screenshot \
-H "Authorization: Bearer rf_live_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"type": "png",
"viewport": { "width": 1440, "height": 900 },
"full_page": false,
"wait_for": "networkidle0"
}'Templates
/v1/templates/:id/renderRender a document using a pre-built template.
Templates let you pass JSON data to a pre-designed layout. No HTML required.
curl -X POST https://api.tongorender.io/v1/templates/invoice-modern/render \
-H "Authorization: Bearer rf_live_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"data": {
"invoice_number": "INV-1042",
"company_name": "Acme Corp",
"items": [
{ "name": "Widget Pro", "qty": 5, "price": 29.99 },
{ "name": "Gadget Plus", "qty": 2, "price": 49.99 }
]
},
"output": "pdf"
}'/v1/templatesList all available templates.
Webhooks
Instead of polling for render status, configure a webhook URL to receive notifications when renders complete. Include a webhook_url in your render request.
{
"event": "render.completed",
"data": {
"id": "rj_550e8400...",
"status": "completed",
"type": "pdf",
"url": "https://files.tongorender.io/rj_550e8400.pdf",
"created_at": "2026-03-24T10:30:00Z"
}
}Batch Rendering
/v1/batchRender multiple documents in a single request.
Submit up to 100 render jobs in a single API call. Available on the Scale plan.
{
"renders": [
{ "type": "pdf", "html": "<h1>Doc 1</h1>" },
{ "type": "pdf", "html": "<h1>Doc 2</h1>" },
{ "type": "image", "html": "<div>Image 1</div>", "image_type": "png" }
],
"webhook_url": "https://your-app.com/webhooks/tongorender"
}SDK (TypeScript)
The official TypeScript SDK provides a type-safe, zero-dependency client for all TongoRender APIs. Works with Node.js 18+ and supports both ESM and CommonJS.
npm install @tongo/sdkInitialize the Client
import { TongoClient } from '@tongo/sdk';
const tongo = new TongoClient('rf_live_sk_your_api_key');
// Or with options
const tongo = new TongoClient({
apiKey: 'rf_live_sk_your_api_key',
baseUrl: 'https://api.tongorender.io/api', // optional
timeout: 30000, // optional, in ms
});Generate PDF
// Returns immediately with job info (status: "queued")
const job = await tongo.pdf.render({
html: '<h1>Invoice #1042</h1><p>Due: March 30</p>',
options: { format: 'A4', landscape: false, margin: { top: '20mm', bottom: '20mm' } },
});
console.log(job.id); // "rj_550e8400..."
console.log(job.status); // "queued"// Polls until complete, returns the finished job
const job = await tongo.pdf.renderAndWait({
html: '<h1>Invoice #1042</h1>',
options: { format: 'A4' },
}, {
interval: 1000, // poll every 1s (default)
timeout: 60000, // timeout after 60s (default)
onStatusChange: (j) => console.log('Status:', j.status),
});
console.log(job.url); // S3 signed URL to download
console.log(job.metadata.pages); // 3
console.log(job.metadata.size_bytes); // 125000Generate Image
const job = await tongo.image.renderAndWait({
html: '<div style="width:1200px;height:630px;background:#667eea;color:#fff;display:flex;align-items:center;justify-content:center;font-size:48px">OG Image</div>',
options: { format: 'png', width: 1200, height: 630, pixel_ratio: 2 },
});Screenshot
const job = await tongo.screenshot.captureAndWait({
url: 'https://example.com',
options: {
format: 'png',
width: 1440,
height: 900,
full_page: true,
dark_mode: true,
block_ads: true,
},
});Templates
// List templates
const templates = await tongo.templates.list({ category: 'invoices' });
// Render a template with data
const job = await tongo.templates.render('invoice-modern', {
data: {
company_name: 'Acme Corp',
invoice_number: 'INV-1042',
items: [{ name: 'Widget Pro', qty: 5, price: 29.99 }],
},
output_type: 'pdf',
});All Resources
| Resource | Methods | Description |
|---|---|---|
tongo.pdf | render(), renderAndWait() | HTML to PDF |
tongo.image | render(), renderAndWait() | HTML to Image |
tongo.screenshot | capture(), captureAndWait() | URL to Screenshot |
tongo.render | get(), download(), waitForCompletion() | Job status & download |
tongo.batch | render() | Batch render up to 10 jobs |
tongo.templates | list(), get(), render(), create(), update(), delete() | Template management |
tongo.keys | list(), create(), update(), revoke() | API key management |
tongo.usage | current(), history() | Usage statistics |
tongo.account | get() | Account info |
Error Handling
import { TongoApiError, TongoTimeoutError, TongoNetworkError } from '@tongo/sdk';
try {
const job = await tongo.pdf.renderAndWait({ html: '...' });
} catch (err) {
if (err instanceof TongoApiError) {
console.log(err.status); // 429
console.log(err.code); // "QUOTA_EXCEEDED"
console.log(err.message); // "Monthly render limit reached"
console.log(err.details); // { renders_used: 1000, renders_limit: 1000 }
} else if (err instanceof TongoTimeoutError) {
console.log(err.jobId); // "rj_..." — can retry polling later
} else if (err instanceof TongoNetworkError) {
console.log(err.message); // "Network error: ..."
}
}CLI (tongo)
The tongo CLI lets you render PDFs, images, and screenshots directly from your terminal. Login once and start rendering.
Install
npm install -g @tongo/cliAuthenticate
# Interactive login (email/password)
tongo login
# Or use an API key directly
tongo login --api-key rf_live_sk_your_key
# Check who you are
tongo whoamiRender
# Render HTML file to PDF
tongo render pdf invoice.html --output invoice.pdf --format A4
# Pipe from stdin
echo '<h1>Hello World</h1>' | tongo render pdf - --output hello.pdf
# With options
tongo render pdf report.html --output report.pdf \
--format Letter --landscape --margin "25mm" --scale 0.9# HTML to PNG
tongo render image banner.html --output banner.png --width 1200 --height 630
# HTML to WebP with quality
tongo render image card.html --output card.webp --format webp --quality 85# Screenshot a URL
tongo render screenshot https://example.com --output screenshot.png
# Full page, dark mode, no ads
tongo render screenshot https://news.site.com \
--output article.png --full-page --dark-mode --block-adsTemplates
# List available templates
tongo templates list
# Render a template with JSON data
tongo templates render invoice-modern --data order.json --output invoice.pdfAPI Keys & Usage
# Manage API keys
tongo keys list
tongo keys create --name "Production" --env live
tongo keys revoke 42
# Check usage with visual progress bar
tongo usageAll Commands
| Command | Description |
|---|---|
tongo login | Authenticate with email/password or API key |
tongo logout | Clear stored credentials |
tongo whoami | Show current user and plan info |
tongo render pdf <file> | Render HTML to PDF |
tongo render image <file> | Render HTML to image |
tongo render screenshot <url> | Screenshot a URL |
tongo render status <id> | Check render job status |
tongo templates list | List available templates |
tongo templates render <slug> | Render template with data |
tongo keys list | List API keys |
tongo keys create | Create new API key |
tongo keys revoke <id> | Revoke an API key |
tongo usage | Show usage stats with progress bar |
tongo config set <k> <v> | Set config value |
tongo config get <k> | Get config value |
JSON Output
Add --json to any command for machine-readable output. Perfect for scripting and CI/CD pipelines.
tongo render pdf page.html --json | jq '.url'
tongo usage --json | jq '.renders_remaining'Error Handling
The API returns standard HTTP status codes. Error responses include a JSON body with details.
| Status | Description |
|---|---|
400 | Invalid request body or parameters. |
401 | Missing or invalid API key. |
403 | Feature not available on your plan. |
429 | Rate limit or monthly quota exceeded. |
500 | Internal server error. Retry with exponential backoff. |
{
"error": {
"code": "validation_error",
"message": "Either 'html' or 'url' must be provided.",
"details": {
"field": "html",
"rule": "required_without:url"
}
}
}Rate Limits
Rate limits are applied per API key. When you exceed your rate limit, the API returns a 429 status code. Check the response headers for your current usage:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1711276800| Plan | Requests/min | Monthly renders |
|---|---|---|
| Free | 5 | 100 |
| Starter | 30 | 5,000 |
| Growth | 60 | 25,000 |
| Scale | 120 | 100,000 |