The doc Playground does not support file uploads: Please use the cURL, Python, or JavaScript code examples below to test.
Temporary storage: Uploaded images are stored for only 72 hours. After that, the image URL will expire. Use the image within this period or save it to your own storage service in time.
Important Change: For better performance and cost control, we no longer support passing base64 image data directly in generation APIs. Please use this API to upload images, get the URL, and then call the generation API.
Why upload images first?
- Performance Optimization - base64 encoding inflates data by 33%, uploading first significantly reduces request body size
- Reuse Images - Upload once, reuse the URL multiple times without redundant transfers
Workflow
sequenceDiagram
participant Client
participant OpenVeer
participant Storage
Client->>OpenVeer: POST /v1/uploads/images (Upload image file)
OpenVeer->>Storage: Save image
Storage-->>OpenVeer: Return storage path
OpenVeer-->>Client: Return image URL
Client->>OpenVeer: POST /v1/images/generations (Use image URL)Request example
curl --request POST \
--url https://api.openveer.com/v1/uploads/images \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/your/image.jpg'import requests
# Upload image
with open('image.jpg', 'rb') as f:
response = requests.post(
"https://api.openveer.com/v1/uploads/images",
headers={
"Authorization": "Bearer <token>"
},
files={
"file": f
}
)
result = response.json()
image_url = result['url']
print(f"Image URL: {image_url}")
# Use the uploaded image for generation
response = requests.post(
"https://api.openveer.com/v1/images/generations",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
},
json={
"model": "gemini-3-pro-image-preview",
"prompt": "Create a variation based on this image",
"image_urls": [{"url": image_url}]
}
)// Upload image
const formData = new FormData();
formData.append('file', fileInput.files[0]);
const uploadResponse = await fetch('https://api.openveer.com/v1/uploads/images', {
method: 'POST',
headers: {
'Authorization': 'Bearer <token>'
},
body: formData
});
const uploadResult = await uploadResponse.json();
const imageUrl = uploadResult.url;
console.log(`Image URL: ${imageUrl}`);
// Use the uploaded image for generation
const genResponse = await fetch('https://api.openveer.com/v1/images/generations', {
method: 'POST',
headers: {
'Authorization': 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gemini-3-pro-image-preview',
prompt: 'Create a variation based on this image',
image_urls: [{url: imageUrl}]
})
});Response example
{
"url": "https://upload.openveer.com/f/image/9990000123456-a1b2c3d4-photo.jpg",
"filename": "photo.jpg",
"content_type": "image/jpeg",
"bytes": 235680,
"created_at": 1743436800
}{
"error": {
"message": "missing or invalid file field: http: no such file",
"type": "invalid_request_error"
}
}{
"error": {
"message": "unsupported image type: application/pdf, allowed: jpeg, png, gif, webp",
"type": "invalid_request_error"
}
}{
"error": {
"message": "file size 25165824 exceeds maximum 20971520 bytes",
"type": "invalid_request_error"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded. Please try again later",
"type": "rate_limit_error"
}
}{
"error": {
"message": "failed to upload image",
"type": "server_error"
}
}Authorizations
Authorization stringAll APIs require Bearer Token authentication
Get API Key:
Visit API Key Management Page to get your API Key
Add to request headers:
Authorization: Bearer YOUR_API_KEYBody
file fileImage file
Supported formats: JPEG (.jpg, .jpeg), PNG (.png), WebP (.webp), GIF (.gif)
Maximum file size: 20MB
Response
url stringPublic access URL for the image, can be used directly in generation APIs (valid for 72 hours)
filename stringOriginal file name
content_type stringDetected MIME type, e.g. image/jpeg
bytes integerFile size in bytes
created_at integerUpload time as Unix timestamp (seconds)
Full Example: Image-to-Image Workflow
import requests
import time
API_KEY = "your-OpenVeer-key"
BASE_URL = "https://api.openveer.com"
# Step 1: Upload reference image
def upload_image(file_path):
with open(file_path, 'rb') as f:
response = requests.post(
f"{BASE_URL}/v1/uploads/images",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": f}
)
return response.json()['url']
# Step 2: Create generation task
def create_generation(image_url, prompt):
response = requests.post(
f"{BASE_URL}/v1/images/generations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "gemini-3-pro-image-preview",
"prompt": prompt,
"image_urls": [{"url": image_url}],
"size": "16:9"
}
)
return response.json()['id']
# Step 3: Poll task status
def wait_for_result(task_id):
while True:
response = requests.get(
f"{BASE_URL}/v1/images/generations/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
result = response.json()
if result['status'] == 'completed':
return result['url']
elif result['status'] == 'failed':
raise Exception(f"Generation failed: {result.get('fail_reason')}")
time.sleep(2)
# Execute workflow
image_url = upload_image("reference.jpg")
print(f"Image uploaded: {image_url}")
task_id = create_generation(image_url, "Transform this photo into Ghibli anime style")
print(f"Task created: {task_id}")
result_url = wait_for_result(task_id)
print(f"Generation complete: {result_url}")This documentation is built and hosted on Mintlify, a developer documentation platform.