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)
| Field | Type | Required | Description |
|---|---|---|---|
knowledge_base_name | string | Yes | Name of the folder |
user_defined_tags | string[] | No | Tags for categorization |
parent_kb_id | string | No | Parent 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
| Status | Reason |
|---|---|
403 | Missing create_knowledgebase permission |
409 | Folder 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
| Parameter | Type | Default | Description |
|---|---|---|---|
scope | string | org | org, shared, or all |
parent_kb_id | string | null | Filter 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
| Parameter | Description |
|---|---|
knowledge_base_id | The 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)
| Field | Type | Description |
|---|---|---|
knowledge_base_name | string | New folder name |
user_defined_tags | string[] | 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
| Status | Reason |
|---|---|
400 | Cannot update folder linked to an integration |
409 | Name 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"
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
| Parameter | Type | Default | Description |
|---|---|---|---|
page | int | 0 | Page number (0-based) |
page_size | int | 20 | Results per page |
recursive | bool | false | Include files from all sub-folders |
search_str | string | null | Filter 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:
- Upload the file to get a
file_id - 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
| Field | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | The file_id from step 1 |
data_source_title | string | Yes | Display name for the file |
trigger_indexing | bool | No | Whether 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
| Status | Reason |
|---|---|
400 | Cannot add files to a folder linked to an integration |
404 | File 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
| Parameter | Type | Description |
|---|---|---|
data_source_id | string | Comma-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
| Status | Reason |
|---|---|
400 | No 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
| Parameter | Type | Description |
|---|---|---|
data_source_id | string | Comma-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")