Skip to content

POST /render/from-url

Fetches a URL, extracts its Open Graph and HTML meta tags, and renders an image using the extracted content. Useful for generating social cards from existing web pages without manually copying titles and descriptions.

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

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

  1. OG Engine fetches the url you provide.
  2. It extracts og:title, og:description, og:image, twitter:title, twitter:description, and standard <title> / <meta name="description"> tags.
  3. The extracted values are used as the render payload. Any explicitly provided template, style, and output fields are applied on top.
  4. The rendered image is returned as binary, exactly like POST /render.
FieldTypeRequiredDefaultDescription
urlstringYesThe URL to fetch. Must be publicly accessible over HTTPS.
formatstringNo"og"Output image format preset: og, twitter, square, linkedin, story
templatestringNo"default"Template to use. Supports all 12 built-in templates and custom:<name> (Scale plan).
styleobjectNoStyle overrides applied after content extraction. Same fields as POST /render style.
output.formatstringNo"png"png, webp (Starter+)
output.qualitynumberNo901–100 (WebP only)
Terminal window
curl -X POST https://og-engine.com/render/from-url \
-H "Authorization: Bearer oge_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/blog/my-post",
"format": "og",
"template": "blog-hero",
"style": {
"accent": "#6366f1",
"font": "Inter"
},
"output": {
"format": "png"
}
}' \
--output card.png

OG Engine looks for the following tags in priority order:

Content fieldPriority order
Titleog:titletwitter:title<title>
Descriptionog:descriptiontwitter:description<meta name="description">
Background imageog:imagetwitter:image (used as background when the template supports it)

If none of the title sources are found, the request returns a 422 error with code no_content.

On success, the response body is the raw binary image. HTTP status: 200. Response headers are identical to POST /render, with the addition of:

HeaderExampleDescription
X-Source-Urlhttps://example.com/blog/my-postThe URL that was fetched
X-Extracted-TitleMy Post TitleThe title extracted from the page
StatusCodeCause
400missing_fieldurl not provided
400invalid_urlurl is not a valid HTTPS URL
401unauthorizedMissing or invalid API key
402plan_requiredWebP output requested on Free plan
422fetch_failedOG Engine could not fetch the URL (network error, timeout, or non-2xx HTTP response)
422no_contentPage was fetched but no usable title could be extracted
429rate_limitedMonthly quota exceeded
500server_errorInternal error

The error body includes a details.status field with the HTTP status code returned by the target URL, when available:

{
"error": "fetch_failed",
"message": "The URL returned HTTP 404.",
"details": { "url": "https://example.com/blog/missing", "status": 404 },
"docs": "https://og-engine.com/api-reference/errors#fetch_failed"
}
import { OGEngine } from '@atypical-consulting/og-engine-sdk'
const og = new OGEngine(process.env.OG_ENGINE_KEY!)
const image = await og.renderFromUrl({
url: 'https://example.com/blog/my-post',
format: 'og',
template: 'blog-hero',
style: { accent: '#6366f1' },
})
await Bun.write('card.png', image)