One API call. Your OG image is live.
The OG Image Generator is a Varosity skill that turns a page title and brand style into a hosted Open Graph image URL — ready to drop straight into your og:image and twitter:card meta tags. It runs synchronously: one POST, one URL back, no polling. It's batchable across a whole sitemap and uses the same Varosity API key you already have.
I built this because I kept running into the same stupid gap. You ship a site, you write good content, and then you share it somewhere and the preview is a blank gray box or some random screenshot of your nav. Every platform — LinkedIn, Slack, iMessage, X — pulls that og:image and renders it front and center. If it's missing or ugly, your link looks half-finished. First impressions and all that.
The fix should be simple. It isn't.
The actual problem with OG images
Most developers know they need them. Very few have a clean way to generate them at scale. You can set up a Puppeteer headless-browser pipeline that screenshots an HTML template, manage a server for that, keep it updated, handle timeouts. Or you can pay for one of the dedicated OG image SaaS tools and wire up another API key, another billing account, another integration. Neither feels right when you're moving fast.
What I actually wanted was: give the agent a list of page titles and a brand description, get back the URLs, paste them into the meta tags, done. No new service. No new credentials. Same key I'm already using for everything else on Varosity.
That's what this skill is.
What you actually get
You call the skill with a page title, a brand style (colors, vibe, whether you want the headline text rendered inside the image), and optionally a list of pages for batch. The skill engineers a tight image prompt, fires POST /api/v1/images, and hands you back a hosted imageUrl on Varosity's CDN plus the copy-paste meta tags:
<meta property="og:image" content="https://cdn.varosity.ai/img/og-xyz.png" /> <meta property="og:image:width" content="1200" /> <meta property="og:image:height" content="675" /> <meta name="twitter:card" content="summary_large_image" />
That's it. The URL is already hosted. You don't store anything, you don't upload anything, you don't manage a CDN. You just use the URL.
The image comes back at 16:9 — which is 1200×675. The OG spec technically wants 1200×630, so there's a ~45px height difference. Every major crawler I've tested (Facebook, LinkedIn, X, Slack, iMessage) center-crops, so it renders fine. If you need pixel-exact 1200×630 for some reason, crop 45px off the bottom. In practice, I don't bother.
Model choice matters more than anything else here
This is the part most people miss when they first try to generate OG cards with a diffusion model. Most models mangle text. You ask for a card that says "How we cut render costs 40%" and you get something that says "Haw wa cxt rendel costzz 40%". Looks terrible. Kills the whole point.
So before you build the prompt, you make one decision: does the headline text need to appear inside the image, or are you going to overlay it yourself in CSS?
If the text goes in the image — which is the default for most branded OG cards — use gemini-3-pro-image. It's the best model in the library for legible, correctly-spelled, properly-laid-out in-image text. Multilingual too, if that matters for your site. You put the exact headline in quotes in the prompt and it renders it cleanly. ideogram-v3 is a solid alternative if you want a different aesthetic or lower cost per image.
If you're doing visual-only backgrounds and overlaying text yourself (totally valid, especially if you have a design system handling the typography), use flux-1.1-pro for a richer image at lower cost. For drafts and iteration, flux-1-schnell is the cheapest option.
One more thing on models: imagen-4 and imagen-4-fast are being retired by Google on August 17, 2026. Don't start new workflows on those. Use gemini-3-pro-image instead.
How it actually runs — a real example
Here's a concrete walkthrough. Say I have a blog post titled "How we cut render costs 40%" and my brand is deep navy background, electric-cyan accent, clean modern developer aesthetic.
I tell the agent: "OG image for my blog post 'How we cut render costs 40%'. Brand: deep navy background, electric-cyan accent, clean modern. Put the title in the image."
The skill builds this prompt:
> "Social share card, 16:9. Deep navy (#0B1020) background with a subtle electric-cyan (#22D3EE) gradient glow in the top-right. Bold white headline text reading \"How we cut render costs 40%\" left-aligned with generous margins, clean modern sans-serif. Minimal, high-contrast, professional developer-blog aesthetic. No clutter."
Then it calls:
POST /api/v1/images
{ "prompt": "<engineered prompt>", "model": "gemini-3-pro-image", "aspect_ratio": "16:9" }Response comes back:
{ "imageUrl": "https://cdn.varosity.ai/img/og-rendercosts.png" }And then you get the meta tags to paste. One call. No polling. The URL is live immediately.
For a batch — say, 20 blog posts — the skill loops that same Stage 1 and Stage 2 process over each title sequentially and returns a table mapping each title to its imageUrl. Sequential matters here; I'll get to that.
Authentication and setup
You need a Varosity API key with the generate:image scope. Manage keys at varosity.ai → API Keys. The header is Authorization: Bearer vsk_... for REST calls.
For MCP — which is how most agents will use this — you connect the Varosity MCP server once (https://varosity.ai/api/mcp, Streamable HTTP) and set the key on the connection. After that, the agent just calls generate_image() with the prompt, model, and aspect_ratio. No per-call auth wrangling.
Billing is automatic. If you've connected your own provider key (BYOK), you pay zero markup. Otherwise it comes out of Varosity Credits. Failed generations don't cost anything.
Cost
One gemini-3-pro-image image runs about $0.13 on Credits. ideogram-v3 is roughly $0.05–0.08. flux-1.1-pro is cheaper than that; flux-1-schnell drafts are around $0.01. For a 20-page site, you're probably spending $1–3 total depending on which model you use. That's a one-time cost if you persist the URLs — and you should. There's no seed parameter, so re-running gives you an equivalent image but not bit-identical. If you like a card, save the imageUrl and reuse it. Don't regenerate unnecessarily.
Gotchas to know before you start
Batches hit the global rate limit at around 3 generations per window. That's why the skill runs sequentially and backs off on 429s. Don't try to parallelize the calls — you'll get throttled and have to retry anyway.
The /api/v1/images endpoint takes prompt, model, and aspect_ratio. That's the whole surface — no width/height knobs, no seed, no steps. Dimensions come from the aspect ratio. Keep the request simple.
If you want to anchor your actual logo into the card, pass a public URL or base64 data URI as referenceImageUrl and use model: "nano-banana" — that model is specifically good at preserving a supplied element while generating around it.
Busy image compositions look bad at thumbnail size. OG cards are small. Simple scenes, high contrast, generous margins. The prompt template in the skill enforces this, but if you're customizing, keep it in mind.
Installing and running the skill
The skill lives in Varosity's public skills library. To pull it into your agent runtime:
curl -s https://varosity.ai/api/v1/skills/og-image-generator > ~/.varosity/skills/og-image-generator.md
It's set to auto_update: true, so if you're using MCP, run refresh_skills at the start of your session and you'll always have the latest version. The skill is maintained by Varosity AI — I update it when models change or new options come in.
Once it's loaded, just tell your agent what you need. "Make OG images for my site. Brand: [colors / vibe]. Pages: [list of titles or a sitemap]. Render the title text in the image? Yes." The skill takes it from there.
For developers who want to call it directly from their own tooling rather than through an agent, the REST endpoint is POST https://varosity.ai/api/v1/images with your JSON body. The skill reference doc has the full request shape.
It's one of those tools that I wish had existed before I built it. OG images are table stakes for anything you ship on the web. They shouldn't require a separate service, a separate key, or a headless browser farm. Now they don't.