API reference

One endpoint. Every unique combination of parameters is rendered once and then cached.

Contents: Endpoint · Parameters · Templates · Examples · Caching · Limits · Errors · API keys · Other endpoints · Acceptable use · Privacy

Acceptable use: no impersonation, phishing or illegal content. Matching requests get 403 blocked_content and reported images are taken down.

Endpoint

GET https://ogforge.mike-tusa.workers.dev/api/og?template=blog&title=Hello%20world

Returns a 1200×630 PNG (Content-Type: image/png). HEAD is supported, and /og.png is an alias of /api/og for platforms that want a .png path. CORS is open (Access-Control-Allow-Origin: *) and images can be embedded from any site.

Parameters

All parameters are optional query-string values. URL-encode them. Unknown parameters are ignored and don't affect caching.

NameType / limitDescription
template (alias t)blog | launch | docs | minimal | gradientLayout. Default blog.
titletext, 120 charsMain headline. The font size shrinks for long titles, and anything over 3 lines is clipped with “…”. Default “Untitled”.
subtitle (alias description)text, 200 charsSecondary line (max 2 lines shown).
label (alias tag)text, 40 charsCategory (blog), pill (launch), version (docs) or eyebrow (gradient). Not shown in minimal.
sitetext, 60 charsSite or product name / domain.
authortext, 60 charsAuthor name (blog), or the breadcrumb section (docs).
emojione emojiShown as the logo mark (Twemoji graphics). Ignored when logo loads.
logohttps URL, 512 charsPNG, JPEG or SVG, at most 300 KB, fetched with a 3 s timeout. Must be a public https:// hostname (no IPs, credentials or custom ports). If it can't be loaded, the image renders without it, is cached for only 5 minutes, and carries an X-OgForge-Warning header.
themelight | darkBase palette. Defaults: blog/minimal light; launch/docs dark.
bghex colorBackground (0f172a, #0f172a or fff). For gradient it's the end color (default db2777).
fghex colorText color. If omitted with a custom bg, black or white is picked for contrast.
accenthex colorAccent bar, pills and highlights. For gradient it's the start color (default 6366f1).

Text is cleaned (control characters removed, whitespace collapsed). Text longer than its limit is truncated with “…” rather than rejected, and the response carries X-OgForge-Truncated: title,subtitle. The whole query string may be at most 2,000 characters. Bundled fonts cover Latin scripts (incl. accents); other scripts aren't supported yet.

Templates

TemplateDefault themeUses
bloglightlabel, title, subtitle, emoji/logo, site, author
launchdarkemoji/logo tile, label pill, title, subtitle, site · author
docsdarkemoji/logo, site / author breadcrumb (monospace), label as version pill, title, subtitle
minimallighttitle, subtitle, emoji/logo, site · author
gradientwhite text on accent→bg gradientemoji/logo, label, title, subtitle, site · author

Machine-readable list: /api/templates. See them all on the home page or try them in the playground.

Examples

curl -o og.png "https://ogforge.mike-tusa.workers.dev/api/og?template=launch&title=Introducing%20Nimbus%202.0&label=Now%20live&emoji=%F0%9F%9A%80"

curl -o og.png "https://ogforge.mike-tusa.workers.dev/api/og?template=docs&title=Rate%20limits&label=v1.4.0&site=acme%20docs&author=API"

curl -o og.png "https://ogforge.mike-tusa.workers.dev/api/og?template=gradient&title=Big%20news&accent=0ea5e9&bg=22c55e"

JavaScript

const params = new URLSearchParams({ template: 'blog', title: post.title, subtitle: post.excerpt, site: 'example.com' });
const ogImage = `https://ogforge.mike-tusa.workers.dev/api/og?${params}`;

HTML

<meta property="og:image" content="https://ogforge.mike-tusa.workers.dev/api/og?template=minimal&amp;title=Hello">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://ogforge.mike-tusa.workers.dev/api/og?template=minimal&amp;title=Hello">

Caching

Free-tier limits

LimitValueNotes
Image requests per IPabout 120 / minuteAll /api/og requests, cached or not.
New renders per IPabout 20 / minuteOnly cache misses count. Cached images don't.
New renders, whole serviceabout 60 / minute per Cloudflare locationProtects the free renderer. Returns 429 busy.
Badge“ogforge” in the bottom-right cornerFree renders only. Pro (coming soon) removes it.
Output1200×630 PNGOther sizes and formats aren't available yet.

Limits are approximate (counted per Cloudflare location) and may change. A 429 includes Retry-After: 60.

Errors

Errors are JSON with Cache-Control: no-store:

{ "error": { "code": "invalid_color", "message": "\"accent\" must be a hex color like 0f172a or #0f172a (3 or 6 hex digits).", "field": "accent" } }
StatusCodeWhen
400invalid_templateUnknown template.
400invalid_themetheme isn't light or dark.
400invalid_colorbg, fg or accent isn't a 3- or 6-digit hex color.
400invalid_emojiemoji isn't exactly one emoji.
400invalid_logologo isn't a public https URL.
400param_too_longlogo URL longer than 512 characters.
414query_too_longQuery string over 2,000 characters.
403blocked_contentText or logo host matches the acceptable-use denylist, or the image was taken down. The matched term isn't echoed back; field says which parameter matched, when applicable.
405method_not_allowedAnything except GET, HEAD or OPTIONS.
429rate_limitedPer-IP request or render limit hit. Includes limit, window and scope.
429busyService-wide render cap hit. Cached images still work.
500render_failed / internal_errorUnexpected failure. Please retry.

API keys (coming soon)

There is no paid plan yet, and no key is needed. A future Pro tier will accept a key only in a header (X-Api-Key: … or Authorization: Bearer …), never in the query string, because image URLs end up in public HTML. Until then, requests that send a key are served as free tier and get an X-OgForge-Note header saying so.

Other endpoints

Acceptable use

Don't use OgForge for impersonation (pretending to be a brand, person or organization you don't represent), phishing, or illegal content. OgForge keeps a denylist of phrases (checked in title, subtitle, label, site and author, ignoring case, accents and punctuation), of logo hosts, and of individual images. It is checked before the cache, so a taken-down image stops being served right away (copies already cached by other services may persist until they expire). Report abuse to digitalpromohub.support@gmail.com.

Privacy

Response headers on images

HeaderMeaning
X-OgForge-CacheMISS, HIT-MEMORY, HIT-EDGE or REVALIDATED
X-OgForge-Tierfree (only tier today)
X-OgForge-TruncatedComma-separated fields that were cut to their limit
X-OgForge-Warninge.g. logo_fetch_failed, logo_unsupported_type, logo_too_large, logo_http_404
ETagCache-key hash, for If-None-Match