Initiate Import
POST https://embed-api.postnitro.ai/post/initiate/import
Creates a carousel, image or video post from your own slide content. For a video, see Video Posts. To have the AI write the slides instead, use Generate.
Headers
Content-Type: application/jsonembed-api-key: your-api-key-here(required)
Request Body
| Field | Type | Required | Description | Allowed Values |
|---|---|---|---|---|
postType | string | Yes | Type of post to generate | "CAROUSEL" , "IMAGE", "VIDEO" |
requestorId | string | No | Custom identifier for tracking | Any string |
templateId | string | Yes | ID of the template to use: see Templates | Valid template ID |
brandId | string | Yes | ID of the brand configuration: see Brands | Valid brand ID |
responseType | string | No | Output format (default: “DESIGN”) | "DESIGN", "PDF", "PNG", "MP4" |
slides | array , object | Yes | Array of slide objects for postType CAROUSEL and VIDEO, and an object for postType IMAGE | See slide structure below |
generateImages | object | No | Opt-in AI image generation — generates images and bakes them into the design before rendering | See AI Image Generation |
videoSettings | object | No | How a video post moves, its music and its voiceover. A video is animated without it | See Video Posts |
Slide Structure
Each slide must have the following structure:
| Field | Type | Required | Description | Allowed Values |
|---|---|---|---|---|
type | string | Yes for postType CAROUSEL and VIDEO, not required for postType IMAGE | Type of slide | "starting_slide", "body_slide", "ending_slide" |
heading | string | Yes | Main heading text | Any string |
sub_heading | string | No | Subtitle text | Any string |
description | string | No | Description text | Any string |
image | string | No | Image URL | Valid URL |
background_image | string | No | Background image URL | Valid URL |
cta_button | string | No | Call-to-action button text | Any string |
layoutType | string | No | Slide layout type. Available on both CAROUSEL and IMAGE slides | "default" (default), "infographic" |
layoutConfig | object | No | Infographics configuration, used when layoutType is "infographic". If omitted, the slide falls back to the default layout | Layout Configuration |
Layout Configuration (Infographics)
All fields are optional; any field you omit uses its default.
| Field | Type | Required | Default | Description | Allowed Values |
|---|---|---|---|---|---|
hasHeader | boolean | No | true | Display a header for each column | true, false |
columnCount | number | No | 1 | Number of columns to display | 1, 2, 3 |
displayCounterAs | string | No | "counter" | How the counter is displayed | "none", "counter" |
columnDisplay | string | No | "grid" | Cyclical or grid layout | "cycle", "grid" |
columnData | array | No | [] | Array of column data | Column Data |
Infographics Column Data
Each entry in columnData is a column:
| Field | Type | Required | Description | Allowed Values |
|---|---|---|---|---|
id | string | Yes | Unique id for the column. Caller-provided — stored as-is, not auto-generated | Any string |
header | string | No | Column header text (shown when hasHeader is true) | Any string |
content | array | Yes | Items in the column | Content Item |
Infographics Content Item
Each element of a column’s content array:
| Field | Type | Required | Description | Allowed Values |
|---|---|---|---|---|
id | string | Yes | Unique id for the item. Caller-provided — stored as-is, not auto-generated | Any string |
icon | string | null | No | Optional icon | Any string or null |
title | string | Yes | Item title | Any string |
description | string | Yes | Description as an HTML string | e.g. "<p dir=\"ltr\">Description</p>" |
titleEnabled | boolean | No | Whether to show the title | true, false |
descriptionEnabled | boolean | No | Whether to show the description | true, false |
Important Information for CAROUSEL!
- Exactly 1
starting_slide(required) — must be the first slide - At least 1
body_slide(required) — placed between the starting and ending slides - Exactly 1
ending_slide(required) — must be the last slide - Column Count should not exceed 3
- Layout Type set as
infographicwill replace theimagefield (any provided image is ignored on that slide) - Column Display can either be set as
cycleorgrid - Cyclical Infographic (
columnDisplay: "cycle") accepts data in the firstcolumnDataentry only, so no need to add information in columns two or three - Slides must be an array and include
type
Important Information for IMAGE!
- Slides must be an object
- IMAGE slides support the same infographic layout as CAROUSEL — set
layoutType: "infographic"and providelayoutConfig. Beyond the six content fields,layoutTypeandlayoutConfigare the only additional fields allowed on an IMAGE slide.
Important Information for VIDEO!
- Slides follow the same rules as
CAROUSEL— an array, each slide with atype, exactly 1starting_slide, at least 1body_slide, exactly 1ending_slide. Each slide becomes a scene in the video. - Infographic layouts work the same way as they do on carousel slides.
- Motion, music and voiceover are set once with
videoSettings, not per slide, and the video runs as long as its slides and motion take. Its dimensions come from the template, as with any other post type. - With no
videoSettingsthe video is animated anyway: see Video Motion. For per-slide motion,motiontakes one entry per slide, in the same order asslides.
Important Information for Infographics! (IMAGE & CAROUSEL)
- Available on both IMAGE (the single slide object) and CAROUSEL (per slide in the array). For CAROUSEL it can be set on any slide —
starting_slide,body_slide, orending_slide. - The
idfields on each column and eachcontentitem must be provided by the caller — they are stored as-is and are not auto-generated by the import endpoint. - If
layoutTypeis"infographic"butlayoutConfigis missing, the slide falls back to the default layout. - Any
layoutConfigfield you omit uses its default.
Validation note: IMAGE enforces a strict field allowlist, so
layoutTypeandlayoutConfigare explicitly permitted (any other unknown field returns a422). CAROUSEL does not restrict extra fields, so these keys pass through freely. Infographic behavior is identical on both — only the validation strictness differs.
Video Posts
Set postType: "VIDEO" to turn your imported slides into a video — each slide becomes a scene. See the VIDEO example.
Everything else about video posts:
- Video Motion: how a video moves without asking, the built-in styles, saved styles and sequences, and its length
- Voiceover: narration the AI writes and records, in the voice and tone you pick
- Per-Slide Motion: each slide’s own animations
- Motion Styles and Motion Sequences: list and save the styles and sequences
videoSettingstakes by id - Audio: the
backgroundMusicIdfor its music - Read a Post and Edit a Post: a video’s settings read back, and its slides, template, brand, motion, music or voiceover changed later
Response types. A VIDEO post accepts only "MP4" — renders the video — or "DESIGN", which saves the design without rendering so you can finish it in the video maker via editorUrl. "PDF" and "PNG" are rejected for VIDEO, and "MP4" is rejected for every other post type.
videoSettings
All of it is optional. A video with no videoSettings is animated as its template is, or in the Clean style, and runs as long as its motion takes, up to 2:00. See Video Motion.
| Field | Type | Description |
|---|---|---|
motionStyle | string | How every slide moves: a built-in style’s name, such as "clean" or "bold", or the id of a style saved in your workspace. See Motion styles, and list yours with Motion Styles |
sequenceId | string | The id of a sequence saved in your workspace: its animations on every slide, over the style. See Saved styles and sequences, and list them with Motion Sequences |
backgroundMusicId | string | Music under the video: the id of an audio file in your workspace, from GET /audio. See Background music |
backgroundMusicVolume | number | The music’s volume in percent, 0 to 100, as the editor’s slider shows it. Default 100 |
voiceover | object | A voiceover the AI writes and records: { voice, tone, captions }, all optional. See Voiceover |
Three more fields are accepted: motion, each slide’s own animations, for per-slide motion; videoDuration, which is ignored, since a video runs as long as its motion takes (Length); and audioId, the older name of backgroundMusicId, so requests that send it keep working. Any other field returns a 422, and so does videoSettings on a CAROUSEL or IMAGE post.
Background music
backgroundMusicId is a media id, not a URL. Get one from the Audio API: upload happens in the PostNitro app, and GET /audio lists what the workspace has. It’s verified when you make the request: the media must exist, belong to your API key’s workspace, and be an audio file. Otherwise the request is rejected with a 422.
audioId is its older name and is still accepted. Send one or the other: both together are refused.
The music is kept on the design with its volume, so the editor and the MP4 play it alike. A new track starts at its beginning, at 100 unless backgroundMusicVolume says otherwise, and fades out over the last second. It’s lowered to 30% while a voiceover plays. On a new video, backgroundMusicVolume needs backgroundMusicId. On an edit, a volume alone sets the volume of the music the video already has.
Message (422) | When |
|---|---|
videoSettings takes backgroundMusicId, or audioId, its older name, not both | Both are sent |
videoSettings.backgroundMusicId does not exist in this workspace | No such media, or it belongs to another workspace |
videoSettings.backgroundMusicId must reference an audio file | The id is an image or another file that isn’t audio |
videoSettings.backgroundMusicId must be a media id string | Empty, or not a string |
videoSettings.backgroundMusicVolume must be a number from 0 to 100, its volume in percent | Not a number, or outside 0 to 100 |
videoSettings.backgroundMusicVolume needs the track it sets: backgroundMusicId | A volume with no track, on a new video |
audioId gets the same three messages as backgroundMusicId, with its own name: videoSettings.audioId does not exist in this workspace, and so on.
The scheduling API’s
postSettingstakes the samebackgroundMusicId, so a track carries straight over from importing a video to scheduling it as a reel. A reel plays its design’s motion, and runs as long as it does.
AI Image Generation
Add an optional generateImages object to have the API generate AI images and bake them into the design before it’s rendered. Its presence is the opt-in — omit the field and no images are generated (existing behavior). Works for CAROUSEL, IMAGE, and VIDEO posts and with every responseType (PDF, PNG, MP4, DESIGN).
| Field | Type | Required | Default | Allowed Values |
|---|---|---|---|---|
context | string | No | Empty string if not provided | Any string — topic/brief that guides the image prompts |
imagePlacement | string | No | "auto" | "auto", "background", "in-line" |
imageStrategy | string | No | "strategic" | "strategic", "all" |
These are the only accepted fields — any other key inside generateImages returns a 422. Everything else the image service needs is resolved server-side: editorType from postType, the platform image model, and the copy config (socialPlatform/tone/audience/language) which defaults to LinkedIn / creative / general public / english on the import endpoint.
On direct REST calls,
contextis optional (it falls back as shown above). Over the MCP server and CLI,contextis required — the AI agent composes it for the user. That is the only difference in howgenerateImagesbehaves across the two.
imagePlacement
| Value | Behavior |
|---|---|
auto | AI decides per slide whether an image is a background or placed in-line with the content. |
background | Images are generated for slide backgrounds. |
in-line | Images are generated to sit inside the slide content, alongside the text. |
imageStrategy
| Value | Behavior |
|---|---|
strategic | The AI picks which slides get images, capped at ~50% of slides for a balanced look. |
all | Every eligible slide gets an image, capped only by available credits. |
Behavior & limits:
- Image generation runs after the design is created and before rendering, so a rendered
PDF/PNGalready contains the images and aDESIGNresponse has them baked into the saved design (visible viaeditorUrl). The output shape is unchanged — no new fields. - Best-effort: if generation fails or isn’t permitted, the post still completes without images. A
GENERATE_IMAGESstep appears in the status logs —COMPLETEDon success,FAILED(with a skip reason) otherwise. - Free plan: AI image generation is not available — the step is skipped (logged as failed) and the post completes without images.
- Credits: the post’s reported
credits(slide-based) are unchanged. AI images bill against the organization’s separate AI-image quota. - Image generation adds latency — keep polling status until
COMPLETED.
Example Requests
Default - CAROUSEL
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "CAROUSEL",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "PNG",
"slides": [
{
"type": "starting_slide",
"sub_heading": "My Awesome Subtitle",
"heading": "Welcome to the Carousel!",
"description": "This is how you start with a bang.",
"cta_button": "Swipe to learn more",
"background_image": "https://example.com/background1.jpg"
},
{
"type": "body_slide",
"heading": "Section 1: The Core Idea",
"description": "Explain your first key point here. This point might have multiple lines too.",
"image": "https://example.com/image1.jpg"
},
{
"type": "body_slide",
"heading": "Section 2: Deeper Dive",
"description": "More details for the second point.",
"image": "https://example.com/image2.png"
},
{
"type": "ending_slide",
"sub_heading": "Ready to Act?",
"heading": "Get Started Today!",
"description": "A final encouraging message.",
"cta_button": "Visit Our Website",
"image": "https://example.com/logo.png",
"background_image": "https://example.com/background2.jpg"
}
]
}'Default - IMAGE
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "IMAGE",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "PNG",
"slides": {
"sub_heading": "Ready to Act?",
"heading": "Get Started Today!",
"description": "A final encouraging message.",
"cta_button": "Visit Our Website",
"image": "https://example.com/logo.png",
"background_image": "https://example.com/background2.jpg"
}
}'Default - VIDEO
Same slide array as a carousel. Here the video takes the Bold style, music at a quarter of its volume, and a voiceover in the Nova voice; drop videoSettings and it’s animated as its template is, or in the Clean style, and silent.
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "VIDEO",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "MP4",
"videoSettings": {
"motionStyle": "bold",
"backgroundMusicId": "cmqi7jyir0003v0m91hxnyyaq",
"backgroundMusicVolume": 25,
"voiceover": { "voice": "nova", "tone": "Hype and punchy" }
},
"slides": [
{
"type": "starting_slide",
"sub_heading": "Remote work",
"heading": "3 habits of fast teams",
"description": "The ones that actually stick.",
"cta_button": "Watch on"
},
{
"type": "body_slide",
"heading": "Write things down",
"description": "Decisions live in docs, not in calls."
},
{
"type": "ending_slide",
"heading": "Try one this week",
"description": "Pick the habit your team misses most.",
"cta_button": "Follow for more"
}
]
}'IMAGE with AI-generated background image
Uses generateImages to produce a background image instead of supplying one yourself.
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "IMAGE",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "PNG",
"slides": {
"heading": "Our 2026 Results",
"sub_heading": "By the numbers",
"cta_button": "Learn more"
},
"generateImages": {
"context": "Annual results, upbeat and professional",
"imagePlacement": "background",
"imageStrategy": "strategic"
}
}'With Infographics
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "CAROUSEL",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "PNG",
"slides": [
{
"type":"starting_slide",
"sub_heading":"Import API Feature",
"heading":"PostNitro Infographics",
"description":"Create stunning visual carousels with structured data using PostNitro's powerful infographics feature.",
"cta_button":"Learn More",
"background_image":"https://example.com/postnitro-bg.jpg"
},
{
"type":"body_slide",
"heading":"Grid Layout Infographics",
"description":"Display multiple data points in an organized grid format with PostNitro's flexible column system.",
"layoutType":"infographic",
"layoutConfig":{
"columnCount":2,
"columnDisplay":"grid",
"displayCounterAs":"counter",
"hasHeader":true,
"columnData":[
{
"id":"col-1",
"header":"Layout Options",
"content":[
{
"id":"item-1",
"icon":null,
"title":"Grid Display",
"description":"<p dir=\"ltr\">Organize content in structured columns for easy comparison and readability.</p>",
"titleEnabled":true,
"descriptionEnabled":true
},
{
"id":"item-2",
"icon":null,
"title":"Counter Support",
"description":"<p dir=\"ltr\">Add numbered counters to help users follow the sequence of information.</p>",
"titleEnabled":true,
"descriptionEnabled":true
}
]
},
{
"id":"col-2",
"header":"Customization",
"content":[
{
"id":"item-3",
"icon":null,
"title":"Column Headers",
"description":"<p dir=\"ltr\">Enable or disable headers for each column to match your content structure.</p>",
"titleEnabled":true,
"descriptionEnabled":true
},
{
"id":"item-4",
"icon":null,
"title":"Flexible Columns",
"description":"<p dir=\"ltr\">Choose between 1, 2, or 3 columns to fit your data presentation needs.</p>",
"titleEnabled":true,
"descriptionEnabled":true
}
]
}
]
}
},
{
"type":"body_slide",
"heading":"Standard Content Slides",
"description":"Mix infographics with traditional image-based slides for comprehensive storytelling with PostNitro.",
"image":"https://skfhtbmyanoeqbvrtxqa.supabase.co/storage/v1/object/public/media/static/postnitro-on-the-moon.png"
},
{
"type":"body_slide",
"heading":"Cyclical Infographics",
"description":"Perfect for step-by-step processes or sequential information using PostNitro's cycle display.",
"layoutType":"infographic",
"layoutConfig":{
"columnCount":1,
"columnDisplay":"cycle",
"displayCounterAs":"counter",
"hasHeader":true,
"columnData":[
{
"id":"col-1",
"header":"Implementation Steps",
"content":[
{
"id":"item-1",
"icon":null,
"title":"Set Layout Type",
"description":"<p dir=\"ltr\">Configure layoutType as 'infographic' to enable structured data display.</p>",
"titleEnabled":true,
"descriptionEnabled":true
},
{
"id":"item-2",
"icon":null,
"title":"Choose Display Mode",
"description":"<p dir=\"ltr\">Select 'cycle' for sequential presentation or 'grid' for comparative layout.</p>",
"titleEnabled":true,
"descriptionEnabled":true
},
{
"id":"item-3",
"icon":null,
"title":"Add Column Data",
"description":"<p dir=\"ltr\">Structure your content with titles and descriptions for each data point.</p>",
"titleEnabled":true,
"descriptionEnabled":true
},
{
"id":"item-4",
"icon":null,
"title":"Configure Options",
"description":"<p dir=\"ltr\">Set column count, headers, and counters to match your presentation needs.</p>",
"titleEnabled":true,
"descriptionEnabled":true
}
]
}
]
}
},
{
"type":"ending_slide",
"sub_heading":"Start Creating Today",
"heading":"Try PostNitro Infographics",
"description":"Transform your data into engaging visual carousels with PostNitro's Import API.",
"cta_button":"Get Your API Key"
}
]
}'IMAGE with Infographics
An IMAGE slide uses the same layoutType/layoutConfig fields — just as a single object rather than an array.
curl --location 'https://embed-api.postnitro.ai/post/initiate/import' \
--header 'Content-Type: application/json' \
--header 'embed-api-key: pn-your-api-key' \
--data '{
"postType": "IMAGE",
"templateId": "xtrnxgfgk9a08tmsz2601k1c",
"brandId": "cmdhb8oe10006v0pmh6a4no6t",
"responseType": "PNG",
"slides": {
"heading": "Our 2026 Results",
"sub_heading": "By the numbers",
"layoutType": "infographic",
"layoutConfig": {
"hasHeader": true,
"columnCount": 3,
"columnDisplay": "grid",
"displayCounterAs": "counter",
"columnData": [
{
"id": "col-1",
"header": "Heading",
"content": [
{
"id": "item-1",
"icon": null,
"title": "Title",
"description": "<p dir=\"ltr\">Description</p>",
"titleEnabled": true,
"descriptionEnabled": true
}
]
}
]
}
}
}'Carousel Output (Infographics)

Response
{
"success": true,
"message": "CAROUSEL generation initiated",
"data": {
"embedPostId": "post123",
"status": "PENDING"
}
}Image Output
Response
{
"success": true,
"message": "IMAGE generation initiated",
"data": {
"embedPostId": "post456",
"status": "PENDING"
}
}Generation is asynchronous. This endpoint returns immediately with an
embedPostIdwhile the post is rendered in the background. Poll Check Post Status with theembedPostIduntil the status isCOMPLETED, then call Get Post Output to retrieve the final files.
Once it’s made, Read a Post gives its content back and Edit a Post changes it in place, by the same embedPostId.