curl --fail-with-body --request POST \
--url "$XPILOT_API_BASE_URL/v1/video-agents/conversations/%3Cconversation_id%3E" \
--header "Authorization: Bearer $XPILOT_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: lesson-request-001' \
--data '{"prompt":"Make scene 2 shorter and add a worked example.","files":[{"url":"https://cdn.example.com/course.pdf","files_role":"primary"}],"callback_url":"https://your-domain.com/xpilot/callback","callback_id":"order-1024"}'const response = await fetch(process.env.XPILOT_API_BASE_URL + "/v1/video-agents/conversations/%3Cconversation_id%3E", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.XPILOT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "lesson-request-001",
},
body: JSON.stringify({
"prompt": "Make scene 2 shorter and add a worked example.",
"files": [
{
"url": "https://cdn.example.com/course.pdf",
"files_role": "primary"
}
],
"callback_url": "https://your-domain.com/xpilot/callback",
"callback_id": "order-1024"
}),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);import os, json, requests
response = requests.request(
"POST",
os.environ["XPILOT_API_BASE_URL"] + "/v1/video-agents/conversations/%3Cconversation_id%3E",
headers={
"Authorization": "Bearer " + os.environ["XPILOT_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "lesson-request-001",
},
json=json.loads("{\"prompt\":\"Make scene 2 shorter and add a worked example.\",\"files\":[{\"url\":\"https://cdn.example.com/course.pdf\",\"files_role\":\"primary\"}],\"callback_url\":\"https://your-domain.com/xpilot/callback\",\"callback_id\":\"order-1024\"}"),
timeout=70,
)
print(response.status_code, response.text)
response.raise_for_status(){
"data": {
"conversation_id": "<conversation_id>",
"message_id": "<message_id>",
"status": "running",
"cost_credits": 12
}
}{
"error": {
"code": "invalid_parameter",
"message": "Check parameter types, required fields and idempotency key."
},
"request_id": "<request_id>"
}{
"error": {
"code": "invalid_token",
"message": "Use an active scoped API Key. MCP OAuth tokens cannot call REST."
},
"request_id": "<request_id>"
}{
"error": {
"code": "insufficient_credits",
"message": "The balance cannot cover the platform reserve, or the credential monthly budget is used up."
},
"request_id": "<request_id>"
}{
"error": {
"code": "insufficient_scope",
"message": "Check the credential scope and resource ownership."
},
"request_id": "<request_id>"
}{
"error": {
"code": "not_found",
"message": "Use an existing owned conversation, message, brand kit or render ID."
},
"request_id": "<request_id>"
}{
"error": {
"code": "idempotency_conflict",
"message": "The same idempotency key must use the exact same input. A conversation may already be busy."
},
"request_id": "<request_id>"
}{
"error": {
"code": "rate_limited",
"message": "Credential/workspace rate or concurrency limit reached. Respect Retry-After before retrying.",
"retry_after": 60
},
"request_id": "<request_id>"
}Send message
Send a follow-up turn to a conversation that is not running (409 conversation_busy otherwise). Paid. When next_action=confirm_outline, send outline_action=confirm (no prompt) or outline_action=revise with a prompt. When next_action=reply, answer with a prompt. Otherwise send an edit instruction. video_config and require_outline_confirmation are create-only (400 unsupported_parameter).
curl --fail-with-body --request POST \
--url "$XPILOT_API_BASE_URL/v1/video-agents/conversations/%3Cconversation_id%3E" \
--header "Authorization: Bearer $XPILOT_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: lesson-request-001' \
--data '{"prompt":"Make scene 2 shorter and add a worked example.","files":[{"url":"https://cdn.example.com/course.pdf","files_role":"primary"}],"callback_url":"https://your-domain.com/xpilot/callback","callback_id":"order-1024"}'const response = await fetch(process.env.XPILOT_API_BASE_URL + "/v1/video-agents/conversations/%3Cconversation_id%3E", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.XPILOT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "lesson-request-001",
},
body: JSON.stringify({
"prompt": "Make scene 2 shorter and add a worked example.",
"files": [
{
"url": "https://cdn.example.com/course.pdf",
"files_role": "primary"
}
],
"callback_url": "https://your-domain.com/xpilot/callback",
"callback_id": "order-1024"
}),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);import os, json, requests
response = requests.request(
"POST",
os.environ["XPILOT_API_BASE_URL"] + "/v1/video-agents/conversations/%3Cconversation_id%3E",
headers={
"Authorization": "Bearer " + os.environ["XPILOT_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "lesson-request-001",
},
json=json.loads("{\"prompt\":\"Make scene 2 shorter and add a worked example.\",\"files\":[{\"url\":\"https://cdn.example.com/course.pdf\",\"files_role\":\"primary\"}],\"callback_url\":\"https://your-domain.com/xpilot/callback\",\"callback_id\":\"order-1024\"}"),
timeout=70,
)
print(response.status_code, response.text)
response.raise_for_status(){
"data": {
"conversation_id": "<conversation_id>",
"message_id": "<message_id>",
"status": "running",
"cost_credits": 12
}
}{
"error": {
"code": "invalid_parameter",
"message": "Check parameter types, required fields and idempotency key."
},
"request_id": "<request_id>"
}{
"error": {
"code": "invalid_token",
"message": "Use an active scoped API Key. MCP OAuth tokens cannot call REST."
},
"request_id": "<request_id>"
}{
"error": {
"code": "insufficient_credits",
"message": "The balance cannot cover the platform reserve, or the credential monthly budget is used up."
},
"request_id": "<request_id>"
}{
"error": {
"code": "insufficient_scope",
"message": "Check the credential scope and resource ownership."
},
"request_id": "<request_id>"
}{
"error": {
"code": "not_found",
"message": "Use an existing owned conversation, message, brand kit or render ID."
},
"request_id": "<request_id>"
}{
"error": {
"code": "idempotency_conflict",
"message": "The same idempotency key must use the exact same input. A conversation may already be busy."
},
"request_id": "<request_id>"
}{
"error": {
"code": "rate_limited",
"message": "Credential/workspace rate or concurrency limit reached. Respect Retry-After before retrying.",
"retry_after": 60
},
"request_id": "<request_id>"
}Documentation by X-Pilot
video_agents:write. A stable Idempotency-Key is required for exact retries.
Manage API keys · Authentication and recovery

Authorizations
Scoped X-Pilot API key
Headers
Stable key for exact retries only. Use a different key for a different operation or input.
8 - 128Path Parameters
An owned video agent conversation ID.
Body
The edit instruction or the answer to the assistant. Required unless outline_action=confirm; required with outline_action=revise to describe the change. Up to 20,000 characters.
20000"Make scene 2 shorter and add a worked example."
Only when next_action=confirm_outline. confirm continues with the outline; revise rewrites it using prompt.
confirm, revise Up to 5 attachments. Each item uses either an owned asset_id or a caller-supplied public http(s) URL. Third-party URLs are downloaded and archived to the caller's storage before use. Item fields: asset_id or url (required), name (optional, ≤255), type (optional: document, image, video; inferred when omitted), and files_role (optional: primary or reference).
Show child attributes
Show child attributes
[
{
"url": "https://cdn.example.com/course.pdf",
"files_role": "primary"
}
]
Optional webhook for this message only. Public HTTPS (port 443) up to 2,048 characters; private, loopback and http addresses return 400 invalid_webhook_url / unsafe_webhook_url. When the message reaches completed, paused, failed or stopped, X Pilot POSTs a video-agent. event signed with the workspace callback secret (Developer console → Webhooks). Deliveries retry up to 6 times and are listed in the console.
2048"https://your-domain.com/xpilot/callback"
Optional reference echoed back as data.callback_id in the callback, such as your order ID. Letters, digits, _ . : - up to 128 characters. Requires callback_url.
128^[\w.:-]{1,128}$"order-1024"
Response
Success
