Every shared link needs an image. Designing one per post does not scale, and a generic brand image makes every share look the same.
The cheap version: render the page, or a small template you control, and point
og:image at the request.
<meta property="og:image"
content="https://api.screenshotline.com/take?url=https%3A%2F%2Fexample.com%2Fposts%2Fhello&viewport_width=1200&viewport_height=630&signature=...">
/take returns the image bytes directly, so the URL works anywhere an image
URL works. No JSON to unwrap, no second request.
Sign the URL
That URL is public. Anyone can read it in your HTML and spend your quota, so sign it:
node tools/sign.js "https://example.com/posts/hello" viewport_width=1200 viewport_height=630
The signature covers every parameter, so nobody can change the target URL or
the size and keep a valid request. With REQUIRE_SIGNATURE=true an unsigned
request is refused outright.
Make it cheap
Social crawlers hit the same URL repeatedly. Turn on the cache and pick a TTL that matches how often the page changes:
&cache=true&cache_ttl=86400
Cache hits are never billed and return faster than any cold render.
Sizes that work
1200 by 630 is the usual Open Graph size, and the large Twitter card uses the
same ratio. Add device_scale_factor=2 for a sharper image if you do not mind
the bytes.
If you render your own template rather than the live page, keep the template on a URL you control and pass the title in the query string. That gives you a per-post image with no design work per post.