Meme API Documentation
Generate memes programmatically. 700+ templates, AI auto-captioning, simple REST API. Works with OpenClaw, LangChain, custom bots, and any HTTP client.
Quickstart — one API call
The simplest way to use the API. One call generates a meme and posts it to X:
Generate meme + post to X
curl -X POST https://www.memelair.com/api/v1/memes/generate-and-post \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "When the code works on the first try"}'
# → {"success":true,"tweet_url":"https://x.com/i/status/..."}Or just get the meme image without posting:
Generate meme image only
curl -X POST https://www.memelair.com/api/v1/memes/generate \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "Monday morning standup"}'
# → {"image_base64":"...","template_name":"This Is Fine","texts":[...]}That's it. AI picks the template, writes the captions, renders the image. Need more control? Keep reading for individual endpoints.
Authentication
All endpoints require a Bearer token. Generate an API key from your dashboard → API Keys.
Authorization: Bearer xp_your_api_key_here
Keys start with xp_. They're hashed on our end — we never store the raw key. Revoke anytime from the dashboard.
Base URL
https://www.memelair.com/api/v1
Generate meme (one call)
/memes/generate— AI picks template, writes captions, renders imageSend text, get a finished meme image. No need to list templates or call multiple endpoints.
Request
curl -X POST https://www.memelair.com/api/v1/memes/generate \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "When you deploy on a Friday"}'Response
{
"image_base64": "iVBORw0KGgoAAAANS...",
"url": "data:image/png;base64,...",
"content_type": "image/png",
"template_id": "fine",
"template_name": "This Is Fine",
"texts": ["The servers are on fire", "This is fine"]
}Generate meme + post to X (one call)
/memes/generate-and-post— AI generates meme and posts it to X — all in one requestThe ultimate one-liner. Your agent sends text, we generate the meme, attach it, and post to X. Returns the tweet URL.
Request
curl -X POST https://www.memelair.com/api/v1/memes/generate-and-post \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "When the intern pushes to main"}'Response
{
"success": true,
"tweet_id": "1895123456789012345",
"tweet_url": "https://x.com/i/status/1895123456789012345",
"template_id": "fine",
"template_name": "This Is Fine",
"meme_texts": ["The production database", "This is fine"]
}Text must be ≤280 characters. Requires an X account linked at the Meme Lair dashboard.
OpenAPI spec
Machine-readable spec for auto-discovery in agent frameworks (OpenClaw, LangChain, AutoGPT):
GET https://www.memelair.com/api/v1/openapi.json
Returns OpenAPI 3.1 JSON. Point your agent framework at this URL and it will discover all endpoints automatically.
Advanced endpoints — for agents that need more control
List templates
/memes— List all meme templatesReturns all 700+ templates with IDs, names, box counts, and preview URLs.
Request
curl https://www.memelair.com/api/v1/memes \ -H "Authorization: Bearer xp_your_key"
Response
{
"memes": [
{
"id": "drake",
"name": "Drake Hotline Bling",
"box_count": 2,
"preview_url": "https://www.memelair.com/api/v1/memes/drake/image"
},
{
"id": "distracted",
"name": "Distracted Boyfriend",
"box_count": 3,
"preview_url": "https://www.memelair.com/api/v1/memes/distracted/image"
}
],
"total": 210
}Template image
/memes/{'{id}'}/image— Get template preview imageReturns the raw image file. Add ?thumb=1 for a 300x300 JPEG thumbnail.
Request
# Full size curl https://www.memelair.com/api/v1/memes/drake/image \ -H "Authorization: Bearer xp_your_key" -o drake.png # Thumbnail curl "https://www.memelair.com/api/v1/memes/drake/image?thumb=1" \ -H "Authorization: Bearer xp_your_key" -o drake-thumb.jpg
Create a captioned meme
/memes/caption— Overlay text on a meme templateSend a template_id and an array of texts matching the template's box_count.
Request
curl -X POST https://www.memelair.com/api/v1/memes/caption \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{
"template_id": "drake",
"texts": ["Running a meme server", "One API call to Meme Lair"]
}'Response (JSON, default)
{
"url": "data:image/png;base64,...",
"image_base64": "iVBORw0KGgo...",
"content_type": "image/png"
}Output formats:
image_base64 — raw base64 string, decode to get PNG bytes
url — data URI, embed directly in HTML
Set "format": "raw" in body or Accept: image/png header → returns raw PNG binary
Mork auto-generate meme
/memes/auto— AI picks template + writes captionsSend text, and Mork picks the funniest template and writes the captions. Then pass the result to /memes/caption to render.
Request
curl -X POST https://www.memelair.com/api/v1/memes/auto \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "Just mass-deployed to prod on a Friday"}'Response
{
"template_id": "fine",
"template_name": "This Is Fine",
"texts": ["The servers are on fire", "This is fine"]
}This endpoint only returns the template selection + text. Chain it with POST /memes/caption to get the image.
Post to X
/post— Post a tweet (with optional image) to XPost text and an optional image to X on behalf of your connected account. Pass the meme's url (data URI) from /memes/caption as the image field.
Request
curl -X POST https://www.memelair.com/api/v1/post \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{
"text": "When the code works on first try 😂",
"image": "data:image/png;base64,iVBORw0KGgo..."
}'Response
{
"success": true,
"tweet_id": "1895123456789",
"tweet_url": "https://x.com/i/status/1895123456789"
}Notes:
text — required, max 280 characters
image — optional, data URL or HTTP image URL
User must have connected their X account at the Meme Lair dashboard first
Image uploads require the "Enable image uploads" one-time setup in the dashboard
Full example
Generate a meme and post it to X in 3 API calls:
curl — AI meme → post to X (3 calls)
# Step 1: AI picks template + writes text
RESULT=$(curl -s -X POST https://www.memelair.com/api/v1/memes/auto \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "Just shipped a feature nobody asked for"}')
TEMPLATE=$(echo $RESULT | jq -r .template_id)
TEXTS=$(echo $RESULT | jq -c .texts)
# Step 2: Render the meme image
MEME=$(curl -s -X POST https://www.memelair.com/api/v1/memes/caption \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d "{\"template_id\":\"$TEMPLATE\",\"texts\":$TEXTS}")
IMAGE_URL=$(echo $MEME | jq -r .url)
# Step 3: Post to X with the meme
curl -X POST https://www.memelair.com/api/v1/post \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d "{\"text\":\"Just shipped a feature nobody asked for 😂\",\"image\":\"$IMAGE_URL\"}"
# Response: {"success":true,"tweet_id":"...","tweet_url":"https://x.com/i/status/..."}Agent integration
Drop-in examples for popular agent frameworks. Your agent writes the content, our API generates the meme.
Python — full flow: generate meme + post to X
import requests
API_KEY = "xp_your_key"
BASE = "https://www.memelair.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def generate_and_post_meme(post_text: str):
"""Generate a meme from text and post it to X — 3 API calls."""
# Step 1: AI picks template + writes captions
auto = requests.post(
f"{BASE}/memes/auto",
headers=HEADERS,
json={"text": post_text}
).json()
print(f"Template: {auto['template_name']}")
print(f"Captions: {auto['texts']}")
# Step 2: Render the meme image
meme = requests.post(
f"{BASE}/memes/caption",
headers=HEADERS,
json={
"template_id": auto["template_id"],
"texts": auto["texts"]
}
).json()
# Step 3: Post to X with the meme image
result = requests.post(
f"{BASE}/post",
headers=HEADERS,
json={
"text": post_text,
"image": meme["url"] # pass the data URL directly
}
).json()
print(f"Posted! {result['tweet_url']}")
return result
# One function call does everything:
generate_and_post_meme("When the code works on first try 😂")Python — OpenClaw / LangChain tool definition
from langchain.tools import tool
@tool
def post_meme(text: str) -> str:
"""Generate an AI meme and post it to X with the given text."""
import requests
KEY = "xp_your_key"
BASE = "https://www.memelair.com/api/v1"
H = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
auto = requests.post(f"{BASE}/memes/auto", headers=H, json={"text": text}).json()
meme = requests.post(f"{BASE}/memes/caption", headers=H, json={
"template_id": auto["template_id"], "texts": auto["texts"]
}).json()
result = requests.post(f"{BASE}/post", headers=H, json={
"text": text, "image": meme["url"]
}).json()
return f"Posted: {result.get('tweet_url', 'unknown')}"
# Your agent can now call post_meme("Just mass-deployed on a Friday")Node.js / TypeScript — full flow
const API_KEY = process.env.MEMELAIR_API_KEY!;
const BASE = "https://www.memelair.com/api/v1";
const headers = {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
async function generateAndPostMeme(postText: string) {
// Step 1: AI picks the best meme
const auto = await fetch(`${BASE}/memes/auto`, {
method: "POST", headers,
body: JSON.stringify({ text: postText }),
}).then((r) => r.json());
// Step 2: Render it
const meme = await fetch(`${BASE}/memes/caption`, {
method: "POST", headers,
body: JSON.stringify({
template_id: auto.template_id,
texts: auto.texts,
}),
}).then((r) => r.json());
// Step 3: Post to X with the meme
const result = await fetch(`${BASE}/post`, {
method: "POST", headers,
body: JSON.stringify({
text: postText,
image: meme.url,
}),
}).then((r) => r.json());
console.log("Posted!", result.tweet_url);
return result;
}
// Usage:
await generateAndPostMeme("Nobody asked for this feature but here it is 😅");Post with your own service (just text, no meme)
# You can also post plain text — no meme required
curl -X POST https://www.memelair.com/api/v1/post \
-H "Authorization: Bearer xp_your_key" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from my agent bot 🤖"}'
# Response: {"success":true,"tweet_id":"...","tweet_url":"..."}Pick a specific template (skip AI)
# List templates first
templates = requests.get(
f"{BASE}/memes",
headers=HEADERS
).json()["memes"]
# Find one by name
drake = next(t for t in templates if t["id"] == "drake")
# Generate with custom text
meme = requests.post(
f"{BASE}/memes/caption",
headers=HEADERS,
json={
"template_id": "drake",
"texts": ["Writing unit tests", "Shipping to prod and praying"]
}
).json()
image_bytes = base64.b64decode(meme["image_base64"])Pricing & limits
API usage counts against your plan. Same account, same limits.
| Plan | Price | Memes/month | AI auto-meme | Watermark |
|---|---|---|---|---|
| Free | $0 | 25 | 25 | Yes |
| Lite | $9/mo | 200 | 200 | No |
| Unlimited | $29/mo | Unlimited | Unlimited | No |
When you hit the limit, the API returns 429 with code: "limit_reached".
Error codes
| HTTP | Meaning | Fix |
|---|---|---|
| 401 | Missing or invalid API key | Check your Authorization header |
| 400 | Bad request | Check required fields (template_id, texts) |
| 404 | Template not found | Use GET /memes to list valid IDs |
| 429 | Monthly limit reached | Upgrade your plan or wait for next period |
| 502 | AI service error | Retry after a moment (auto-meme only) |
Error response format
{
"error": "Monthly limit reached (25/25). Upgrade for more.",
"code": "limit_reached"
}