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
- You build the canonical query string: every parameter (except the signature), sorted and RFC-3986 encoded.
- You compute
HMAC_SHA256(secret, "GET/api/v1/og\n" + canonical). - You append the signature as the
sparameter.
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:
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