OG Image API

API Documentation

v1

Complete 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

text
https://api.ogimage.dev/v1

Authentication

All API requests (except /v1/auth/register and /v1/health) require a Bearer token in the Authorization header.

http
Authorization: Bearer og_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

Endpoints

All endpoints respond with JSON for errors and metadata. Image generation endpoints return PNG binary on success.

POST/v1/auth/registerNo auth required

Register 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

json
{
  "email": "you@example.com"
}

Response 200

json
{
  "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"
  }
}
POST/v1/generate

Generate an OG image from a JSON request body. Returns a PNG binary on success.

Parameters

ParameterTypeRequiredDefaultDescription
titlestringRequiredOG image title (1–100 chars, no HTML tags)
subtitlestringOptional""Subtitle text (0–150 chars)
templatestringOptional"blog"Template ID: blog, product, social, minimal, dark
bg_colorstringOptional"#1a1a1a"Background color (HEX format)
text_colorstringOptional"#ffffff"Text color (HEX format)
accent_colorstringOptional"#f97316"Accent color (HEX format)
logo_urlstringOptionalnullLogo image URL (HTTPS only, max 2048 chars)
logo_positionstringOptional"top-left"Logo position: top-left, top-right, top-center, bottom-left, bottom-right
widthintegerOptional1200Image width in pixels (600–2400)
heightintegerOptional630Image height in pixels (315–1260)

Request Examples

bash
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.png

Response Headers (200 OK)

http
# 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
GET/v1/generate

Generate an OG image using query parameters. Designed for use directly in og:image meta tags — no server-side code required.

URL Example

text
https://api.ogimage.dev/v1/generate?key=YOUR_API_KEY&title=My+Blog+Post&template=blog

HTML meta tag usage

html
<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" />
GET/v1/templates

List all available templates with their supported parameters and preview URLs.

Response 200

json
{
  "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" }
}
GET/v1/usage

Retrieve usage statistics for the current API key — images generated, cache hits, and rate limit status.

Response 200

json
{
  "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" }
}
GET/v1/healthNo auth required

Check service availability. No authentication required.

Response 200

json
{
  "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

json
{
  "data": null,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key.",
    "details": null
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-02-24T12:00:00Z"
  }
}
CodeHTTP StatusDescription
UNAUTHORIZED401API key missing or invalid
FORBIDDEN403API key inactive or insufficient permissions
INVALID_PARAMS400Parameter validation failed
RATE_LIMIT_EXCEEDED429Per-minute request limit exceeded — check Retry-After header
DAILY_LIMIT_EXCEEDED429Monthly image generation limit exceeded
TEMPLATE_NOT_FOUND404Template ID does not exist
INTERNAL_ERROR500Server internal error

Examples

Blog post OG image

Generate a blog-style OG image with a title, subtitle, and custom accent color.

bash
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.png

Next.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.

typescript
// 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,
        },
      ],
    },
  };
}