MostlyRender

Signed render URLs

Render-on-the-fly from a plain URL — perfect for <img> tags, Open Graph images, and email. No API key travels to the browser: the URL carries a signature made with your account’s URL-signing secret, so nobody can change its data or point it at another template. Repeat hits are served from cache and never counted twice.

text
GET https://api.mostlyrender.com/v1/templates/{id}/render.{ext}?<modifications>&sig=<signature>

# Example

html
<img src="https://api.mostlyrender.com/v1/templates/tpl_abc/render.png?title=Hello&theme=dusk&sig=8f3c…" />
  • {ext} is png, jpg/jpeg, webp, or pdf.
  • Every query param other than the reserved sig, scale, q, and exp is passed to the template as a modification.
  • scale (1–3) sets the device scale factor; q (0–100) sets JPEG/WebP quality.

# Getting a signed URL

From the dashboard: open the Playground, pick a template and press Get signed URL — it’s ready to paste into an <img> tag.

From your backend, with your API key: ask us to sign it.

bash
curl -X POST https://api.mostlyrender.com/v1/templates/tpl_abc/signed-url \
  -H "Authorization: Bearer $MOSTLYRENDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modifications":{"title":"Hello"},"output":"png"}'
# → { "url": "https://api.mostlyrender.com/v1/templates/tpl_abc/render.png?title=Hello&sig=…", "expires_at": null }

Pass "expiresIn": 2592000 (seconds) for a URL that stops working after 30 days.

Sign it yourself (no request to us per URL): copy your URL signing secret from Settings. The sig is an HMAC-SHA256 over the template id, the extension, and the canonicalised query string (params sorted, sig excluded):

js
import crypto from 'node:crypto';

function signRenderUrl(secret, id, ext, params) {
  const query = Object.keys(params).sort()
    .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`).join('&');
  const sig = crypto.createHmac('sha256', secret).update(`${id}:${ext}:${query}`).digest('hex');
  return `https://api.mostlyrender.com/v1/templates/${id}/render.${ext}?${query}&sig=${sig}`;
}

// Optional expiry: include exp (unix seconds) BEFORE signing — it's covered by the signature.
signRenderUrl(process.env.MOSTLYRENDER_SIGNING_SECRET, 'tpl_abc', 'png',
  { title: 'Hello', exp: Math.floor(Date.now() / 1000) + 86400 });

Keep the signing secret server-side, like an API key. Rotating it in Settings invalidates every URL signed with the old one.

# Responses

Status Meaning
200 The image. X-MR-Cache: hit when served from cache.
402 The template owner’s free-plan quota is used up.
403 Missing or wrong sig — or an unknown template (we don’t reveal which).
410 The URL’s exp has passed.
429 Too many uncached renders for this template right now; cached URLs keep serving. Retry after Retry-After.

# When to use which

Use Reach for
Server-side generation, store the URL POST /v1/renders
Many at once Batch
Embed in <img>/OG/email, no key in the client Signed render URLs