Install
openclaw skills install postnitro-carouselGenerate professional social media carousel posts using the PostNitro.ai Embed API. Supports AI-powered content generation and manual content import for Link...
openclaw skills install postnitro-carouselGenerate social media carousel posts via the PostNitro.ai Embed API. Two workflows: AI generation (topic/article/X post → carousel) and content import (your own slides, with optional infographics).
export POSTNITRO_API_KEY="your-api-key"
export POSTNITRO_TEMPLATE_ID="your-template-id"
export POSTNITRO_BRAND_ID="your-brand-id"
export POSTNITRO_PRESET_ID="your-ai-preset-id"
Base URL: https://embed-api.postnitro.ai
Auth header: embed-api-key: $POSTNITRO_API_KEY
All carousel creation is asynchronous: Initiate → Poll Status → Get Output.
curl -X POST 'https://embed-api.postnitro.ai/post/initiate/generate' \
-H 'Content-Type: application/json' \
-H "embed-api-key: $POSTNITRO_API_KEY" \
-d '{
"postType": "CAROUSEL",
"templateId": "'"$POSTNITRO_TEMPLATE_ID"'",
"brandId": "'"$POSTNITRO_BRAND_ID"'",
"presetId": "'"$POSTNITRO_PRESET_ID"'",
"responseType": "PNG",
"aiGeneration": {
"type": "text",
"context": "5 tips for growing your LinkedIn audience in 2026",
"instructions": "Professional tone, actionable advice"
}
}'
Returns { "success": true, "data": { "embedPostId": "post123", "status": "PENDING" } }. Save the embedPostId.
aiGeneration.type values:
"text" — context is the text content to turn into a carousel"article" — context is an article URL to extract and convert"x" — context is an X (Twitter) post or thread URLSee examples/generate-from-text.json, examples/generate-from-article.json, and examples/generate-from-x-post.json.
curl -X POST 'https://embed-api.postnitro.ai/post/initiate/import' \
-H 'Content-Type: application/json' \
-H "embed-api-key: $POSTNITRO_API_KEY" \
-d '{
"postType": "CAROUSEL",
"templateId": "'"$POSTNITRO_TEMPLATE_ID"'",
"brandId": "'"$POSTNITRO_BRAND_ID"'",
"responseType": "PNG",
"slides": [
{ "type": "starting_slide", "heading": "Your Title", "description": "Intro text" },
{ "type": "body_slide", "heading": "Key Point", "description": "Details here" },
{ "type": "ending_slide", "heading": "Take Action!", "cta_button": "Learn More" }
]
}'
Returns same response format with embedPostId.
Slide rules:
starting_slide (required)body_slide (required)ending_slide (required)heading is required on every slideSlide fields: heading (required), sub_heading, description, image (URL), background_image (URL), cta_button, layoutType, layoutConfig.
For infographic slides, set layoutType: "infographic" on body slides — replaces the image with structured data columns. See examples/import-infographics.json and references/api-reference.md for full infographics config.
curl -X GET "https://embed-api.postnitro.ai/post/status/$EMBED_POST_ID" \
-H "embed-api-key: $POSTNITRO_API_KEY"
Poll every 3–5 seconds until data.embedPost.status is "COMPLETED". The logs array shows step-by-step progress.
curl -X GET "https://embed-api.postnitro.ai/post/output/$EMBED_POST_ID" \
-H "embed-api-key: $POSTNITRO_API_KEY"
Returns downloadable URLs in data.result.data:
See references/api-reference.md for full response schemas.
Generate a carousel from a topic with professional tone:
{
"aiGeneration": {
"type": "text",
"context": "5 mistakes startups make with their LinkedIn strategy and how to fix each one",
"instructions": "Professional but conversational tone. Each slide should have one clear takeaway."
}
}
Turn an existing article into a carousel:
{
"aiGeneration": {
"type": "article",
"context": "https://yourblog.com/posts/social-media-strategy-2026",
"instructions": "Extract the 5 most actionable points. Keep slide text concise."
}
}
Convert a viral X thread into a visual carousel:
{
"aiGeneration": {
"type": "x",
"context": "https://x.com/username/status/1234567890",
"instructions": "Maintain the original voice and key points"
}
}
Import slides with structured infographic layouts:
See examples/import-infographics.json for a complete example with grid and cycle layouts.
"PNG" explicitly if you want individual slide images.heading is required on every slide — omitting it returns an error."article" type expects a URL as context, not plain text."x" type expects https://x.com/... or https://twitter.com/... as context.layoutType: "infographic" overrides any image on that slide.columnDisplay: "cycle" ignores data in columns 2+.columnCount cannot exceed 3 for infographic layouts.image and background_image fields require publicly accessible URLs.| Plan | Price | Credits/Month |
|---|---|---|
| Free | $0 | 5 |
| Monthly | $10 | 250+ (scalable) |
Reference docs:
Ready-to-use examples:
# Auth
Header: embed-api-key: $POSTNITRO_API_KEY
# AI generation
POST /post/initiate/generate { postType, templateId, brandId, presetId, responseType?, requestorId?, aiGeneration: { type, context, instructions? } }
# Content import
POST /post/initiate/import { postType, templateId, brandId, responseType?, requestorId?, slides: [{ type, heading, ... }] }
# Check status (poll until COMPLETED)
GET /post/status/{embedPostId}
# Get output (download URLs)
GET /post/output/{embedPostId}
POSTNITRO_API_KEY, POSTNITRO_TEMPLATE_ID, POSTNITRO_BRAND_ID before calling any endpoint.POSTNITRO_PRESET_ID is only required for AI generation, not for content import."article" type, the context must be a URL — not article text. For article text, use "text" type."x" type, the context must be an X/Twitter post URL.responseType is "PDF" — always pass "PNG" if the user wants individual slide images.starting_slide → 1+ body_slide → 1 ending_slide.GET /post/status/{embedPostId} every 3–5 seconds — don't hammer the endpoint.data field contains download URLs — present them to the user directly.