Generating Images
The /render endpoint is the heart of OG Engine. Send a JSON payload describing what you want, receive a binary image — PNG by default, WebP on paid plans. This guide walks through what happens under the hood, the minimal and full request shapes, and how to interpret the response headers.
How Rendering Works
Section titled “How Rendering Works”When your request hits the API, OG Engine follows a four-step pipeline:
- Text measurement — Pretext’s
prepareWithSegments()analyzes your title and description text, handling Unicode grapheme clusters, CJK characters, Arabic, emoji, and bidirectional text with full accuracy. - Layout —
layoutWithLines()breaks each text block into lines given the available width, font metrics, and line height. Overflow is detected and an ellipsis is appended if the text exceedsmaxLines. - Canvas draw — The selected template composites the background gradient (or image), decorative elements, and each line of text onto an
@napi-rs/canvassurface. - PNG encode — The canvas is serialized to a binary buffer and streamed back as the HTTP response body.
Total time from request to response: typically ~22ms for a standard OG image (benchmarked). PNG encoding dominates; text layout + canvas draw take <1ms.
Minimal Request
Section titled “Minimal Request”The only required fields are format and title:
curl -X POST https://og-engine.com/render \ -H "Authorization: Bearer oge_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"format": "og", "title": "Hello, World"}' \ --output image.pngThis uses all defaults: the default template, Outfit font at 48px, the void gradient, and left-aligned layout.
Full Request
Section titled “Full Request”A fully specified request gives you control over every visual parameter:
{ "format": "og", "template": "default", "title": "Server-Side Text Layout Without a Browser", "description": "Pure JS text measurement replaces Puppeteer. ~22ms renders, zero browser dependencies.", "author": "Pretext Engine", "tag": "Open Source", "style": { "accent": "#38ef7d", "font": "Outfit", "titleSize": 48, "descSize": 22, "layout": "left", "gradient": "void", "overlayOpacity": 0.65 }, "output": { "format": "png", "quality": 90 }}Any field you omit falls back to its default. You never need to send the full object.
Reading Response Headers
Section titled “Reading Response Headers”Every successful /render response includes diagnostic headers alongside the image bytes:
| Header | Example | Meaning |
|---|---|---|
Content-Type | image/png | Output format |
X-Render-Time-Ms | 2.34 | Total server-side render time in milliseconds |
X-Title-Lines | 2 | Number of lines the title was broken into |
X-Desc-Lines | 3 | Number of lines the description was broken into |
X-Layout-Overflow | false | Whether any text was truncated with ellipsis |
X-RateLimit-Limit | 500 | Your plan’s monthly render limit |
X-RateLimit-Remaining | 483 | Renders remaining this month |
X-RateLimit-Reset | 1735689600 | Unix timestamp when quota resets |
You can use X-Layout-Overflow: true as a signal to call /validate with a smaller font size and retry — or simply display a warning in your UI.
# Inspect headers without saving the image bodycurl -I -X POST https://og-engine.com/render \ -H "Authorization: Bearer oge_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"format": "og", "title": "Checking overflow"}'Output Formats
Section titled “Output Formats”PNG (all plans)
Section titled “PNG (all plans)”PNG is the default. It is lossless, supports transparency, and is universally accepted by social platforms. Most OG images are 1200×630 at approximately 80–200KB depending on complexity.
{ "output": { "format": "png" } }WebP (Starter and above)
Section titled “WebP (Starter and above)”WebP delivers 25–35% smaller files than PNG at equivalent visual quality. Ideal for high-volume scenarios or performance-sensitive applications.
{ "output": { "format": "webp", "quality": 85 } }The quality field (1–100, default 90) controls the WebP lossy compression level. Values between 80–90 are recommended for social cards. Attempting to request WebP on the Free plan returns a plan_required error.
SDK Example
Section titled “SDK Example”import { OGEngine } from '@atypical-consulting/og-engine-sdk'
const og = new OGEngine(process.env.OG_ENGINE_KEY!)
const imageBuffer = await og.render({ format: 'og', title: 'Server-Side Text Layout Without a Browser', description: 'Pure JS text measurement replaces Puppeteer.', tag: 'Open Source', style: { accent: '#38ef7d', font: 'Outfit' },})
// Node.js / Bunawait Bun.write('output.png', imageBuffer)Try It Live
Section titled “Try It Live”Edit the title and description below to see how rendering works in real time:
Next Steps
Section titled “Next Steps”- Read Formats & Templates to understand the 5 format presets and 4 templates
- Learn how to Customize Styles with fonts, colors, and gradients
- Explore the POST /render API Reference for the complete field reference