Skip to main content

Drive API Documentation – xMagic

The Drive API allows you to programmatically manage folders (knowledge bases) and files (data sources) used as retrieval context for your agents.

Base path: /v1/knowledge-bases

Authentication & Base URL

See the Authentication page for details on API keys.

Base URL:

https://api.xmagic.ai/xmagic-backend/v1

1. Create a Folder

Create a new Drive folder (knowledge base). Supports nested folders via parent_kb_id.

Request

POST /v1/knowledge-bases

Request Body (JSON)

FieldTypeRequiredDescription
knowledge_base_namestringYesName of the folder
user_defined_tagsstring[]NoTags for categorization
parent_kb_idstringNoParent folder ID (null = root level)

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
}

# Create a root-level folder
response = requests.post(
f"{BASE_URL}/knowledge-bases",
headers=headers,
json={
"knowledge_base_name": "Company Policies",
"user_defined_tags": ["hr", "policies"],
},
)

folder = response.json()["data"]
print(f"Created folder: {folder['id']}")

# Create a nested sub-folder
response = requests.post(
f"{BASE_URL}/knowledge-bases",
headers=headers,
json={
"knowledge_base_name": "Meeting Policies",
"user_defined_tags": ["meetings"],
"parent_kb_id": folder["id"],
},
)

subfolder = response.json()["data"]
print(f"Created sub-folder: {subfolder['id']}")

Response — 200 OK

{
"status": "success",
"data": {
"id": "683abc123def456...",
"name": "Company Policies",
"created_at": "2026-06-01T10:00:00Z",
"parent_kb_id": null,
"is_root": true,
"integration_id": null,
"user_defined_tags": ["hr", "policies"]
}
}

Errors

StatusReason
403Missing create_knowledgebase permission
409Folder with same name already exists in that location

2. List Folders

Retrieve all folders in your workspace, optionally filtered by parent folder.

Request

GET /v1/knowledge-bases?scope=org&parent_kb_id={parent_kb_id}

Query Parameters

ParameterTypeDefaultDescription
scopestringorgorg, shared, or all
parent_kb_idstringnullFilter to contents of a specific parent folder

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

# List all root-level folders
response = requests.get(
f"{BASE_URL}/knowledge-bases",
headers=headers,
params={"scope": "org"},
)

data = response.json()["data"]
for kb in data["org_knowledge_bases"]:
print(f"{kb['name']} (ID: {kb['_id']})")

# List sub-folders inside a specific folder
parent_id = "683abc123def456..."
response = requests.get(
f"{BASE_URL}/knowledge-bases",
headers=headers,
params={"scope": "org", "parent_kb_id": parent_id},
)

subfolders = response.json()["data"]["org_knowledge_bases"]
for folder in subfolders:
print(f" └── {folder['name']}")

Response — 200 OK

{
"status": "success",
"data": {
"org_knowledge_bases": [
{
"_id": "683abc123def456...",
"name": "Company Policies",
"organization_id": "org_123",
"parent_kb_id": null,
"is_root": true,
"user_defined_tags": ["hr", "policies"],
"created_at": "2026-06-01T10:00:00Z"
}
],
"shared_knowledge_bases": []
}
}

3. Get Folder Details

Retrieve metadata for a specific folder, including child folder and file counts.

Request

GET /v1/knowledge-bases/{knowledge_base_id}?include_counts=true

Path Parameters

ParameterDescription
knowledge_base_idThe folder ID

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

folder_id = "683abc123def456..."
response = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}",
headers=headers,
params={"include_counts": True},
)

folder = response.json()["data"]
print(f"Folder: {folder['name']}")
print(f" Sub-folders: {folder['child_folders_count']}")
print(f" Files: {folder['files_count']}")

Response — 200 OK

{
"status": "success",
"data": {
"_id": "683abc123def456...",
"name": "Company Policies",
"parent_kb_id": null,
"is_root": true,
"child_folders_count": 3,
"files_count": 12,
"user_defined_tags": ["hr", "policies"]
}
}

