Browse the docs Open Close
Signed URLs
one hotlink, infinite renders
A signed URL is a plain image link you drop straight into an
<img> tag or an
og:image meta tag. There is no API call
and no SDK. The browser requests the URL, and Snapsbrew renders the snap on
the spot. It is the easiest way to ship social cards, email art, or any image
that needs to change with your data.
Signed URLs are authenticated with an API token. You create a dedicated signed-URL key and use it as the secret that signs each link. That is different from Embedded Forms, where the signature is built into the link and no token is involved. Reach for signed URLs when your code generates the image, and embedded forms when a person fills it in.
1. Create a signed-URL key
In the dashboard, open Settings → Developers and generate a Signed URL key. The key can do one thing and one thing only: render signed URLs. Copy it the moment it appears, because you will not be able to read it again. If a key ever leaks, revoke it from the same screen and every link signed with it stops working straight away.
2. Sign the request
Put your parameters together, sort them by name, and sign the encoded string
with HMAC-SHA256 using your key as the
secret. Add the result back as a signature
parameter.
| Param | Required | Description |
|---|---|---|
template_id |
Yes | UUID of the template to render. |
variants |
No | Base64url-encoded JSON array of layer overrides, using the same layer, text, and image shape as the rest of the API. |
signature |
Yes | HMAC-SHA256 of the sorted query string, signed with your signed-URL key. |
Sign every parameter except signature
itself, and sort them by name first. The server sorts them again before it
checks the signature, so the order of the parameters in the final link does
not matter. What matters is that the bytes you signed were sorted.
<?php
// Layer overrides for this render.
$variants = json_encode([
['layer' => 'title', 'text' => $post->title],
['layer' => 'image', 'text' => $post->cover_url],
]);
// Base64url-encode the variants.
$variants = rtrim(strtr(base64_encode($variants), '+/', '-_'), '=');
$apiKey = config('services.snapsbrew.signed_url_key'); // your signed-URL key
$fields = [
'template_id' => 'a1b2c3d4',
'variants' => $variants,
];
ksort($fields); // sort by name before signing
$query = http_build_query($fields);
$signature = hash_hmac('sha256', $query, $apiKey);
$url = 'https://snapsbrew.com/signed-url/image.jpg?'.$query.'&signature='.$signature;
3. Embed it
Drop the link anywhere an image URL works. The endpoint answers with a redirect to the finished asset, so browsers, crawlers, and email clients all follow it without noticing the difference.
<meta property="og:image" content="https://snapsbrew.com/signed-url/image.jpg?template_id=a1b2c3d4&variants=...&signature=...">
<img src="https://snapsbrew.com/signed-url/image.jpg?template_id=a1b2c3d4&variants=...&signature=..." alt="Share card">
Billing and caching
The first request for a given link renders the snap and costs the key owner 1 credit. After that, Snapsbrew caches the result against the exact link, so every later request is served from cache. It is free and instant. Change any parameter and you have a new link, which means a fresh render and one more credit.
Good to know
A bad, missing, or revoked signature does not return an error. It renders
a neutral placeholder image instead. That stops a broken
<img> tag from showing a 404, but
it also means a silent placeholder is your hint that the signature is
wrong.
variants has to be base64url
(swap +/ for
-_ and strip the padding), and it has to
be part of the sorted query string you signed.