Submit Prompt
curl --request POST \
--url https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"content": "<string>",
"force": true
}
'import requests
url = "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt"
payload = {
"content": "<string>",
"force": True
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({content: '<string>', force: true})
};
fetch('https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'content' => '<string>',
'force' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt"
payload := strings.NewReader("{\n \"content\": \"<string>\",\n \"force\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"content\": \"<string>\",\n \"force\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"content\": \"<string>\",\n \"force\": true\n}"
response = http.request(request)
puts response.read_body{
"prompt_id": "<string>",
"status": "<string>",
"message": "<string>",
"estimated_time": "<string>",
"VALIDATION_ERROR": {},
"CONFLICT": {},
"NOT_FOUND": {}
}Prompts
Submit Prompt
Submit a text prompt to create video content for a chapter
POST
/
api
/
v1
/
projects
/
{projectId}
/
chapters
/
{chapterId}
/
prompt
Submit Prompt
curl --request POST \
--url https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"content": "<string>",
"force": true
}
'import requests
url = "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt"
payload = {
"content": "<string>",
"force": True
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({content: '<string>', force: true})
};
fetch('https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'content' => '<string>',
'force' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt"
payload := strings.NewReader("{\n \"content\": \"<string>\",\n \"force\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"content\": \"<string>\",\n \"force\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/projects/{projectId}/chapters/{chapterId}/prompt")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"content\": \"<string>\",\n \"force\": true\n}"
response = http.request(request)
puts response.read_body{
"prompt_id": "<string>",
"status": "<string>",
"message": "<string>",
"estimated_time": "<string>",
"VALIDATION_ERROR": {},
"CONFLICT": {},
"NOT_FOUND": {}
}Overview
Submit a prompt to a chapter, describing what to build. The system processes the prompt and creates the chapter content, typically completing in 30-90 seconds.If a chapter already has a prompt being processed, this endpoint returns a
409 Conflict error unless you set force: true to override.Request
Path Parameters
string
required
The project ID
string
required
The chapter ID
Headers
string
required
Bearer token with your API key
string
required
Must be
application/jsonBody
string
required
The prompt text describing the video content you want to create (1-5000 characters)
boolean
default:"false"
Force processing even if another prompt is already being processed for this chapter
Response
string
Unique identifier for the submitted prompt
string
Processing status:
processing, completed, or failedstring
Human-readable status message
string
Estimated processing time (e.g., “30-90 seconds”)
Examples
curl -X POST https://api.babou.ai/api/v1/projects/prj_abc123xyz/chapters/cht_def456uvw/prompt \
-H "Authorization: Bearer $BABOU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "30-second product launch ad for the new Team tier. Lead with the headline from our latest release notes, drop in the new pricing screenshot, and resolve brand colors and type from the catalog."
}'
async function submitPrompt(
projectId: string,
chapterId: string,
content: string,
force = false
) {
const response = await fetch(
`https://api.babou.ai/api/v1/projects/${projectId}/chapters/${chapterId}/prompt`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BABOU_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ content, force })
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to submit prompt: ${error.error}`);
}
return await response.json();
}
const result = await submitPrompt(
'prj_abc123xyz',
'cht_def456uvw',
'Product launch ad for the new Team tier, pulling the headline from our release notes'
);
console.log(`Prompt submitted: ${result.status}`);
console.log(`Estimated time: ${result.estimated_time}`);
import os
import requests
def submit_prompt(project_id, chapter_id, content, force=False):
response = requests.post(
f'https://api.babou.ai/api/v1/projects/{project_id}/chapters/{chapter_id}/prompt',
headers={
'Authorization': f'Bearer {os.environ["BABOU_API_KEY"]}',
'Content-Type': 'application/json'
},
json={'content': content, 'force': force}
)
if not response.ok:
error = response.json()
raise Exception(f'Failed to submit prompt: {error["error"]}')
return response.json()
result = submit_prompt(
'prj_abc123xyz',
'cht_def456uvw',
'Product launch ad for the new Team tier, pulling the headline from our release notes'
)
print(f'Prompt submitted: {result["status"]}')
print(f'Estimated time: {result["estimated_time"]}')
Response Example
{
"prompt_id": "int_abc123xyz789",
"status": "processing",
"message": "Prompt processing started",
"estimated_time": "30-90 seconds"
}
Error Responses
400
Invalid prompt content
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"hint": "Content must be between 1 and 5000 characters"
}
409
Another prompt is already being processed for this chapter
{
"error": "A prompt is already being processed for this chapter",
"code": "CONFLICT",
"hint": "Wait for the current prompt to complete or set force: true to override"
}
404
Project or chapter not found
{
"error": "Chapter not found",
"code": "NOT_FOUND"
}
Best Practices
Write clear, descriptive prompts
Write clear, descriptive prompts
Be specific about what you want in your video. Include details about:
- Visual style and aesthetics
- Text content and messaging
- Transitions and animations
- Mood and tone
const prompt = `
30-second product launch ad for the new Team tier.
- Lead with the headline from our latest release notes
- Show the updated pricing screenshot at 5s
- Resolve brand colors and type from the catalog
- Close on a CTA matching the pricing page button
`;
await submitPrompt(projectId, chapterId, prompt);
Wait for processing to complete
Wait for processing to complete
After submitting a prompt, the video content is created asynchronously. Use the Get Chapter endpoint to check when processing is complete:
async function waitForPromptCompletion(
projectId: string,
chapterId: string,
maxAttempts = 20
) {
for (let i = 0; i < maxAttempts; i++) {
const chapter = await getChapter(projectId, chapterId);
const latestPrompt = chapter.prompts[chapter.prompts.length - 1];
if (latestPrompt.status === 'completed') {
return latestPrompt;
}
if (latestPrompt.status === 'failed') {
throw new Error('Prompt processing failed');
}
await new Promise(r => setTimeout(r, 5000)); // Wait 5s
}
throw new Error('Timeout waiting for prompt completion');
}
Handle conflicts gracefully
Handle conflicts gracefully
If you get a 409 error, decide whether to:
- Wait for the current prompt to complete
- Override with
force: true(use cautiously)
async function submitPromptSafe(
projectId: string,
chapterId: string,
content: string
) {
try {
return await submitPrompt(projectId, chapterId, content);
} catch (error: any) {
if (error.message.includes('already being processed')) {
console.log('Waiting for current prompt to complete...');
await waitForPromptCompletion(projectId, chapterId);
// Retry submission
return await submitPrompt(projectId, chapterId, content);
}
throw error;
}
}
Reference uploaded assets
Reference uploaded assets
If you’ve uploaded assets, reference them in your prompts:
// Upload asset first
const logo = await uploadAsset('./company-logo.png', 'image/png');
// Reference in prompt
const prompt = `
Create an intro video using the uploaded company logo (${logo.url}).
Animate the logo with a fade-in effect over 3 seconds.
Add the text "Welcome" below the logo.
`;
await submitPrompt(projectId, chapterId, prompt);
Next Steps
Get Chapter
Check processing status
Export Project
Export your completed video
Video Creation Guide
Learn more about creating videos