Generate Caption — POST /v1/ai/generate-caption
Generates 1-5 caption variants for a social media post from a topic + tone + platform. Companion to /v1/ai/generate-image — together they let an MCP agent compose an entire post in two API calls.
Captions respect per-platform character limits and follow each platform's hashtag conventions automatically:
| Platform | Hard limit | Hashtag style |
|---|---|---|
| X / Twitter | 280 chars | 1-3 hashtags at end |
| Bluesky | 300 chars | 1-3 hashtags |
| Threads | 500 chars | 1-3 hashtags |
| 500 chars | No hashtags (uses natural-language search) | |
| YouTube | 1,000 chars | 1-3 hashtags |
| 2,200 chars | 5-10 hashtags at end | |
| TikTok | 2,200 chars | 5-10 hashtags |
| 3,000 chars | 2-3 hashtags (LinkedIn discourages heavy use) | |
| 5,000 chars | 1-3 hashtags |
Request
curl -X POST https://app.posteverywhere.ai/api/v1/ai/generate-caption \
-H "Authorization: Bearer $POSTEVERYWHERE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"topic": "Black Friday sale on running shoes — 30% off through Monday",
"platform": "instagram",
"tone": "enthusiastic",
"length": "medium",
"count": 3
}'
Requires the ai scope. Costs 1 AI credit per returned caption.
Parameters
| Field | Type | Default | Description |
|---|---|---|---|
topic | string (required) | — | What the post should be about (max 1,000 chars). |
platform | string | none | If set, applies platform-specific length + style rules. Omit for generic. |
tone | string | professional | professional | casual | witty | enthusiastic | urgent | inspirational |
length | string | medium | short (~80 chars) | medium (~180 chars) | long (~400 chars) |
include_hashtags | boolean | true | Set false to omit hashtags entirely. |
include_emojis | boolean | true | Set false for emoji-free output. |
count | integer | 1 | Number of variants to return (1-5). |
Response
{
"captions": [
"🏃 30% OFF until Monday! Time to lace up. Our best running shoes — half a closet, all the comfort. Free shipping over $50. Link in bio.\n\n#blackfriday #runningshoes #sale #fitness #running",
"BLACK FRIDAY MADNESS 🛍️ ...",
"..."
],
"platform": "instagram",
"tone": "enthusiastic",
"length": "medium",
"count_requested": 3,
"count_returned": 3,
"credits_used": 3,
"credits_remaining": 197
}
Errors
| Code | HTTP | When |
|---|---|---|
validation_error | 400 | Missing topic or topic > 1000 chars. |
insufficient_credits | 402 | Not enough AI credits for the requested count. Response includes needed and available. |
ai_no_content | 502 | OpenAI returned no content. Rephrase the topic and retry. |
Typical workflow with generate-image
const me = await client.me.get();
if (me.quota.ai_credits.limit - me.quota.ai_credits.used < 6) {
showUpgrade();
return;
}
// 1 image (~5 credits) + 1 caption (1 credit) = 6 credits.
const [image, captions] = await Promise.all([
client.ai.generateImage({ prompt: 'Vibrant running shoes on a track', model: 'gemini-3-pro' }),
client.ai.generateCaption({
topic: 'Black Friday — 30% off running shoes',
platform: 'instagram',
tone: 'enthusiastic',
count: 1,
}),
]);
await client.posts.create({
content: captions.captions[0],
account_ids: [igAccountId],
media_ids: [image.media_id],
scheduled_for: '2026-11-29T10:00:00Z',
});
Notes
- Tone influences word choice.
professionalproduces measured copy with full sentences.wittyintroduces wordplay.enthusiasticuses exclamation marks and energy words. Match tone to brand voice. - Multi-platform posting. If you're posting to multiple platforms with different character limits, generate ONE caption sized for the shortest (X/Bluesky). Or call this endpoint per-platform.
- Hashtag placement. Hashtags always land at the end of the caption (Instagram convention), unless you set
include_hashtags: false. - Pinterest is special —
include_hashtagsis ignored. Pinterest uses natural-language search, not hashtags, so they're omitted.