API Reference
OG Screenshot API
Generate a PNG screenshot of any URL using a saved template. The image is returned directly — drop the endpoint URL into any og:image meta tag and you're done.
Endpoint#
/api/og/v1/:templateId?url=<targetUrl>Returns a PNG image of the target URL rendered with the template's configuration.
Authentication#
This endpoint requires no authentication header. The URL itself is the credential — it embeds your template ID, and Linkshot validates the request by checking:
- The
templateIdreferences an existing template owned by an active subscriber. - The domain of the
urlquery parameter is in your registered domain list (subdomains are allowed automatically).
Keep your template IDs private
Parameters#
| Parameter | Type | In | Description | |
|---|---|---|---|---|
templateId* | string (UUID) | path | — | The UUID of the template to use. Find this in Dashboard → Templates. |
url* | string (URL) | query | — | The fully-qualified URL of the page to screenshot. Must be on a domain you have registered. |
Template Configuration#
Each template stores a set of capture settings that control how the screenshot is taken. You configure these in the dashboard — they are not passed as query parameters.
| Setting | Type | Default | Description |
|---|---|---|---|
viewportWidth | integer | 1200 | Browser viewport width in pixels (320–3840). |
viewportHeight | integer | 630 | Browser viewport height in pixels (200–2160). 1200×630 is the OG standard. |
deviceScaleFactor | integer | 2 | Pixel density multiplier (1–3). 2 produces retina-quality output. |
scrollPosition | integer | 0 | Vertical scroll offset in pixels before capturing. |
enableTailwindInjection | boolean | true | Inject TailwindCSS into the page before capturing. Enables Tailwind classes to render correctly. |
waitTimeout | integer | 0 | Additional wait time in milliseconds after page load before capturing (0–3000). |
blockPopups | boolean | true | Block cookie banners and popup overlays before capturing. |
Response#
A successful request returns the screenshot directly as a PNG image.
Content-Type: image/png
Cache-Control: public, s-maxage=600, stale-while-revalidate=600
X-Cache: HIT | MISSX-Cache header
X-Cache: HIT — the image was served from cache. A background job is regenerating it so the next request gets a fresh copy.
X-Cache: MISS — the image was freshly generated and is now cached.
Caching#
Screenshots are cached keyed by templateId + sha256(url).
- Cache hit: The cached image is returned immediately. A background job regenerates it so the next request gets a fresh copy.
- Cache miss: The screenshot is generated synchronously, stored to R2, and returned.
- TTL:
s-maxage=600, stale-while-revalidate=600(10 minutes).
Example#
curl -X GET \
"https://uselinkshot.com/api/og/v1/84ed4d78-7ad7-40cb-8abc-dbd122d4da79?url=https%3A%2F%2Fexample.com%2Fblog%2Fmy-post"<meta property="og:image"
content="https://uselinkshot.com/api/og/v1/TEMPLATE_ID?url=https://example.com/blog/my-post" />
<meta name="twitter:image"
content="https://uselinkshot.com/api/og/v1/TEMPLATE_ID?url=https://example.com/blog/my-post" />
<meta name="twitter:card" content="summary_large_image" />URL-encode the target URL
url parameter must be URL-encoded (percent-encoded). Use encodeURIComponent() in JavaScript or urllib.parse.quote() in Python. Most OG image meta tag contexts encode automatically.Error Responses#
All error responses have Content-Type: application/json and include an error field with a machine-readable code.
{
"error": "Missing url parameter",
"message": "Please provide a url query parameter"
}{
"error": "Invalid URL",
"message": "The provided url is not a valid URL"
}{
"error": "Template not found",
"message": "The specified template does not exist"
}{
"error": "No active subscription",
"message": "The template owner does not have an active subscription"
}{
"error": "Domain not authorized",
"message": "The domain \"example.com\" is not in the authorized domain list"
}{
"error": "navigation_timeout",
"message": "Page failed to load within timeout: https://example.com/page"
}{
"error": "screenshot_failed",
"message": "Screenshot generation failed: <error detail>"
}