4. Update a Folder

Rename a folder or update its tags.

Request

PATCH /v1/knowledge-bases/{knowledge_base_id}

Request Body (JSON)

FieldTypeDescription
knowledge_base_namestringNew folder name
user_defined_tagsstring[]Updated tags

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
}

folder_id = "683abc123def456..."
response = requests.patch(
f"{BASE_URL}/knowledge-bases/{folder_id}",
headers=headers,
json={
"knowledge_base_name": "HR Policies (Updated)",
"user_defined_tags": ["hr", "policies", "2026"],
},
)

print(response.json()["data"]["name"])

Errors

StatusReason
400Cannot update folder linked to an integration
409Name conflict with another folder in same location

5. Delete a Folder

Delete a folder and all its contents (sub-folders and files) recursively.

Request

DELETE /v1/knowledge-bases/{knowledge_base_id}

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

folder_id = "683abc123def456..."
response = requests.delete(
f"{BASE_URL}/knowledge-bases/{folder_id}",
headers=headers,
)

print(response.json()["message"])
# "Knowledge base and all its contents deleted successfully"
warning

This is irreversible. All sub-folders and files within will be permanently deleted.


6. List Files in a Folder

List all files (data sources) inside a folder. Supports pagination and recursive listing into sub-folders.

Request

GET /v1/knowledge-bases/{knowledge_base_id}/data-sources?page=0&page_size=20&recursive=false

Query Parameters

ParameterTypeDefaultDescription
pageint0Page number (0-based)
page_sizeint20Results per page
recursiveboolfalseInclude files from all sub-folders
search_strstringnullFilter by file name

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

folder_id = "683abc123def456..."

# List files in a specific folder
response = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources",
headers=headers,
params={"page": 0, "page_size": 50},
)

data = response.json()["data"]
print(f"Total items: {data['data_sources_count']['total']}")
for ds in data["data_sources"]:
print(f" - {ds.get('title') or ds.get('name')} ({ds.get('source_type', 'folder')})")

# Recursively list all files including sub-folders
response = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources",
headers=headers,
params={"page": 0, "page_size": 100, "recursive": True},
)

all_files = response.json()["data"]["data_sources"]
print(f"\nAll files (recursive): {len(all_files)}")

Response — 200 OK

{
"status": "success",
"data": {
"data_sources": [
{
"id": "ds_abc123...",
"title": "Meeting_guidelines.pdf",
"source_type": "document",
"status": "successful",
"knowledge_base_id": "683abc123def456...",
"created_at": "2026-06-01T10:30:00Z"
}
],
"data_sources_count": {
"total": 12,
"successful": 10
},
"folder_info": {
"id": "683abc123def456...",
"name": "Company Policies",
"is_root": true,
"parent_kb_id": null
},
"query_info": {
"recursive": false,
"folders_queried": 1
}
}
}

7. Upload a File to a Folder

Adding a file is a two-step process:

  1. Upload the file to get a file_id
  2. Add the file to a specific folder (triggers indexing)

Step 1: Upload File

POST /v1/uploaded-files
Content-Type: multipart/form-data

Step 2: Add File to Folder

POST /v1/knowledge-bases/{knowledge_base_id}/data-sources/documents

Request Body (JSON) — Step 2

FieldTypeRequiredDescription
file_idstringYesThe file_id from step 1
data_source_titlestringYesDisplay name for the file
trigger_indexingboolNoWhether to index immediately (default: true)

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

# Step 1: Upload the file
with open("meeting_policy.pdf", "rb") as f:
upload_response = requests.post(
f"{BASE_URL}/uploaded-files",
headers=headers,
files={"file": ("meeting_policy.pdf", f, "application/pdf")},
)

file_id = upload_response.json()["data"]
print(f"Uploaded file ID: {file_id}")

