How to Use ApiFlash to Create Open Graph Preview Images
Capture a designed webpage with ApiFlash, publish the image URL in Open Graph metadata, and troubleshoot the rendering and caching issues that affect previews.
Direct answer: ApiFlash can capture a webpage that renders your Open Graph preview image, but it does not automatically design a branded card from a title and theme. Build a page that displays the card at your chosen dimensions, capture it with ApiFlash, store the resulting image at a public URL, and use that URL in the shared page’s og:image tag. ApiFlash’s endpoint is https://api.apiflash.com/v1/urltoimage; it accepts GET or POST requests with an access key and a complete target URL. See the ApiFlash API documentation.
1. Choose what page ApiFlash should capture
ApiFlash captures a rendered page in Chrome. It is not a graphic-design system that turns arbitrary text into a composed social card. You have two practical approaches:
- Capture an existing page: useful when its current layout is already suitable for the image. This is quick, but the result may include navigation, page content, or responsive layout that you do not want in a preview.
- Create a dedicated card page: render only the desired design at a known viewport size. This gives you control over typography, colors, branding, and layout. Keep it publicly reachable by ApiFlash, or use the documented options for pages that require authentication.
For a predictable card, make the capture page’s CSS explicitly size the card and keep the surrounding page plain. ApiFlash’s width and height set the browser viewport; the result depends on the page’s layout and the capture settings. The Open Graph protocol does not prescribe one universal image size for every social service. Choose dimensions for your design and intended consumers, then verify the resulting preview.
2. Build and capture a card page
Here is a minimal page that renders a card. Save it as card.html and serve it at a publicly reachable HTTPS URL before asking ApiFlash to capture it. Replace the example content with your design.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Preview card</title>
<style>
* { box-sizing: border-box; }
html, body { margin: 0; width: 100%; height: 100%; }
body {
display: grid;
place-items: center;
background: #111827;
font: 700 56px/1.1 system-ui, sans-serif;
color: white;
}
.card {
width: 1200px;
height: 630px;
padding: 72px;
display: flex;
flex-direction: column;
justify-content: space-between;
background: linear-gradient(135deg, #1d4ed8, #111827);
}
.eyebrow { font-size: 24px; letter-spacing: .12em; text-transform: uppercase; }
.title { max-width: 950px; }
.footer { font-size: 24px; font-weight: 500; }
</style>
</head>
<body>
<main class="card">
<div class="eyebrow">Engineering notes</div>
<div class="title">A useful preview image starts with a page</div>
<div class="footer">example.com</div>
</main>
</body>
</html>
Assume the deployed page is https://example.com/og-cards/article-1. Keep the API key out of public browser code. Run the following requests from a server, shell, or other trusted environment. ApiFlash documents GET with query parameters and POST with form data; encode parameter values, especially the target URL.
cURL
curl -G 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_APIFLASH_ACCESS_KEY' \
--data-urlencode 'url=https://example.com/og-cards/article-1' \
--data-urlencode 'width=1200' \
--data-urlencode 'height=630' \
--data-urlencode 'format=png' \
-o article-1.png
Python
import os
import requests
endpoint = "https://api.apiflash.com/v1/urltoimage"
params = {
"access_key": os.environ["APIFLASH_ACCESS_KEY"],
"url": "https://example.com/og-cards/article-1",
"width": 1200,
"height": 630,
"format": "png",
}
response = requests.get(endpoint, params=params, timeout=60)
response.raise_for_status()
with open("article-1.png", "wb") as image_file:
image_file.write(response.content)
Node.js
import { writeFile } from "node:fs/promises";
const endpoint = new URL("https://api.apiflash.com/v1/urltoimage");
endpoint.search = new URLSearchParams({
access_key: process.env.APIFLASH_ACCESS_KEY,
url: "https://example.com/og-cards/article-1",
width: "1200",
height: "630",
format: "png",
});
const response = await fetch(endpoint);
if (!response.ok) {
throw new Error(`ApiFlash returned HTTP ${response.status}: ${await response.text()}`);
}
await writeFile("article-1.png", Buffer.from(await response.arrayBuffer()));
In production, adapt error handling and the timeout to your runtime. A successful binary response is the image itself by default. The image must then be uploaded to storage or otherwise served from a stable, public URL. Do not point og:image at a local file, an expiring private URL, or an API request that requires a secret key.
3. Set capture parameters for the design
ApiFlash’s API reference documents these relevant controls. Check the live documentation for current limits and plan availability before relying on a parameter.
| Setting | How to use it |
|---|---|
url |
Required complete page URL, including https:// or http://. |
access_key |
Your API key. Keep private keys on the server and out of source control and public JavaScript. |
width, height |
Browser viewport dimensions. The documented default is 1920 by 1080. Stay within the documented combined pixel-area limit. When full_page=true, the height parameter is ignored. |
format |
JPEG, PNG, or WebP. Choose based on downstream compatibility and file-size needs; verify what your preview consumers accept. |
| quality | Controls quality for JPEG and WebP. It does not apply in the same way to PNG. |
full_page |
Capture the whole page. Usually unnecessary for a card page whose design fits inside the viewport. |
element |
Capture the first element matching a CSS selector. Useful if the page contains other content; ensure the selector exists when capture occurs. |
wait_for |
Wait for a CSS selector to appear. ApiFlash documents a 15-second limit; a missing selector results in an error. |
wait_until |
Wait for a page readiness state. Prefer a suitable readiness or selector condition over an arbitrary delay where possible. |
delay |
Fixed delay in the documented 0–10 second range. Use only when rendering needs a short, known extra time. |
response_type=json |
Return JSON containing a screenshot link rather than the image body. JSON mode can also request extracted HTML or text when needed. |
fresh |
Bypass ApiFlash’s screenshot cache to make a fresh capture. |
| Cache TTL | Documented default is 86,400 seconds; the reference permits up to 2,592,000 seconds. Repeated identical requests may return a cached screenshot. |
| CSS/JavaScript injection | Adjust the rendered page when appropriate, using the documented injection parameters. Avoid depending on fragile injected selectors where you can control the capture page. |
For a card design, start with a viewport matching the CSS card size. Set format based on the intended audience: PNG preserves sharp edges and text cleanly, while JPEG and WebP provide quality controls and may suit different size requirements. Test the resulting file and the receiving platforms rather than assuming one format or dimension works everywhere.
4. Store the image and add Open Graph metadata
Upload the saved image to a publicly fetchable HTTPS location and use its absolute URL in the page being shared. The Open Graph protocol names og:title, og:type, og:image, and og:url as the four required properties; og:image identifies an image representing the page. See the Open Graph protocol specification.
<head>
<title>Example article title</title>
<meta property="og:title" content="Example article title">
<meta property="og:type" content="article">
<meta property="og:url" content="https://example.com/articles/article-1">
<meta property="og:image" content="https://cdn.example.com/og/article-1.png">
<meta property="og:image:alt" content="A blue preview card for the article about useful preview images">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
</head>
Use the canonical URL of the shared page for og:url, not the temporary capture page, unless that capture page is itself the object you intend people to share. Optional image properties can describe MIME type, dimensions, secure URL, and alternative text. The dimensions above are an example design choice, not a universal protocol mandate. Ensure the image URL returns the image directly to unauthenticated fetchers and that the server’s content type matches the file.
5. Validate the complete preview path
- Open the capture page directly and confirm the card is visible at the chosen viewport size.
- Call ApiFlash and inspect the downloaded image. Check text wrapping, font loading, image loading, clipping, and background color.
- Upload the image and fetch its public URL without cookies or authorization. Confirm it returns an image and not an HTML error page or redirect to a login screen.
- Fetch the shared page’s HTML and confirm its Open Graph tags appear in the document head. A client-rendered page that inserts tags only after JavaScript runs may not expose them to every preview crawler.
- Use the target platform’s preview inspection or refresh mechanism, if available, to diagnose what it fetched. Platform behavior differs and the protocol does not define a universal cache-refresh process.
ApiFlash’s fresh setting only addresses its screenshot cache. Social platforms and messaging services can cache page metadata and image responses independently. A new ApiFlash capture does not guarantee that a platform immediately refetches the shared page or image.
6. GET, POST, and JSON response options
GET is convenient for scripts and command-line examples, but query strings can appear in logs. POST with form data can reduce exposure in URL logs; it does not replace secret handling or transport security. Use the API reference’s parameter names and encoding rules for either method.
curl -X POST 'https://api.apiflash.com/v1/urltoimage' \
--data-urlencode 'access_key=YOUR_APIFLASH_ACCESS_KEY' \
--data-urlencode 'url=https://example.com/og-cards/article-1' \
--data-urlencode 'width=1200' \
--data-urlencode 'height=630' \
--data-urlencode 'format=png' \
-o article-1.png
To receive JSON instead of image bytes, request response_type=json as documented, parse the response, and use the returned screenshot link according to its documented lifecycle. Store or copy the image into your own durable public storage if the preview URL must remain stable. JSON mode can also include extracted HTML or text when requested, but those fields are not needed for the ordinary image-to-Open-Graph workflow.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from ScreenshotNeo. It can capture the card page with one request, and its screenshot parameter names also work with names used by other screenshot APIs. Use the ScreenshotNeo API documentation for the complete options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/og-cards/article-1 -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/og-cards/article-1"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/og-cards/article-1' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Store the returned image at a stable public URL and put that URL in og:image. Sign up for free and capture 1,000 screenshots a month with no card.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| ApiFlash rejects the request or reports a missing URL | The target URL is absent, incomplete, or malformed. | Include the complete scheme and host, for example https://example.com/og-cards/article-1, and URL-encode query values. |
| Authentication fails | The access key is missing, invalid, or not being sent under the expected parameter name. | Check the key and request encoding. Keep it in a server environment variable; do not place it in public frontend code. |
| Image dimensions or layout look wrong | The viewport differs from the card CSS dimensions, or full-page mode changes capture behavior. | Match width and height to the design, inspect responsive breakpoints, and omit full_page for a fixed-size card. |
| Capture fails because an element is missing | The element or wait_for selector does not match, or appears after the documented wait limit. |
Check the selector in the rendered page, make the card render sooner, or use a suitable wait_until condition. |
| Fonts, images, or client-rendered content are absent | Resources load asynchronously or are blocked/inaccessible to the capture browser. | Make resources publicly reachable, wait for a meaningful selector or readiness state, and use a bounded delay only when needed. |
| Downloaded file is JSON or an error body | The request asked for JSON, failed, or the client treated a non-success response as an image. | Check the HTTP status and content type. Remove JSON response mode for binary output and surface API error bodies during debugging. |
| Open Graph preview shows an old image | ApiFlash may have served a cached capture, or the consumer has separately cached the page or image. | Use ApiFlash’s fresh option when recapturing, publish the new image URL, and use the consumer’s available preview inspection or refresh tools. |
| Image link works in your browser but preview is missing | Your browser may have cookies or credentials that a crawler does not; the URL may redirect, expire, or return the wrong content type. | Test the URL without authentication, serve it publicly over HTTPS, and confirm it returns the image bytes directly. |
| API request is unexpectedly slow | The page itself may be slow, wait conditions may take time, or the request may perform a fresh capture. | Keep the card page light, wait for the specific required content, and use an appropriate cache TTL when the image is unchanged. |
Performance, reliability, and cost
Capture cost and latency depend on the API plan and the page being rendered; the research sources do not establish a universal benchmark. Keep the capture page small: avoid unrelated scripts, large resources, and unnecessary third-party calls. Prefer selector or readiness-based waiting when it reflects actual page state. Fixed delays add latency even when rendering finishes sooner, and a delay cannot guarantee success if a resource never arrives.
ApiFlash documents a default screenshot cache TTL of 86,400 seconds and a maximum of 2,592,000 seconds. Repeated identical requests can use cached screenshots and, according to its documentation, do not count against monthly quota. Use fresh when the page has changed and a new capture is required. For stable publishing, save the captured bytes in storage you control instead of depending on an ephemeral response URL. Cache behavior at ApiFlash, your image host, and the social platform are separate layers.
Handle failures explicitly in automation: check HTTP status before writing a file, retain enough error detail to diagnose rejected parameters, and retry only transient failures with a bounded retry policy. Avoid parallel bursts unless your plan and the service documentation support the intended concurrency. Protect API keys, and rotate a key if it is exposed in logs or client code.
FAQ
Can ApiFlash generate an Open Graph card from only a title?
No. It captures a rendered webpage. Create a page that lays out the title and other design elements first.
Does the captured card page need to be the page I share?
No. The card page is a capture source. The shared article’s og:image can point to the separately stored image.
Does a successful fresh capture force social platforms to show it immediately?
No. ApiFlash’s cache and a consumer’s metadata or image cache are independent.
Is one image dimension required by the Open Graph protocol?
The protocol defines the image property, not a single universal dimension for all social preview consumers.
Should I expose the capture API key in a static website?
No. Keep a private key on a server-side component and have that component make the API request.


