Use case · Publishing

A share image for every story, made from the story.

Put the headline, section, byline and lead photo into a template once. After that every article has its own card, rendered the first time someone shares the link. No designer in the queue, no build step, no plugin to keep up to date.

150 images a month free, no card. A site publishing 40 stories a day fits in the $9 plan.

live · POST /v1/images1200 × 630
News article with lead photo, rendered with the sample variables
rendering…
rendered with the sample variables · change them and render again
Open in the editorThe template
the same render with your saved copy
curl -X POST https://api.imageapis.com/v1/images \
  -H 'X-API-Key: YOUR_KEY' -H 'Content-Type: application/json' \
  -d '{"template": "tpl_…", "variables": {"publication": "The Daily Example", "section": "Climate", "title": "The tide gauges were right. The flood maps were not.", "author": "Priya Natarajan", "date": "12 October 2026", "photo": "https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=1200"}}'
How it works

Three ways in. Use the one your stack allows.

Most sites need only the first: the theme writes the image URL, and the image is made when a crawler asks for it.

GET img.imageapis.com/s/…

In the theme: a signed URL

The article template builds the image URL with an HMAC, next to where it prints the headline. The first fetch, usually a social network's crawler, renders the card; later fetches come from the cache. Nothing runs at publish time, and the archive needs no backfill: an old story gets its card the first time someone shares it.

publish webhook → og_image

On publish: store the URL

When the theme can't run code, as on Ghost or a hosted CMS, its publish webhook can. A few lines sign the same URL and write it into the story's social image fields. The card still renders on first fetch, so the hook never waits for a browser.

POST /v1/collections · text/csv

Right now: a CSV of stories

For a social scheduler, a newsletter or your media library, you want the files in hand. Post a CSV with a row per story, up to 1,000 at a time; every URL comes back at once and a webhook says when they are done. Try ten rows.

# 1. Copy the news article starter into your account; its id is your template
curl -s https://api.imageapis.com/v1/starters/news-article -H 'X-API-Key: YOUR_KEY' | jq .template > card.json
curl -X POST https://api.imageapis.com/v1/templates -H 'X-API-Key: YOUR_KEY' \
  -H 'Content-Type: application/json' -d @card.json
# → { "id": "tpl_…", "object": "template", … }

# 2. A signed base that can render that template and nothing else
curl -X POST https://api.imageapis.com/v1/signed-bases -H 'X-API-Key: YOUR_KEY' \
  -H 'Content-Type: application/json' -d '{"name":"article cards","template":"tpl_…"}'
# → { "id": "sb_…", "secret": "sbs_…", … }

# Keep them where your code can read them: OG_TEMPLATE=tpl_…  OG_BASE=sb_…  OG_SECRET=sbs_…

Sign the query string exactly as you send it: http_build_query and URLSearchParams both write spaces as +, which is why each example signs the string it then puts in the URL. The signed URLs guide has Python too, and the Next.js guide walks through checking the card in the X and LinkedIn validators.

Headline fitting

Three words or thirty, the headline fits.

The headline layer is set at 64 px with fit: "shrink". Once the web font has loaded, the browser steps the size down until every line sits inside the box. Nobody picks a size per story, and nothing runs off the card.

A news card with a three-word headline set large
3 words · 64 px, as set
The same card with a ten-word headline on four lines
10 words · 64 px, four lines
The same card with a 28-word headline shrunk to six lines
28 words · shrunk to fit, six lines
Beyond the card

The rest of what a newsroom asks for.

imageapis.com/editor

Redesign once, every story follows

Change the type or the colours in the editor and save. The template is part of a signed URL's cache key, so each story's card is redrawn on its next fetch. No republishing, no backfill. Open this one in the editor.

POST /v1/screenshots · selector

Pull quotes and charts, from the page

Screenshot one element of a published article by CSS selector: a pull quote, a data table, an embedded chart. Hide the cookie banner with hide. Try a screenshot.

POST /v1/charts

Charts from the story's numbers

Send the series and get a bar, line, area, pie or donut chart, as SVG for the article or PNG for social. Or put a chart layer in the card itself. Make a chart.

POST /v1/videos

A version that moves

Give the card's layers an entrance and render the same template as an MP4, WebM or GIF of up to 30 seconds for social feeds, with a soundtrack under the MP4 or WebM if you give it one. Animate a card.

signed URLs in email

Newsletter headers

The same signed URL works in an email template: a header for every issue, rendered when the first reader opens it. Ask for .png or .jpg, which every mail client shows.

mcp.imageapis.com

From the newsroom's assistant

Connect the MCP server to Claude, Cursor or your own agent with the same key, and it can make the card, the chart and the clip from a draft. Set it up.

What it costs

One render per story, not per share.

A signed URL renders on its first fetch and is served from the cache after that, so a story shared ten thousand times costs one image. The cache keeps a render for a week; a story fetched again after that renders again, which is one more image.

Stories a dayImages a month, roughlyPlan
4120Free, $0 (150 included)
401,200Starter, $9 (2,000 included)
3009,000Growth, $29 (10,000 included)
1,20036,000Scale, $79 (40,000 included)

Counted as one render per new story. Older stories fetched again after their week in the cache, and headlines edited after publishing, add one each. Past a paid plan's images, renders cost $2 to $4 per 1,000; the free plan stops at 150. All plans.

Guides

Read further.

FAQ

Questions publishers ask.

Does this replace the featured image on the article?

No. The card goes in the og:image and twitter:image tags that social networks and chat apps read when someone shares the link. The page keeps its own featured image, and the card can use it as the lead photo.

What happens when a headline changes after publishing?

The headline is part of the URL, so an edited headline makes a new URL and a new card on its first fetch. Social networks keep the image they already scraped until they look again; Facebook's Sharing Debugger and LinkedIn's Post Inspector make them look now.

What about square, story and Pinterest sizes?

A signed URL draws its template at the template's own size, so a 1080×1080 square or a 1080×1920 story is a second template that takes the same variables, with its own signed URL. The code above stays the same apart from the template id.

Our photos are behind a login.

An image layer needs a public URL. Upload the photo first with POST /v1/uploads: it is copied to img.imageapis.com/u/… and kept until you delete it. Uploads are free.

How long do the images last?

A signed URL works for as long as its base exists: when a render ages out of the cache, the next fetch makes it again. A file from POST /v1/images or a collection is kept 30 days on the free plan and a year on paid plans. So when the card should last as long as the story, store the signed URL in the CMS, not the file's URL.

Can we use our own fonts?

Any Google Fonts family loads by name in a layer template. For a licensed face, save the card as an HTML template (engine: "html") and load the font with @font-face from your own server; the render waits for it.

Start from the template above.

Copy the news article starter into your account, lock a signed base to it, and paste the code for your stack. The first 150 cards each month are free.

Get a free keyOpen it in the editorSee the template