ThumbAPI logoThumbAPI

Code Examples

Copy-paste examples for common use cases. Every example works with the free tier.

YouTube Thumbnail (Faceless)

cURL

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "10 Tips to Grow Your YouTube Channel",
    "format": "youtube",
    "category": "education-tutorial"
  }'

JavaScript

const res = await fetch("https://api.thumbapi.dev/v1/generate", {
  method: "POST",
  headers: {
    "x-api-key": process.env.THUMBAPI_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "10 Tips to Grow Your YouTube Channel",
    format: "youtube",
    category: "education-tutorial",
  }),
});

const { image, format, outputFormat } = await res.json();

Python

import requests, os

res = requests.post(
    "https://api.thumbapi.dev/v1/generate",
    headers={"x-api-key": os.environ['THUMBAPI_KEY']},
    json={
        "title": "10 Tips to Grow Your YouTube Channel",
        "format": "youtube",
        "category": "education-tutorial",
    },
)
data = res.json()

OG Image (Blog Post)

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Understanding Vector Databases: A Practical Guide",
    "format": "blogpost"
  }'

Returns a 1200x630 image — the standard OG image size.

LinkedIn Post

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How We Cut Onboarding Time in Half",
    "format": "linkedin",
    "category": "business-finance"
  }'

Returns a 1200x627 image, sized for LinkedIn feed shares.

Instagram Post

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "5 Morning Habits That Changed My Life",
    "format": "instagram"
  }'

Returns a 1024x1024 square image.

With Saved Photo

const res = await fetch("https://api.thumbapi.dev/v1/generate", {
  method: "POST",
  headers: {
    "x-api-key": process.env.THUMBAPI_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "My Journey to 1M Subscribers",
    format: "youtube",
    usePhoto: true,
  }),
});

Pulls your saved Personal Photo from the dashboard — no need to upload per request.

With Inline Photo

import { readFileSync } from "fs";

const photoBase64 = readFileSync("./photo.jpg", "base64");

const res = await fetch("https://api.thumbapi.dev/v1/generate", {
  method: "POST",
  headers: {
    "x-api-key": process.env.THUMBAPI_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "My Journey to 1M Subscribers",
    format: "youtube",
    usePhoto: true,
    photoImage: `data:image/jpeg;base64,${photoBase64}`,
  }),
});

photoImage is capped at 2MB. For logos use logoImage (capped at 1MB).

Photo + Logo

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My 2026 Annual Review",
    "format": "youtube",
    "usePhoto": true,
    "useLogo": true
  }'

usePhoto and useLogo are independent — combine them for a personalized scene with a branded logo overlay.

Custom Reference Set

curl -X POST https://api.thumbapi.dev/v1/generate \
  -H "x-api-key: $THUMBAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Episode 47: The Future of AI",
    "customAssetsId": "ref_brand_v2"
  }'

format is optional when customAssetsId is provided — the reference set's stored format wins.

Save to Disk

Node.js

import { writeFileSync } from "fs";

const { image } = await res.json();
const base64 = image.replace(/^data:image\/webp;base64,/, "");
writeFileSync("thumbnail.webp", base64, "base64");

Python

import base64

b64 = data["image"].split(",")[1]
with open("thumbnail.webp", "wb") as f:
    f.write(base64.b64decode(b64))

Error Handling

const res = await fetch("https://api.thumbapi.dev/v1/generate", {
  method: "POST",
  headers: {
    "x-api-key": process.env.THUMBAPI_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(requestBody),
});

if (!res.ok) {
  const { error } = await res.json();
  if (res.status === 429) {
    // Rate limited — retry with backoff
  } else if (res.status === 401) {
    // Auth error — check API key
  } else {
    throw new Error(`ThumbAPI error ${res.status}: ${error}`);
  }
}

Next Steps