Open Graph images
Give every page its own link preview instead of one generic banner: send a template plus that page's title, image or price, and get back a rendered social card for chat apps and feeds. You pay per card, with no subscription.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
dynamic social cards from a template
Why every page deserves its own preview
Open Graph tags arrived in 2010 so that any web page could describe itself when shared, with a standard title, description and image for the link preview. More than fifteen years later, that same image still drives the preview card in chat apps, social feeds and messaging apps. For years the easy path was one static banner reused across a whole site, so every article, product and landing page looked identical when someone pasted its link. That flattens exactly the content that should stand out.
One template, a different card for each page
Instead of a hand-designed image per page, you supply a template plus the values for that page, and a finished card is rendered at publishing time. A blog can show each article's headline and hero image the moment it goes live, a shop can preview the product photo, name and current price, a job board can give every posting its role and company, and an event page can carry the name, date and speaker. No designer has to touch each page, and the finished image is available through a link that stays valid for 24 hours.
Where the Open Graph protocol comes from
Open Graph tags were introduced in 2010 to let any web page describe itself as a rich object when shared on social platforms, standardizing the title, description, and image that a link preview should show. Fifteen-plus years later, that same og:image tag still drives the preview card on chat apps, social feeds, and messaging platforms, which is exactly why a wrong or generic image there is such a visible, wasted opportunity.
What you can do with it
Blog and news publishing
Render a card showing each article's headline and hero image the moment it's published, instead of one shared banner site-wide.
E-commerce product pages
Generate a card with the product photo, name, and current price so shared product links preview accurately.
Job boards and listings
Produce a distinct card per job posting with the role title and company so shared listings stand out in a feed.
Event and webinar pages
Create a card with the event name, date, and speaker for each event page as it goes live.
FAQ
Is generating OG images free?
There's no free tier — free tiers get abused and slow everyone down. No subscription, no tokens, no invented credits, and a failed task is never charged.
What size are the generated images?
Cards are rendered at the dimensions expected for standard link-preview og:image usage across major sharing platforms.
Am I charged if a render fails?
No. A failed render is retried automatically up to three times and never billed if it doesn't ultimately succeed.
How is this different from a static og:image?
A static image is the same file for every page; this renders a unique card per page from live data, which is the whole point when content varies but the share image traditionally didn't.
What can the card show for each page?
Whatever values you send with the template for that page: an article's headline and hero image, a product's photo, name and price, a job's title and company, or an event's name, date and speaker.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/image/og \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'const res = await fetch("https://api.kit.forhosting.com/image/og", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://example.com"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/og",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://example.com"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/og", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://example.com"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://example.com"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/og", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://example.com"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.og",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 15 |
max_megapixels | 12 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |
Technical notes
Feed a template plus per-page data into our Open Graph image API and get back a rendered social card sized for link previews on every major platform. It exists so that a blog post, a product page, or a job listing does not have to share the same generic banner image every time someone pastes its link.
The problem with static share images
For years, the easy path was one static image reused across an entire site's Open Graph tags, which meant every article, every product, and every landing page looked identical when shared in a chat or social feed. That flattens exactly the content that should stand out. POST /image/og exists to render a distinct card per page, pulling in the title, a snippet, or a price at generation time instead of at design time.
How a card gets built
You submit a template reference along with the dynamic values for that specific page, the task is queued asynchronously and returns a task_id immediately, and the finished image is delivered by signed webhook or a signed link valid for 24 hours once rendering completes. That flow keeps page generation fast, since your app never waits on image rendering to finish a response.
Fitting it into a publishing pipeline
No designer has to touch each individual page. Because the endpoint takes a template and data rather than a hand-designed image, it plugs neatly into a CMS's publish hook: whenever a post, product, or event is created or updated, trigger a render, store the returned image, and update the page's og:image tag before the next crawl or share.
What determines the final look
The card's design comes entirely from the template you provide — the endpoint renders your layout with your data, it does not invent design decisions. That keeps output predictable and on-brand across hundreds or thousands of generated cards, rather than producing a look that drifts from page to page. If you maintain templates for different content types — an article layout, a product layout, an event layout — you can route each page to the matching template and still get consistent, on-brand output from a single endpoint.
Technical questions
How does the Open Graph image API generate a card?
You send a template and page-specific data to POST /image/og; it returns a task_id immediately and delivers the rendered image afterward via webhook or a signed link valid for 24 hours.
What's the cost per OG image?
Each request is $0.040 plus $0.001 per image rendered, and you're only billed when a card is successfully generated.
Can I design my own template?
Yes, the rendered card reflects whatever template and layout you provide; the API fills it with your dynamic data rather than imposing a fixed design.
Can I generate OG images in bulk for an entire catalog?
Yes, since each call is asynchronous and independent, you can queue a render for every product, post, or listing in a catalog and track each by its own task_id.