cURL
curl --fail-with-body --request POST \
--url "$XPILOT_API_BASE_URL/v1/assets" \
--header "Authorization: Bearer $XPILOT_API_KEY" \
--form 'files=@"solar.pdf"'const form = new FormData();
form.append("files", /* File|Blob */ solarPdf, "solar.pdf");
const response = await fetch(process.env.XPILOT_API_BASE_URL + "/v1/assets", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.XPILOT_API_KEY}` },
body: form,
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);import os, requests
response = requests.post(
os.environ["XPILOT_API_BASE_URL"] + "/v1/assets",
headers={"Authorization": "Bearer " + os.environ["XPILOT_API_KEY"]},
files=[("files", ("solar.pdf", open("solar.pdf", "rb"), "application/pdf"))],
timeout=70,
)
print(response.status_code, response.text)
response.raise_for_status(){
"data": [
{
"id": 1,
"name": "solar.pdf",
"url": "<asset_url>",
"mimetype": "application/pdf",
"created_at": 1791849600,
"updated_at": 1791849600
}
]
}{
"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_scope",
"message": "Check the credential scope and resource ownership."
},
"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>"
}Assets
Upload assets
Multipart upload, field name files, up to 5 files per request. Limits per file: documents (pdf, docx, pptx, md, markdown, mdx) 10 MB; images (jpg, jpeg, png, gif, webp, svg) 10 MB; audio (wav, mp3, m4a, aac, ogg, flac) 20 MB; video (mp4, webm, mov) 60 MB. Empty files are rejected. Errors return 400 invalid_parameter with reason (too_many, unsupported_type, empty, too_large), file and max_mb. Returned ids and urls are reused by conversations, voice cloning and avatar creation.
POST
/
v1
/
assets
cURL
curl --fail-with-body --request POST \
--url "$XPILOT_API_BASE_URL/v1/assets" \
--header "Authorization: Bearer $XPILOT_API_KEY" \
--form 'files=@"solar.pdf"'const form = new FormData();
form.append("files", /* File|Blob */ solarPdf, "solar.pdf");
const response = await fetch(process.env.XPILOT_API_BASE_URL + "/v1/assets", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.XPILOT_API_KEY}` },
body: form,
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);import os, requests
response = requests.post(
os.environ["XPILOT_API_BASE_URL"] + "/v1/assets",
headers={"Authorization": "Bearer " + os.environ["XPILOT_API_KEY"]},
files=[("files", ("solar.pdf", open("solar.pdf", "rb"), "application/pdf"))],
timeout=70,
)
print(response.status_code, response.text)
response.raise_for_status(){
"data": [
{
"id": 1,
"name": "solar.pdf",
"url": "<asset_url>",
"mimetype": "application/pdf",
"created_at": 1791849600,
"updated_at": 1791849600
}
]
}{
"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_scope",
"message": "Check the credential scope and resource ownership."
},
"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
Required scope:assets:write.
Manage API keys · Authentication and recovery

