File Upload & Management
The Synvo API provides comprehensive file and directory management capabilities. All file operations support various formats including documents, images, videos, and web pages.
Authentication
All endpoints require authentication via:
- API Key:
X-API-Key: <api_key>
Base URL
https://api.synvo.aiCreate Directory
Creates a virtual directory in Azure Blob Storage by uploading a .keep marker file.
Endpoint: POST /file/create_dir
Content-Type: application/x-www-form-urlencoded
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Directory path (e.g., "/", "/docs") |
Example Request
curl -X POST "https://api.synvo.ai/file/create_dir" \
-H "X-API-Key: ${API-KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "path=/docs"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/file/create_dir"
data = {"path": "/docs"}
headers = {"X-API-Key": api_key}
response = requests.post(url, data=data, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const params = new URLSearchParams({ path: "/docs" });
const response = await fetch("https://api.synvo.ai/file/create_dir", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: params,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"message": "Directory created successfully at /docs"
}Response Codes
200- Directory exists or created400- Bad request401- Unauthorized
List Directory Contents
Lists files and directories at a given path, optionally recursive with version tracking.
Endpoint: GET /file/list
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | "/" | Directory path |
recursive | boolean | true | Include nested items and return tree structure |
version | string | - | Optional file version to check if refresh is needed |
Example Request
curl -X GET "https://api.synvo.ai/file/list?path=/project&recursive=true" \
-H "X-API-Key: ${API-KEY}"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/file/list"
params = {"path": "/project", "recursive": True}
headers = {"X-API-Key": api_key}
response = requests.get(url, params=params, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const params = new URLSearchParams({
path: "/project",
recursive: "true"
});
const response = await fetch(`https://api.synvo.ai/file/list?${params}`, {
method: "GET",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"items": [
{
"is_dir": false,
"name": "document.pdf",
"path": "/project/document.pdf",
"file_id": "abc123xyz",
"size": 1024000,
"status": "COMPLETED",
"created_at": "2024-01-15T10:30:00Z"
}
],
"tree": {
"/project": {
"document.pdf": {
"file_id": "abc123xyz",
"is_dir": false
}
}
},
"version": "v1.2.3",
"need_refresh_file": false
}Response Codes
200- Directory listing400- Bad request401- Unauthorized404- Directory not found
Upload File
Uploads a file to the specified path, builds memory index if requested, and stores in Azure Blob Storage.
Endpoint: POST /file/upload
Content-Type: multipart/form-data
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
file | binary | Yes | - | File to upload |
path | string | No | "/" | Upload path |
Example Request
curl -X POST "https://api.synvo.ai/file/upload" \
-H "X-API-Key: ${API-KEY}" \
-F "file=@/path/to/document.pdf" \
-F "path=/"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/file/upload"
headers = {"X-API-Key": api_key}
with open("/path/to/document.pdf", "rb") as f:
files = {"file": f}
data = {
"path": "/",
}
response = requests.post(url, files=files, data=data, headers=headers, timeout=60)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const formData = new FormData();
formData.append("file", file);
formData.append("path", "/");
const response = await fetch("https://api.synvo.ai/file/upload", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: formData,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"filename": "document.pdf",
"path": "/",
"renamed": false,
"file_id": "abc123xyz",
"timestamp": "2024-01-15T10:30:00Z"
}Response Codes
200- Upload accepted400- Bad request401- Unauthorized
Download File
Returns a signed URL for downloading the file from Azure Blob Storage.
Endpoint: GET /file/download
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | File identifier |
Example Request
curl -X GET "https://api.synvo.ai/file/download?file_id=abc123xyz" \
-H "X-API-Key: ${API-KEY}"import requests
api_key = "<API_KEY>"
file_id = "abc123xyz"
url = "https://api.synvo.ai/file/download"
params = {"file_id": file_id}
headers = {"X-API-Key": api_key}
response = requests.get(url, params=params, headers=headers, timeout=30)
response.raise_for_status()
# Get the signed URL and download the file
data = response.json()
download_url = data["url"]
file_response = requests.get(download_url, timeout=60)
with open(data["name"], "wb") as f:
f.write(file_response.content)const api_key = "<API_KEY>";
const fileId = "abc123xyz";
const response = await fetch(`https://api.synvo.ai/file/download?file_id=${fileId}`, {
method: "GET",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log("Download URL:", data.url);
// Open the download URL in a new window
window.open(data.url, "_blank");Example Response
{
"url": "https://storage.azure.com/signed-url-here",
"name": "document.pdf",
"file_type": "application/pdf",
"file_id": "abc123xyz"
}Response Codes
200- File download information401- Unauthorized404- File not found
Delete File
Deletes a file or directory and removes it from the vector database.
Endpoint: DELETE /file/delete/{file_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | File identifier |
Example Request
curl -X DELETE "https://api.synvo.ai/file/delete/abc123xyz" \
-H "X-API-Key: ${API-KEY}"import requests
api_key = "<API_KEY>"
file_id = "abc123xyz"
url = f"https://api.synvo.ai/file/delete/{file_id}"
headers = {"X-API-Key": api_key}
response = requests.delete(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const fileId = "abc123xyz";
const response = await fetch(`https://api.synvo.ai/file/delete/${fileId}`, {
method: "DELETE",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"message": "File deleted successfully"
}Response Codes
200- Deleted401- Unauthorized404- File not found
Move/Rename File
Moves a file or directory to a new location and updates all database references.
Endpoint: POST /file/move
Content-Type: application/x-www-form-urlencoded
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
src | string | Yes | Source path (e.g., "/project/report.pdf") |
dest | string | Yes | Destination path (e.g., "/archive/report.pdf") |
Example Request
curl -X POST "https://api.synvo.ai/file/move" \
-H "X-API-Key: ${API-KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "src=/project/report.pdf" \
--data-urlencode "dest=/archive/report.pdf"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/file/move"
data = {
"src": "/project/report.pdf",
"dest": "/archive/report.pdf"
}
headers = {"X-API-Key": api_key}
response = requests.post(url, data=data, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const params = new URLSearchParams({
src: "/project/report.pdf",
dest: "/archive/report.pdf"
});
const response = await fetch("https://api.synvo.ai/file/move", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: params,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"message": "File moved successfully",
"file_moves": [
["/project/report.pdf", "/archive/report.pdf"]
]
}Response Codes
200- Successfully moved401- Unauthorized404- Source not found409- Destination already exists
Get File Thumbnail
Returns a thumbnail image for supported file types (images, PDFs, videos).
Endpoint: GET /file/thumbnail
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
file_id | string | - | File identifier |
max_size | integer | 200 | Maximum thumbnail size (width or height) |
Example Request
curl -X GET "https://api.synvo.ai/file/thumbnail?file_id=abc123xyz&max_size=200" \
-H "X-API-Key: ${API-KEY}" \
-o thumbnail.jpgimport requests
api_key = "<API_KEY>"
file_id = "abc123xyz"
url = "https://api.synvo.ai/file/thumbnail"
params = {"file_id": file_id, "max_size": 200}
headers = {"X-API-Key": api_key}
response = requests.get(url, params=params, headers=headers, timeout=30)
response.raise_for_status()
with open("thumbnail.jpg", "wb") as f:
f.write(response.content)const api_key = "<API_KEY>";
const fileId = "abc123xyz";
const params = new URLSearchParams({
file_id: fileId,
max_size: "200"
});
const response = await fetch(`https://api.synvo.ai/file/thumbnail?${params}`, {
method: "GET",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
// Display thumbnail in an img element
const img = document.createElement("img");
img.src = imageUrl;
document.body.appendChild(img);Response Codes
200- Thumbnail image (binary data)401- Unauthorized404- File not found
Get File Processing Status
Returns the current processing status of a file (PENDING, COMPLETED, FAILED).
Endpoint: GET /file/status/{file_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | File identifier |
Example Request
curl -X GET "https://api.synvo.ai/file/status/abc123xyz" \
-H "X-API-Key: ${API-KEY}"import requests
api_key = "<API_KEY>"
file_id = "abc123xyz"
url = f"https://api.synvo.ai/file/status/{file_id}"
headers = {"X-API-Key": api_key}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const apiKey = "<API_KEY>";
const fileId = "abc123xyz";
const response = await fetch(`https://api.synvo.ai/file/status/${fileId}`, {
method: "GET",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"file_id": "abc123xyz",
"status": "COMPLETED"
}Status Values
PENDING- File is being processedCOMPLETED- File processing completed successfullyFAILED- File processing failedUNKNOWN- Status cannot be determined
Response Codes
200- File status401- Unauthorized
Verify Upload Completion
After uploading files, it's critical to verify that all files have been processed before querying them. Here's how to check the processing status:
import requests
import time
api_key = "<API_KEY>"
BASE_URL = "https://api.synvo.ai"
# Assume we have file_ids from previous uploads
# file_ids = {"document.pdf": "file_abc123", "report.docx": "file_def456"}
# Wait for all files to complete processing
print("\n⏳ Waiting for all files to process...")
for filename, file_id in file_ids.items():
while True:
status_response = requests.get(
f"{BASE_URL}/file/status/{file_id}",
headers={"X-API-Key": api_key}
)
status = status_response.json()["status"]
if status == "COMPLETED":
print(f"✅ {filename} processing complete!")
break
elif status == "FAILED":
print(f"❌ {filename} processing failed!")
break
# Wait 5 seconds before checking again
time.sleep(5)
print("\n🎉 All files ready for querying!")
print("\nFile IDs:")
for filename, file_id in file_ids.items():
print(f" {filename}: {file_id}")const apiKey = "<API_KEY>";
const BASE_URL = "https://api.synvo.ai";
// Assume we have fileIds from previous uploads
// const fileIds = {"document.pdf": "file_abc123", "report.docx": "file_def456"}
// Wait for all files to complete processing
console.log("\n⏳ Waiting for all files to process...");
async function waitForFileProcessing(filename, fileId) {
while (true) {
const statusResponse = await fetch(
`${BASE_URL}/file/status/${fileId}`,
{
headers: { "X-API-Key": apiKey }
}
);
const data = await statusResponse.json();
const status = data.status;
if (status === "COMPLETED") {
console.log(`✅ ${filename} processing complete!`);
break;
} else if (status === "FAILED") {
console.log(`❌ ${filename} processing failed!`);
break;
}
// Wait 5 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
// Process all files
for (const [filename, fileId] of Object.entries(fileIds)) {
await waitForFileProcessing(filename, fileId);
}
console.log("\n🎉 All files ready for querying!");
console.log("\nFile IDs:");
for (const [filename, fileId] of Object.entries(fileIds)) {
console.log(` ${filename}: ${fileId}`);
}Complete Upload Workflow with Status Verification
Here's a complete example that uploads multiple files and waits for processing to complete:
import requests
import time
from pathlib import Path
api_key = "<API_KEY>"
BASE_URL = "https://api.synvo.ai"
# List of files to upload
files_to_upload = [
{"path": "/documents", "file": "/local/path/report.pdf"},
{"path": "/documents", "file": "/local/path/summary.docx"},
{"path": "/images", "file": "/local/path/chart.png"},
]
# Step 1: Upload all files
print("📤 Uploading files...")
file_ids = {}
for item in files_to_upload:
file_path = item["file"]
upload_path = item["path"]
filename = Path(file_path).name
try:
with open(file_path, "rb") as f:
files = {"file": f}
data = {"path": upload_path}
response = requests.post(
f"{BASE_URL}/file/upload",
files=files,
data=data,
headers={"X-API-Key": api_key},
timeout=60
)
response.raise_for_status()
result = response.json()
file_id = result.get("file_id")
file_ids[filename] = file_id
print(f"✓ Uploaded: {filename} (ID: {file_id})")
time.sleep(0.5) # Rate limiting
except Exception as e:
print(f"✗ Failed to upload {filename}: {e}")
# Step 2: Wait for all files to complete processing
print("\n⏳ Waiting for all files to process...")
for filename, file_id in file_ids.items():
max_retries = 60 # Maximum 5 minutes (60 * 5 seconds)
retries = 0
while retries < max_retries:
try:
status_response = requests.get(
f"{BASE_URL}/file/status/{file_id}",
headers={"X-API-Key": api_key},
timeout=10
)
status_response.raise_for_status()
status = status_response.json()["status"]
if status == "COMPLETED":
print(f"✅ {filename} - Processing complete!")
break
elif status == "FAILED":
print(f"❌ {filename} - Processing failed!")
break
retries += 1
time.sleep(5)
except Exception as e:
print(f"⚠️ Error checking status for {filename}: {e}")
retries += 1
time.sleep(5)
if retries >= max_retries:
print(f"⏱️ {filename} - Timeout waiting for processing")
# Step 3: Summary
print("\n🎉 Batch upload complete!")
print("\nProcessed File IDs:")
for filename, file_id in file_ids.items():
print(f" {filename}: {file_id}")const apiKey = "<API_KEY>";
const BASE_URL = "https://api.synvo.ai";
// List of files to upload (assumes File objects from file input)
const filesToUpload = [
{ path: "/documents", file: documentFile },
{ path: "/documents", file: summaryFile },
{ path: "/images", file: chartFile },
];
async function batchUploadWithVerification() {
// Step 1: Upload all files
console.log("📤 Uploading files...");
const fileIds = {};
for (const item of filesToUpload) {
const file = item.file;
const uploadPath = item.path;
const filename = file.name;
try {
const formData = new FormData();
formData.append("file", file);
formData.append("path", uploadPath);
const response = await fetch(`${BASE_URL}/file/upload`, {
method: "POST",
headers: { "X-API-Key": apiKey },
body: formData,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const result = await response.json();
const fileId = result.file_id;
fileIds[filename] = fileId;
console.log(`✓ Uploaded: ${filename} (ID: ${fileId})`);
await new Promise(resolve => setTimeout(resolve, 500)); // Rate limiting
} catch (error) {
console.log(`✗ Failed to upload ${filename}: ${error.message}`);
}
}
// Step 2: Wait for all files to complete processing
console.log("\n⏳ Waiting for all files to process...");
for (const [filename, fileId] of Object.entries(fileIds)) {
const maxRetries = 60; // Maximum 5 minutes (60 * 5 seconds)
let retries = 0;
while (retries < maxRetries) {
try {
const statusResponse = await fetch(
`${BASE_URL}/file/status/${fileId}`,
{ headers: { "X-API-Key": apiKey } }
);
if (!statusResponse.ok) {
throw new Error(`HTTP ${statusResponse.status}`);
}
const data = await statusResponse.json();
const status = data.status;
if (status === "COMPLETED") {
console.log(`✅ ${filename} - Processing complete!`);
break;
} else if (status === "FAILED") {
console.log(`❌ ${filename} - Processing failed!`);
break;
}
retries++;
await new Promise(resolve => setTimeout(resolve, 5000));
} catch (error) {
console.log(`⚠️ Error checking status for ${filename}: ${error.message}`);
retries++;
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
if (retries >= maxRetries) {
console.log(`⏱️ ${filename} - Timeout waiting for processing`);
}
}
// Step 3: Summary
console.log("\n🎉 Batch upload complete!");
console.log("\nProcessed File IDs:");
for (const [filename, fileId] of Object.entries(fileIds)) {
console.log(` ${filename}: ${fileId}`);
}
}
// Execute batch operation
batchUploadWithVerification();Best Practices for File Upload
- Status Verification: Always check file processing status before querying
- Timeout Protection: Set maximum wait times to prevent infinite loops
- Error Handling: Properly handle upload failures and processing errors
- Rate Limiting: Add delays between uploads to avoid rate limits
- Progress Tracking: Log upload and processing progress for monitoring
Error Handling
All endpoints return standard HTTP status codes. Error responses include a JSON object with error details:
{
"error": "Error description",
"code": "ERROR_CODE"
}Common error codes:
400- Bad Request: Invalid parameters or malformed request401- Unauthorized: Missing or invalid authentication404- Not Found: Resource does not exist409- Conflict: Resource already exists or operation conflicts500- Internal Server Error: Server-side error