API Documentation

Everything you need to generate images with SnapOG

NewMCP Server

Give any AI assistant direct access to SnapOG with a single tool call. Setup for Claude, Cursor, VS Code, and more.

AI-Friendly Docs

Point your AI to https://api.snapog.dev/v1/docs — it returns this entire API as markdown in one fetch.

Quick Start

Generate your first image in 3 steps:

  1. 1.Sign up and get your API key (starts with sk_live_)
  2. 2.Choose a template from the template list
  3. 3.Make a POST request with your parameters
curl -X POST https://api.snapog.dev/v1/generate \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template":"blog-post","params":{"title":"Hello World","author":"SnapOG"}}' \
  -o output.png

Authentication

All image generation endpoints require an API key. Include it in the Authorization header:

Authorization: Bearer sk_live_YOUR_API_KEY

Get your key from the signup page or dashboard.

Rate Limiting

Rate limits are based on your plan tier. Every response includes these headers:

X-RateLimit-LimitnumberYour monthly image limit
X-RateLimit-UsednumberImages generated this month
X-RateLimit-RemainingnumberImages remaining this month
PlanMonthly Limit
Free100
Starter1,000
Pro10,000
Business100,000

Endpoints

POST/v1/generateAUTH

Generate an image from a template. Returns image binary (PNG, SVG, or PDF).

Request Body

templatestringrequiredTemplate ID (e.g. blog-post, product, stats)
paramsobjectrequiredTemplate-specific parameters (title, author, etc.)
options.widthnumberImage width in pixels (default: 1200)
options.heightnumberImage height in pixels (default: 630)
options.formatstring"png", "svg", or "pdf" (default: "png")
fontFamilystringAny Google Font family name (e.g. Poppins, Raleway)
webhook_urlstringURL to POST when generation completes

Example

curl -X POST https://api.snapog.dev/v1/generate \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "blog-post",
    "params": {
      "title": "How to Build a Lightning-Fast API",
      "author": "Jane Doe",
      "date": "Feb 11, 2026",
      "tags": ["API", "Tutorial"]
    }
  }' \
  -o output.png
Response: 200 OK with Content-Type: image/png
GET/v1/og/:templateIdAUTH

Generate an image via URL parameters. Perfect for HTML meta tags — use as the og:image URL.

Query Parameters

titlestringAny template parameter can be passed as a query param
widthnumberImage width (default: 1200)
heightnumberImage height (default: 630)
formatstring"png", "svg", or "pdf" (default: "png")
fontFamilystringAny Google Font family name

Example

<!-- Use directly in HTML meta tags -->
<meta property="og:image" content="https://api.snapog.dev/v1/og/blog-post?title=My+Post&author=Jane+Doe&Authorization=Bearer+sk_live_YOUR_KEY" />

<!-- Or fetch via cURL -->
curl "https://api.snapog.dev/v1/og/blog-post?title=Hello+World&author=SnapOG" \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -o output.png
GET/v1/templates

List all available templates with their IDs, names, descriptions, and parameter schemas.

Response

{
  "templates": [
    {
      "id": "blog-post",
      "name": "Blog Post",
      "description": "Clean, modern blog post social card",
      "defaultParams": { "title": "How to Build a Lightning-Fast API", ... },
      "paramSchema": {
        "title": { "type": "string", "label": "Title", "required": true },
        "author": { "type": "string", "label": "Author Name" },
        "tags": { "type": "string[]", "label": "Tags" },
        ...
      }
    },
    ...
  ]
}
GET/v1/templates/:id

Get a single template's definition including its parameter schema and defaults.

Example

curl https://api.snapog.dev/v1/templates/blog-post
POST/v1/signAUTH

Create a signed URL for use in meta tags. The signed URL renders without authentication — perfect for og:image and Farcaster fc:miniapp tags.

Request Body

templatestringrequiredTemplate ID
paramsobjectrequiredTemplate parameters
options.widthnumberImage width (default: 1200)
options.heightnumberImage height (default: 630)
expiresInnumberSeconds until expiry (default: 2592000 = 30 days)

Example

curl -X POST https://api.snapog.dev/v1/sign \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "blog-post",
    "params": { "title": "Hello World" },
    "expiresIn": 2592000
  }'

# Response:
# {
#   "url": "https://api.snapog.dev/v1/i/<token>",
#   "token": "<token>",
#   "expiresAt": "2026-03-13T..."
# }

# Use the signed URL in meta tags (no auth needed):
# <meta property="og:image" content="https://api.snapog.dev/v1/i/<token>" />
POST/v1/batchAUTH

