Signed, expiring URLs
Every query parameter is HMAC-SHA256 signed with your key, and every URL carries an expiry. Nobody can spend your credits by editing the title.
Rendra turns a signed URL into a 1200×630 social card. Pick a template, pass title and description as query parameters, sign them with your API key — crawlers get a PNG, cached for a day, billed once. A signed URL becomes a 1200×630 social card. Pick a template, pass title and description, sign with your API key. Crawlers get a PNG, cached for a day, billed once.
50 renders a month free. No card. Sign in with Google or a magic link. 50 renders a month free. No card.
// the URL in your <meta property="og:image">
https://rendra.alphabros.eu/i/og_standard
?title=Ship+faster
&description=Beautiful+social+cards+from+one+URL
&expires=1788393600
&sig=<key id>.<hmac-sha256 of the sorted query>
// sign it once, server-side (Node)
const digest = createHmac("sha256", RENDRA_API_KEY)
.update(`${path}?${query}`)
.digest("hex");
query.set("sig", `${RENDRA_API_KEY_ID}.${digest}`);
Social crawlers fetch og:image with a plain GET. Rendra makes that GET safe, cheap and repeatable.
Every query parameter is HMAC-SHA256 signed with your key, and every URL carries an expiry. Nobody can spend your credits by editing the title.
Two templates today: og_standard for evergreen cards and announcement for launches. Custom templates are on the Pro roadmap.
Identical renders come back from cache with X-Cached: true and cost nothing. Responses stay public and immutable for up to 24 hours.
Sign in with Google or a magic link. Create named API keys, revoke one without touching the others, and watch usage against your monthly quota.
Your generation history lives in the dashboard and behind /api/v1/dashboard/history, so you can see what shipped and when.
POST a prompt, then poll for the image. It runs on a provider chain with automatic failover. In preview now, not yet part of the plans below.
Everything below is in the OpenAPI spec at /openapi.yaml.
One public call with your email creates the account and returns the key and its id. Or sign in and create named keys in the dashboard.
$ curl -X POST \
https://rendra.alphabros.eu/api/v1/users \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
201 Created
{ "id": "…", "email": "you@example.com",
"api_key": "rendra_…", "plan": "free" }
Sort the query, sign path plus query with HMAC-SHA256 using your key, and append sig as key id, a dot, then the hex digest.
const path = "/i/og_standard";
const query = new URLSearchParams({
title: "Ship faster",
description: "Beautiful social cards…",
expires: String(Math.floor(Date.now() / 1000) + 3600),
});
query.sort();
// sig = keyId + "." + hmac(path+"?"+query)
Put the URL in your og:image tag. Crawlers get the PNG; a bad or expired signature gets a 403, an exhausted quota a 402.
GET /i/og_standard?title=…&expires=…&sig=…
200 OK
Content-Type: image/png
Cache-Control: public, max-age=86400, immutable
X-Cached: false
403 { "error": "Invalid or expired signature" }
402 { "error": "Credit limit exceeded" }
Rendering server-side instead? POST /api/v1/render with the same template, data, width, height and format fields and your API key.
One render is one credit. Credits reset monthly. Cache hits are never counted.
Hobby projects, testing, small blogs.
Businesses, agencies, high-traffic blogs.
Extra credits: €0.50 per 10. Unused credits don't roll over. 30-day money-back guarantee.
50 renders a month, free. Sign the first URL in the time it takes to read the spec.
Get your free API key