Documentation

Uploading Videos

Upload videos up to 10GB using chunked multipart uploads

SDK Status

Video upload is not yet implemented in the Python SDK. Use the REST API directly. The examples below show the REST API workflow.

Supported Formats

MP4, MOV, M4V, WebM, AVI. Maximum 10GB per video. 10MB chunks.

Upload Workflow

Videos use a 4-step chunked multipart upload

Step 1: Initiate Upload

curl -X POST https://api.aionvision.tech/api/v2/video-uploads/initiate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "inspection.mp4",
"content_type": "video/mp4",
"size_bytes": 524288000
}'

The response returns a media_id, upload_id, and a chunks array — each entry has a chunk_number, upload_url, and size_bytes.

Step 2: Upload Chunks

Upload each chunk to its presigned URL from the initiate response

curl -X PUT "PRESIGNED_CHUNK_URL" \
-H "Content-Type: video/mp4" \
--data-binary @chunk_001.bin

Step 3: Confirm Each Chunk

curl -X POST https://api.aionvision.tech/api/v2/video-uploads/chunks/confirm \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"media_id": "MEDIA_ID_FROM_STEP_1",
"upload_id": "UPLOAD_ID_FROM_STEP_1",
"chunk_number": 1,
"etag": "ETAG_FROM_S3_RESPONSE",
"size_bytes": 10485760
}'

Step 4: Complete Upload

curl -X POST https://api.aionvision.tech/api/v2/video-uploads/complete \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"media_id": "MEDIA_ID_FROM_STEP_1",
"upload_id": "UPLOAD_ID_FROM_STEP_1"
}'

Complete Python Example

import requests
import os
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.aionvision.tech/api/v2"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def upload_video(file_path):
file_size = os.path.getsize(file_path)
filename = os.path.basename(file_path)
# Step 1: Initiate — server determines chunk layout
resp = requests.post(
f"{BASE_URL}/video-uploads/initiate",
headers=HEADERS,
json={
"filename": filename,
"content_type": "video/mp4",
"size_bytes": file_size,
}
)
data = resp.json()
media_id = data["media_id"]
upload_id = data["upload_id"]
chunks = data["chunks"] # list of {chunk_number, upload_url, size_bytes, ...}
# Step 2 & 3: Upload each chunk to S3, then confirm
with open(file_path, "rb") as f:
for chunk_info in chunks:
chunk_data = f.read(chunk_info["size_bytes"])
# Upload to S3 presigned URL
s3_resp = requests.put(
chunk_info["upload_url"],
data=chunk_data,
headers={"Content-Type": "video/mp4"},
)
etag = s3_resp.headers["ETag"]
# Confirm the chunk
requests.post(
f"{BASE_URL}/video-uploads/chunks/confirm",
headers=HEADERS,
json={
"media_id": media_id,
"upload_id": upload_id,
"chunk_number": chunk_info["chunk_number"],
"etag": etag,
"size_bytes": chunk_info["size_bytes"],
},
)
print(f"Chunk {chunk_info['chunk_number']}/{len(chunks)} uploaded")
# Step 4: Complete
resp = requests.post(
f"{BASE_URL}/video-uploads/complete",
headers=HEADERS,
json={"media_id": media_id, "upload_id": upload_id},
)
return resp.json()
result = upload_video("inspection.mp4")
print(f"Video ID: {result['media_id']}")

Progress Tracking

curl https://api.aionvision.tech/api/v2/video-uploads/progress/{media_id} \
-H "Authorization: Bearer YOUR_API_KEY"

Error Recovery

Retry Failed Chunks

# Request new presigned URL for a failed chunk
curl -X POST https://api.aionvision.tech/api/v2/video-uploads/chunks/retry \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"media_id": "MEDIA_ID",
"upload_id": "UPLOAD_ID",
"chunk_number": 5
}'

Abort Upload

# Abort upload and clean up
curl -X POST https://api.aionvision.tech/api/v2/video-uploads/abort \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"media_id": "MEDIA_ID",
"upload_id": "UPLOAD_ID"
}'
# S3 multipart upload is aborted and chunk records are cleaned up