Generate one template at multiple sizes in a single request. Returns base64-encoded images for each size.

Request Body

templatestringrequiredTemplate ID
paramsobjectrequiredTemplate parameters
sizesarrayrequiredPreset names or {name, width, height} objects. Presets: og, twitter, farcaster, instagram-square, instagram-story, linkedin, facebook, pinterest
formatstring"png", "svg", or "pdf" (default: "png")
webhook_urlstringURL to POST when batch completes

Example

curl -X POST https://api.snapog.dev/v1/batch \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "brand-card",
    "params": { "title": "My App" },
    "sizes": ["og", "twitter", "farcaster", "instagram-square"]
  }'
GET/v1/sizes

List all available size presets with their dimensions.

Example

curl https://api.snapog.dev/v1/sizes

Farcaster Mini Apps

Guide

Generate dynamic share images for Farcaster mini apps. Images must be PNG, 3:2 aspect ratio (1200x800). Use signed URLs so your API key stays server-side.

1. Sign the image URL on your server

const { url } = await fetch("https://api.snapog.dev/v1/sign", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template: "brand-card",
    params: { title: "My Score: 420", description: "Can you beat me?" },
    options: { width: 1200, height: 800 }, // 3:2 required by Farcaster
    expiresIn: 2592000,
  }),
}).then(r => r.json());

2. Return it in your mini app's meta tags

<meta name="fc:miniapp" content='{
  "version": "1",
  "imageUrl": "https://api.snapog.dev/v1/i/<signed-token>",
  "button": {
    "title": "Play Now",
    "action": { "type": "launch_miniapp" }
  }
}' />

3. Or batch-generate for multiple platforms

curl -X POST https://api.snapog.dev/v1/batch \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "brand-card",
    "params": { "title": "My App" },
    "sizes": ["farcaster", "og", "twitter"]
  }'

The farcaster preset generates at 1200x800 (3:2).

Additional Features

PDF Output

Add "format": "pdf" to any generation request to get a PDF instead of PNG. Supported formats: png, svg, pdf.

curl -X POST https://api.snapog.dev/v1/generate \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template":"brand-card","params":{"title":"Hello"},"options":{"format":"pdf"}}' \
  -o card.pdf

Dynamic Google Fonts

Use any Google Font by adding fontFamily to your request. Fonts are fetched on-demand and cached.

curl -X POST https://api.snapog.dev/v1/generate \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template":"brand-card","params":{"title":"Custom Font"},"fontFamily":"Poppins"}'

# Also works with GET:
# /v1/og/brand-card?title=Hello&fontFamily=Poppins

Webhooks

Add webhook_url to get notified when generation completes. Works with both /v1/generate and /v1/batch.

curl -X POST https://api.snapog.dev/v1/generate \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "brand-card",
    "params": { "title": "Hello" },
    "webhook_url": "https://your-server.com/hook"
  }'

# Webhook payload:
# {
#   "event": "generate.completed",
#   "template": "brand-card",
#   "format": "png",
#   "width": 1200,
#   "height": 630,
#   "generationTimeMs": 342
# }

Code Examples

Node.js

import fs from "fs";

const response = await fetch("https://api.snapog.dev/v1/generate", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template: "blog-post",
    params: {
      title: "My Blog Post",
      author: "Jane Doe",
      tags: ["API", "Tutorial"],
    },
  }),
});

const buffer = await response.arrayBuffer();
fs.writeFileSync("og-image.png", Buffer.from(buffer));
console.log("Image saved to og-image.png");

Python

import requests

response = requests.post(
    "https://api.snapog.dev/v1/generate",
    headers={"Authorization": "Bearer sk_live_YOUR_KEY"},
    json={
        "template": "blog-post",
        "params": {
            "title": "My Blog Post",
            "author": "Jane Doe",
            "tags": ["API", "Tutorial"],
        },
    },
)

with open("og-image.png", "wb") as f:
    f.write(response.content)
print("Image saved to og-image.png")

Next.js (Dynamic OG Images)

// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug);

  const ogUrl = new URL("https://api.snapog.dev/v1/og/blog-post");
  ogUrl.searchParams.set("title", post.title);
  ogUrl.searchParams.set("author", post.author);

  return {
    openGraph: {
      images: [{ url: ogUrl.toString(), width: 1200, height: 630 }],
    },
  };
}

Error Codes

StatusErrorDescription
400bad_requestInvalid JSON or missing required fields
401unauthorizedMissing or invalid API key
404not_foundTemplate not found
429rate_limit_exceededMonthly image limit reached