API Access
Manage your API keys and integrate VisaPics into your applications
API Balance
Loading...
Current Rate
$0.50/photo
Your Tier
Base
Photos Available
0
Photos Processed
0
Active Keys
0
Rate Limit
1,000/hr
Your API Keys
API DocumentationLoading API keys...
Pay-As-You-Go Pricing
Your rate improves as you deposit more. Tier is based on lifetime deposits.
Base
$0.50
per photo
< $100 deposited
Starter
$0.40
per photo
20% off
$100+ deposited
Professional
$0.30
per photo
40% off
$250+ deposited
Enterprise
$0.20
per photo
60% off
$500+ deposited
API Reference
Authentication
All API requests require authentication via Bearer token:
Authorization: Bearer YOUR_API_KEY
/api/v1/specifications/{country_code}
Get document specifications
Returns all document types for a country with their spec_id.
Parameters
country_code
string, required
ISO 2-letter country code (us, gb, de, etc.)
Example Response
{
"specifications": [
{"id": 822, "name": "US Passport", "type": "passport"},
{"id": 821, "name": "US Visa", "type": "visa"}
]
}
/api/v1/photo/process
Process a photo
Upload and process a photo. Returns task_id for async processing.
Request Body (multipart/form-data)
photo
*
JPEG or PNG image file
spec_id
*
Document specification ID (get from /specifications endpoint)
output_format
string
"url" (default) or "base64"
Example Request (cURL)
curl -X POST "https://visapics.org/api/v1/photo/process" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "photo=@photo.jpg" \
-F "spec_id=822"
Response (202 Accepted)
{
"status": "processing",
"task_id": "abc123-def456-...",
"message": "Photo queued for processing"
}
/api/v1/task/{task_id}
Get processing result
Poll this endpoint to get the processing result.
States
PENDING
- In queue
PROCESSING
- Being processed
SUCCESS
- Completed
FAILURE
- Error occurred
Success Response
{
"success": true,
"data": {
"state": "SUCCESS",
"progress": 100,
"result": {
"specification": {
"country_code": "us",
"document_type": "US Passport"
},
"compliance": {
"overall_success": true,
"photo_size": "51x51mm",
"head_measurements": "25-35mm",
"resolution_dpi": 300,
"warnings": [],
"suitable_for_online": true,
"printable": true
},
"digital_photo_url": "/download/...",
"printable_photo_url": "/download_printable/..."
}
}
}
Error Response (Photo Failed)
{
"success": false,
"error": {
"code": "E400_PROCESSING",
"message": "Photo processing failed",
"failure_reasons": [{
"code": "NO_FACE_DETECTED",
"message": "No face detected in the photo",
"suggestion": "Upload a photo with a clearly visible face"
}],
"compliance_issues": ["Head size out of spec range"],
"warnings": []
}
}
/api/v1/billing/balance
Get account balance
{
"balance_usd": 25.50,
"photos_available": 51,
"tier": "Starter",
"rate_per_photo": 0.40
}
Failure Reason Codes
When photo processing fails, these codes indicate why:
NO_FACE_DETECTED
No face found in the uploaded photo
MULTIPLE_FACES
More than one face detected
HEAD_SIZE_INVALID
Head size cannot meet spec requirements
EYE_POSITION_INVALID
Eye position cannot be adjusted
LOW_RESOLUTION
Photo resolution too low
PROCESSING_FAILED
General processing error
Complete Code Examples
Full working examples with async polling:
import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://visapics.org/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def process_photo(photo_path, spec_id):
# Step 1: Upload photo
with open(photo_path, "rb") as f:
response = requests.post(
f"{BASE_URL}/photo/process",
headers=HEADERS,
files={"photo": f},
data={"spec_id": spec_id}
)
task_id = response.json()["task_id"]
print(f"Task created: {task_id}")
# Step 2: Poll for result
while True:
result = requests.get(
f"{BASE_URL}/task/{task_id}",
headers=HEADERS
).json()
if result["state"] == "SUCCESS":
return result["result"]
elif result["state"] == "FAILURE":
raise Exception(result.get("error", "Processing failed"))
time.sleep(1) # Poll every second
# Usage
result = process_photo("photo.jpg", spec_id=822)
print(f"Photo URL: {result['photo_url']}")
print(f"Printable: {result['printable_url']}")