Documentation

Code Examples

Ready-to-use examples in popular programming languages

Before You Start

Replace aion_your_api_key with your actual API key from the dashboard. The API supports four verification levels: quick (1 API call), standard (2 API calls), thorough (2 API calls, higher quality), and critical (3 API calls).

Python
Using the requests library

Upload Image with Auto-Description

import requests
import os
API_KEY = "aion_your_api_key"
BASE_URL = "https://api.aionvision.tech/api/v2"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Step 1: Get presigned URL
file_path = "product.jpg"
file_size = os.path.getsize(file_path)
presigned_response = requests.post(
f"{BASE_URL}/uploads/request-presigned-url",
headers=headers,
json={
"filename": os.path.basename(file_path),
"content_type": "image/jpeg",
"size_bytes": file_size
}
)
presigned = presigned_response.json()
# Step 2: Upload to storage (use upload_method from response)
method = presigned.get("upload_method", "PUT")
upload_headers = presigned.get("upload_headers") or {"Content-Type": "image/jpeg"}
with open(file_path, "rb") as f:
upload_response = requests.request(
method,
presigned["upload_url"],
data=f,
headers=upload_headers
)
# Step 3: Confirm upload (triggers auto-describe)
confirm = requests.post(
f"{BASE_URL}/uploads/confirm",
headers=headers,
json={
"object_key": presigned["object_key"],
"size_bytes": file_size
}
)
result = confirm.json()
print(f"Image ID: {result['upload_id']}")
print("Auto-describe queued - poll the image endpoint for description")

Batch Upload with Status Polling

import time
# Step 1: Prepare batch upload
batch_prepare = requests.post(
f"{BASE_URL}/uploads/batch-prepare",
headers=headers,
json={
"files": [
{"filename": "image1.jpg", "size_bytes": 1024000, "content_type": "image/jpeg"},
{"filename": "image2.jpg", "size_bytes": 2048000, "content_type": "image/jpeg"}
],
"intent": "describe",
"verification_level": "standard"
}
)
batch_data = batch_prepare.json()
batch_id = batch_data["batch_id"]
# Step 2: Upload each file using presigned URLs
files_input = [
{"filename": "image1.jpg", "size_bytes": 1024000},
{"filename": "image2.jpg", "size_bytes": 2048000}
]
for file_info in batch_data["presigned_urls"]:
method = file_info.get("upload_method", "PUT")
hdrs = file_info.get("upload_headers") or {"Content-Type": "image/jpeg"}
with open(file_info["filename"], "rb") as f:
requests.request(method, file_info["upload_url"], data=f, headers=hdrs)
# Step 3: Confirm batch upload
confirm_response = requests.post(
f"{BASE_URL}/uploads/batch-confirm",
headers=headers,
json={
"batch_id": batch_id,
"confirmations": [
{
"object_key": url["object_key"],
"success": True,
"file_size": files_input[url["file_index"]]["size_bytes"]
}
for url in batch_data["presigned_urls"]
],
"auto_process": True
}
)
# Poll for status using the uploads batch status endpoint
while True:
status_response = requests.get(
f"{BASE_URL}/uploads/batch/{batch_id}/status", headers=headers
)
batch_status = status_response.json()
pct = batch_status.get("completion_percentage", 0)
print(f"Status: {batch_status['overall_status']} - Progress: {pct}%")
if batch_status["overall_status"] in ["completed", "failed"]:
break
time.sleep(2)
# Results are in the batch-confirm response's stored_images
for img in confirm_response.json().get("stored_images", []):
print(f"Image {img['image_id']}: {img['filename']}")
cURL
Command line examples

Upload Image with Auto-Description

# Step 1: Get presigned URL
curl -X POST https://api.aionvision.tech/api/v2/uploads/request-presigned-url \
-H "Authorization: Bearer aion_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filename": "image.jpg",
"content_type": "image/jpeg",
"size_bytes": 1048576
}'
# Step 2: Upload file (use upload_url and upload_method from response)
# upload_method will be "PUT" or "POST" - use the corresponding
# upload_headers (for PUT) or upload_fields (for POST)
curl -X PUT "<upload_url_from_step_1>" \
-H "Content-Type: image/jpeg" \
--data-binary @image.jpg
# Step 3: Confirm upload (triggers auto-describe)
curl -X POST https://api.aionvision.tech/api/v2/uploads/confirm \
-H "Authorization: Bearer aion_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"object_key": "<object_key_from_step_1>",
"size_bytes": 1048576
}'
Error Handling
def upload_with_retry(file_path, max_retries=3):
"""Upload a file with automatic retry and error handling."""
for attempt in range(max_retries):
try:
# Step 1: Get presigned URL
response = requests.post(
f"{BASE_URL}/uploads/request-presigned-url",
headers=headers,
json={
"filename": os.path.basename(file_path),
"content_type": "image/jpeg",
"size_bytes": os.path.getsize(file_path)
}
)
if response.status_code == 200:
presigned = response.json()
# Step 2: Upload to storage
method = presigned.get("upload_method", "PUT")
hdrs = presigned.get("upload_headers") or {}
with open(file_path, "rb") as f:
upload = requests.request(method, presigned["upload_url"], data=f, headers=hdrs)
# Step 3: Confirm upload
confirm = requests.post(
f"{BASE_URL}/uploads/confirm",
headers=headers,
json={"object_key": presigned["object_key"], "size_bytes": os.path.getsize(file_path)}
)
print(f"Success: {confirm.json()['upload_id']}")
return confirm.json()
elif response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 5))
print(f"Rate limited, waiting {retry_after} seconds...")
time.sleep(retry_after)
continue
elif response.status_code == 403:
error = response.json()['error']
print(f"Forbidden: {error['code']} - {error['message']}")
if error['code'] == 'USAGE_LIMIT_EXCEEDED':
print("Usage limit exceeded - check your plan")
return None
else:
error = response.json()['error']
print(f"Error: {error['code']} - {error['message']}")
return None
except requests.exceptions.RequestException as e:
print(f"Request failed (attempt {attempt + 1}/{max_retries}): {e}")
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff
print(f"Retrying in {wait_time} seconds...")
time.sleep(wait_time)
continue
raise