Signed OG Image URLs

A signed OG image URL is a URL whose parameters are protected with an HMAC-SHA256 signature, so only you (and the code holding your secret) can request renders that spend your credits. FastOG signs the content — identical parameters always produce the identical, cached URL — which both protects your credits and makes caching deterministic.

Why sign OG image URLs

An OG image endpoint that renders arbitrary text from an unauthenticated URL is a free render farm anyone can hit. On a credit-based service that means anyone could burn your balance. Signing each URL with a secret only your backend knows blocks every unauthorized request on the first (uncached) fetch, while legitimate, cached URLs keep working.

How content signing works

  1. You build the canonical query string: every parameter (except the signature), sorted and RFC-3986 encoded.
  2. You compute HMAC_SHA256(secret, "GET/api/v1/og\n" + canonical).
  3. You append the signature as the s parameter.

The message includes no timestamp, so the URL is stable: same params → same URL → same cache entry.

canonical = "key=sk_...&template=default&title=Hello"
signature = HMAC-SHA256(secret, "GET/api/v1/og\n" + canonical)
url = ".../api/v1/og?key=...&template=default&title=Hello&s=" + signature

The trade-off people get wrong

Concern Reality
"A signed URL will expire" No — it's content-signed, valid until you rotate the secret
"A tampered URL breaks the cache" No — a bogus s only gets 401'd on a cache miss; cached images return anyway
"I need timestamps for security" Content signing is enough to stop credit abuse; no clock needed

One-file SDKs

FastOG ships a single signer file per language (zero dependencies) so you never hand-roll HMAC. Download from the SDK page or curl straight from the CDN:

bash
curl -O https://fastog.com/sdk/node.js

FAQ

Do signed URLs ever expire?

Not by default — they stay valid until you rotate the API key's HMAC secret. Content-signed, not time-signed.

Can someone else spend my credits by guessing a URL?

No. They need your HMAC secret to form a valid signature; without it, uncached renders return 401 invalid_signature.

Do I sign the URL in the browser?

No. Sign server-side (or in an edge function) where the secret never ships to the client. The rendered image URL is safe to put in your public <head>.

Related

Try it free — no signup required

Preview and test dynamic OG images in seconds.

Open the Free OG Image Tester