API Documentation
v1Complete reference for the OG Image API — generate open graph images with a single API call.
Overview
OG Image API lets you generate Open Graph images programmatically. Send a POST request with your content, and receive a 1200×630 PNG image optimized for social sharing. Images are rendered on Cloudflare's edge network and cached globally for fast delivery.
Base URL
https://api.ogimage.dev/v1Authentication
All API requests (except /v1/auth/register and /v1/health) require a Bearer token in the Authorization header.
Authorization: Bearer og_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6Keep your API key safe
Endpoints
All endpoints respond with JSON for errors and metadata. Image generation endpoints return PNG binary on success.
/v1/auth/registerNo auth requiredRegister with an email address and receive an API key instantly. No password required. The API key is shown only once — save it immediately.
Request Body
{
"email": "you@example.com"
}Response 200
{
"data": {
"api_key": "og_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"email": "you@example.com",
"plan": "free",
"created_at": "2026-02-24T12:00:00Z"
},
"error": null,
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-24T12:00:00Z"
}
}Email already registered?
409 error with code EMAIL_ALREADY_REGISTERED. Check your inbox for the original key./v1/generateGenerate an OG image from a JSON request body. Returns a PNG binary on success.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| title | string | Required | — | OG image title (1–100 chars, no HTML tags) |
| subtitle | string | Optional | "" | Subtitle text (0–150 chars) |
| template | string | Optional | "blog" | Template ID: blog, product, social, minimal, dark |
| bg_color | string | Optional | "#1a1a1a" | Background color (HEX format) |
| text_color | string | Optional | "#ffffff" | Text color (HEX format) |
| accent_color | string | Optional | "#f97316" | Accent color (HEX format) |
| logo_url | string | Optional | null | Logo image URL (HTTPS only, max 2048 chars) |
| logo_position | string | Optional | "top-left" | Logo position: top-left, top-right, top-center, bottom-left, bottom-right |
| width | integer | Optional | 1200 | Image width in pixels (600–2400) |
| height | integer | Optional | 630 | Image height in pixels (315–1260) |
Request Examples
curl -X POST https://api.ogimage.dev/v1/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "My Blog Post",
"subtitle": "A great article",
"template": "blog",
"accent_color": "#f97316"
}' \
--output og-image.pngResponse Headers (200 OK)
# Success: PNG binary returned
Content-Type: image/png
Content-Length: 45231
Cache-Control: public, max-age=31536000, immutable
X-Cache: MISS
X-Image-Hash: sha256_abc123...
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1708790400/v1/generateGenerate an OG image using query parameters. Designed for use directly in og:image meta tags — no server-side code required.
URL Example
https://api.ogimage.dev/v1/generate?key=YOUR_API_KEY&title=My+Blog+Post&template=blogAPI key in URL
key query parameter. This is intentional for og:image tag usage. Same parameters as POST apply.HTML meta tag usage
<meta property="og:image"
content="https://api.ogimage.dev/v1/generate?key=YOUR_API_KEY&title=My+Blog+Post&template=blog" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />/v1/templatesList all available templates with their supported parameters and preview URLs.
Response 200
{
"data": {
"templates": [
{
"id": "blog",
"name": "Blog Post",
"description": "Clean layout for blog articles",
"supported_params": ["title", "subtitle", "bg_color", "text_color", "accent_color", "logo_url"],
"preview_url": "https://api.ogimage.dev/v1/generate?template=blog&title=Preview&key=demo"
},
{
"id": "product",
"name": "Product",
"description": "Center-aligned with logo emphasis",
"supported_params": ["title", "subtitle", "bg_color", "text_color", "accent_color", "logo_url", "logo_position"],
"preview_url": "https://api.ogimage.dev/v1/generate?template=product&title=Preview&key=demo"
},
{
"id": "social",
"name": "Social",
"description": "Optimized for social sharing with large text",
"supported_params": ["title", "subtitle", "bg_color", "text_color", "accent_color"],
"preview_url": "https://api.ogimage.dev/v1/generate?template=social&title=Preview&key=demo"
},
{
"id": "minimal",
"name": "Minimal",
"description": "Clean minimal design with wide margins",
"supported_params": ["title", "subtitle", "text_color", "bg_color"],
"preview_url": "https://api.ogimage.dev/v1/generate?template=minimal&title=Preview&key=demo"
},
{
"id": "dark",
"name": "Dark Pro",
"description": "Professional dark theme with accent bar",
"supported_params": ["title", "subtitle", "accent_color", "logo_url"],
"preview_url": "https://api.ogimage.dev/v1/generate?template=dark&title=Preview&key=demo"
}
]
},
"error": null,
"meta": { "request_id": "req_abc123", "timestamp": "2026-02-24T12:00:00Z" }
}/v1/usageRetrieve usage statistics for the current API key — images generated, cache hits, and rate limit status.
Response 200
{
"data": {
"plan": "free",
"period": {
"start": "2026-02-01T00:00:00Z",
"end": "2026-02-28T23:59:59Z"
},
"usage": {
"generated": 142,
"limit": 1000,
"cache_hits": 534,
"cache_hit_rate": 0.79
},
"rate_limit": {
"requests_per_minute": 10,
"current_minute_usage": 3
}
},
"error": null,
"meta": { "request_id": "req_abc123", "timestamp": "2026-02-24T12:00:00Z" }
}/v1/healthNo auth requiredCheck service availability. No authentication required.
Response 200
{
"data": {
"status": "ok",
"version": "1.0.0"
},
"error": null,
"meta": { "request_id": "req_abc123", "timestamp": "2026-02-24T12:00:00Z" }
}Error Codes
All error responses follow a consistent JSON structure. Check the error.code field to handle specific cases.
Error response structure
{
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key.",
"details": null
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-24T12:00:00Z"
}
}| Code | HTTP Status | Description |
|---|---|---|
| UNAUTHORIZED | 401 | API key missing or invalid |
| FORBIDDEN | 403 | API key inactive or insufficient permissions |
| INVALID_PARAMS | 400 | Parameter validation failed |
| RATE_LIMIT_EXCEEDED | 429 | Per-minute request limit exceeded — check Retry-After header |
| DAILY_LIMIT_EXCEEDED | 429 | Monthly image generation limit exceeded |
| TEMPLATE_NOT_FOUND | 404 | Template ID does not exist |
| INTERNAL_ERROR | 500 | Server internal error |
Rate limit headers
X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When you hit a rate limit, check the Retry-After header for the reset time.Examples
Blog post OG image
Generate a blog-style OG image with a title, subtitle, and custom accent color.
curl -X POST https://api.ogimage.dev/v1/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "How to Build a Next.js App in 2026",
"subtitle": "A complete guide from setup to deployment",
"template": "blog",
"accent_color": "#6366f1"
}' \
--output blog-og.pngNext.js dynamic OG images
Use generateMetadata in Next.js App Router to set unique OG images per page. The API key is kept server-side.
// app/blog/[slug]/page.tsx
import type { Metadata } from "next";
interface Props {
params: { slug: string };
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await getPost(params.slug);
const ogImageUrl = new URL("https://api.ogimage.dev/v1/generate");
ogImageUrl.searchParams.set("key", process.env.OG_IMAGE_API_KEY!);
ogImageUrl.searchParams.set("title", post.title);
ogImageUrl.searchParams.set("subtitle", post.excerpt);
ogImageUrl.searchParams.set("template", "blog");
return {
title: post.title,
openGraph: {
images: [
{
url: ogImageUrl.toString(),
width: 1200,
height: 630,
alt: post.title,
},
],
},
};
}