Skip to content

POST /render

Renders a single image from a structured JSON payload. Returns the binary image bytes directly — not a URL to an image.

POST https://og-engine.com/render

Authentication: Required (Authorization: Bearer oge_sk_...)

FieldTypeRequiredDefaultConstraints
formatstringYesog, twitter, square, linkedin, story
templatestringNo"default"default, social-card, blog-hero, email-banner, or custom:<name> (Scale plan)
titlestringYesMax 200 characters
descriptionstringNoMax 500 characters
authorstringNoMax 100 characters
tagstringNoMax 50 characters
style.accentstringNo"#38ef7d"Valid hex color (#rrggbb or #rgb)
style.fontstringNo"Outfit"One of the 8 supported fonts
style.titleSizenumberNo4828–72
style.descSizenumberNo2214–32
style.layoutstringNo"left"left, center, bottom
style.gradientstringNo"void"void, deep-sea, ember, forest, plum, slate
style.overlayOpacitynumberNo0.650.2–0.9 (used with background image)
style.autoFitbooleanNofalseAuto-adjust font sizes to prevent overflow
output.formatstringNo"png"png, webp (Starter+), pdf
output.qualitynumberNo901–100 (WebP only)
Terminal window
curl -X POST https://og-engine.com/render \
-H "Authorization: Bearer oge_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "og",
"template": "default",
"title": "Server-Side Text Layout Without a Browser",
"description": "Pure JS text measurement replaces Puppeteer. ~22ms renders ([benchmarked](/benchmarks/)), zero browser dependencies.",
"author": "Pretext Engine",
"tag": "Open Source",
"style": {
"accent": "#38ef7d",
"font": "Outfit",
"titleSize": 48,
"descSize": 22,
"layout": "left",
"gradient": "void"
},
"output": {
"format": "png"
}
}' \
--output card.png

To supply a background image, use multipart/form-data. The JSON payload goes in a field named config, the image in image:

Terminal window
curl -X POST https://og-engine.com/render \
-H "Authorization: Bearer oge_sk_YOUR_KEY" \
-F 'config={
"format": "og",
"template": "blog-hero",
"title": "Building in the Open",
"style": { "overlayOpacity": 0.65 }
}' \
-F 'image=@cover.jpg' \
--output card.png

Accepted image formats: JPEG, PNG, WebP. Maximum size: 5MB.

On success, the response body is the raw binary image. The HTTP status is 200.

HeaderExampleDescription
Content-Typeimage/pngMIME type (image/png, image/webp, or application/pdf)
X-Cachemisshit if served from image cache, miss otherwise
X-Render-Time-Ms2.34Server-side render time in milliseconds
X-Title-Lines2Number of lines the title was wrapped to
X-Desc-Lines3Number of lines the description was wrapped to
X-Layout-Overflowfalsetrue if any text was truncated with ellipsis
X-RateLimit-Limit500Monthly render quota
X-RateLimit-Remaining483Renders remaining this month
X-RateLimit-Reset1735689600Unix timestamp (seconds) of next quota reset

If your title or description is too long to fit within the max lines for the chosen format, OG Engine truncates the last visible line and appends . The response header X-Layout-Overflow: true signals this occurred.

To prevent truncation, use /validate before rendering to check fit, and adjust font size or shorten the text accordingly.

StatusCodeCause
400missing_fieldformat or title not provided
400invalid_formatformat is not one of the allowed values
400invalid_fontstyle.font is not a supported font
400invalid_fileBackground image is too large or corrupt
401unauthorizedMissing or invalid API key
402plan_requiredWebP output requested on Free plan
429rate_limitedMonthly quota exceeded
500server_errorInternal error
0.0ms|8500x
Accent
Font
Layout
Gradient
48
22