# Step 2: Add to a specific folder
folder_id = "683abc123def456..."
response = requests.post(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources/documents",
headers={**headers, "Content-Type": "application/json"},
json={
"file_id": file_id,
"data_source_title": "Meeting Policy Guidelines",
"trigger_indexing": True,
},
)

data_source = response.json()["data"]
print(f"File added: {data_source['title']} (status: {data_source['status']})")

Response — 200 OK

{
"status": "success",
"data": {
"_id": "ds_xyz789...",
"title": "Meeting Policy Guidelines",
"source_type": "document",
"status": "pending",
"knowledge_base_id": "683abc123def456..."
}
}

Errors

StatusReason
400Cannot add files to a folder linked to an integration
404File ID not found (expired or invalid)

8. Download Files from a Folder

Download one or more files from a folder as a ZIP archive.

Request

GET /v1/knowledge-bases/{knowledge_base_id}/data-sources/actions/download?data_source_id={id1},{id2}

Query Parameters

ParameterTypeDescription
data_source_idstringComma-separated data source IDs to download

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

folder_id = "683abc123def456..."
file_ids = "ds_abc123,ds_def456"

# Download files as ZIP
response = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources/actions/download",
headers=headers,
params={"data_source_id": file_ids},
)

if response.status_code == 200:
with open("downloaded_files.zip", "wb") as f:
f.write(response.content)
print("Files downloaded successfully!")
else:
print(f"Error: {response.json()}")

Response — 200 OK

Returns a binary ZIP file with Content-Type: application/zip.

Errors

StatusReason
400No downloadable data sources found (wrong IDs or non-document types)

9. Delete Files from a Folder

Delete one or more files from a folder.

Request

DELETE /v1/knowledge-bases/{knowledge_base_id}/data-sources?data_source_id={id1},{id2}

Query Parameters

ParameterTypeDescription
data_source_idstringComma-separated data source IDs to delete

Example

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}

folder_id = "683abc123def456..."
file_ids = "ds_abc123,ds_def456"

response = requests.delete(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources",
headers=headers,
params={"data_source_id": file_ids},
)

print(response.json()["message"])
# "Successfully deleted 2 data source(s)"

Complete Drive Workflow Example

End-to-end example: create a folder, upload files, list them, and download.

import requests

BASE_URL = "https://api.xmagic.ai/xmagic-backend/v1"
API_KEY = "YOUR_API_KEY"

headers = {"x-api-key": API_KEY}
json_headers = {**headers, "Content-Type": "application/json"}


# 1. Create a folder
folder_resp = requests.post(
f"{BASE_URL}/knowledge-bases",
headers=json_headers,
json={
"knowledge_base_name": "Q2 Reports",
"user_defined_tags": ["reports", "q2"],
},
)
folder_id = folder_resp.json()["data"]["id"]
print(f"1. Created folder: {folder_id}")


# 2. Upload and add multiple files
files_to_upload = ["report_q2.pdf", "financials_q2.xlsx"]

for filename in files_to_upload:
# Upload
with open(filename, "rb") as f:
upload_resp = requests.post(
f"{BASE_URL}/uploaded-files",
headers=headers,
files={"file": (filename, f)},
)
file_id = upload_resp.json()["data"]

# Add to folder
requests.post(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources/documents",
headers=json_headers,
json={
"file_id": file_id,
"data_source_title": filename,
"trigger_indexing": True,
},
)
print(f"2. Added: {filename}")


# 3. List files in folder
list_resp = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources",
headers=headers,
)
files = list_resp.json()["data"]["data_sources"]
print(f"3. Folder contains {len(files)} file(s)")


# 4. Download all files
all_ids = ",".join([f["id"] for f in files if f.get("source_type") == "document"])
if all_ids:
download_resp = requests.get(
f"{BASE_URL}/knowledge-bases/{folder_id}/data-sources/actions/download",
headers=headers,
params={"data_source_id": all_ids},
)
with open("q2_reports_export.zip", "wb") as f:
f.write(download_resp.content)
print("4. Downloaded all files as ZIP")