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 owner pre-signs the URL, so it always serves (it never blocks on quota the way the API does), and repeat hits are CDN-cached and deduped from metering.

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, and q is passed to the template as a modification.
  • scale (1–3) sets the device scale factor; q (0–100) sets JPEG/WebP quality.

# Signing

The easiest path: open a template in the app and copy its signed embed URL — it’s pre-signed and ready to paste into an <img> tag.

To mint URLs yourself, the sig is an HMAC-SHA256 over the template id, the extension, and the canonicalised query string (params sorted, sig excluded), using your signing secret:

js
import crypto from 'node:crypto';

function signRenderUrl(base, 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 `${base}/v1/templates/${id}/render.${ext}?${query}&sig=${sig}`;
}

A request with a missing or wrong sig returns 403. The signature only covers the params you signed, so a tampered URL (an extra or changed param) is rejected.

# 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