- New /developers/ page with API docs, SDKs, pricing, use cases - OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics - Case study: Glasskiosken i Flatenbadet — complete ROI analysis - Updated /order/ with recurring missions and frequency dropdown
24 KiB
quiXzoom Developer API — Product Specification
Version: 1.0.0
Status: Draft
Last updated: 2026-07-14
Owner: Landvex Inc / quiXzoom Platform Team
Executive Summary
quiXzoom Developer API enables software developers, agencies, and platform builders to programmatically order, verify, and retrieve real-world geotagged photography. Unlike stock photo APIs that serve stale archives, quiXzoom dispatches verified field contributors ("Zoomers") to capture fresh visual data on demand.
The core value proposition: Any visual information gap in a digital product can be filled with fresh, verified, structured photography — ordered via REST API and delivered within hours.
The Problem We Solve
Scenario: Malmö Stad Website Redesign
A marketing agency wins a contract to rebuild Malmö Stad's tourism website. The design mockups need real photography of:
- All 15 museums (exterior + current exhibitions)
- 40 public parks (seasonal conditions, crowd levels)
- 8 beaches (water quality flags, facility status)
- 25 restaurants in the old town (ambiance, outdoor seating)
Traditional approach:
- City sends archive photos from 2019 (outdated, wrong seasons)
- Agency hires a media crew for 3 days (€8,000+, scheduling hell)
- Photos are staged, not representative of actual conditions
- Website launches with stale visuals, requires redo in 6 months
quiXzoom approach:
# Order all museum exteriors — fresh, current, verified
POST /v1/missions
{
"category": "cultural_exterior",
"locations": [...15 museum coordinates...],
"requirements": {
"angles": ["front", "entrance_signage"],
"time_of_day": "daylight",
"weather": "any"
},
"delivery_format": "api_json",
"recurring": {
"frequency": "monthly",
"seasonal_adjustments": true
}
}
# Response: mission_id, estimated_completion, price_quote
# Poll for completion
GET /v1/missions/{mission_id}/status
# → "completed" — photos ready
# Retrieve structured data
GET /v1/missions/{mission_id}/photos
# → JSON with URLs, metadata, verification_status, AI_analysis
Result: €200, 4-hour turnaround, photos verified by AI against requirements, auto-updating every month.
Product Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ DEVELOPER APPLICATION │
│ (Website, App, Dashboard, CMS, Digital Signage, AI Training Pipeline) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼ REST API
┌─────────────────────────────────────────────────────────────────────────┐
│ quiXzoom DEVELOPER API │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Orders │ │ Missions │ │ Photos │ │ Analytics │ │
│ │ /orders │ │ /missions │ │ /photos │ │ /analytics │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Order │ │ Order │ │ Order │
│ Routing │ │ Matching │ │ Pricing │
│ Engine │ │ Engine │ │ Engine │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└───────────────┼───────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ ZOOMER NETWORK │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Zoomer │ │ Zoomer │ │ Zoomer │ │ Zoomer │ │ Zoomer │ ... │
│ │ #4721 │ │ #4722 │ │ #4723 │ │ #4724 │ │ #4725 │ │
│ │ Malmö │ │ Göteborg│ │ Stockholm││ Uppsala│ │ Lund │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Photo │ │ GPS │ │ Quality │
│ Capture │ │ Verify │ │ Verify │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└───────────────┼───────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ AI VERIFICATION PIPELINE │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Object │ │ Angle │ │ Condition │ │ Geo │ │
│ │ Detection │ │ Match │ │ Check │ │ Validate │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Crowd │ │ Weather │ │ Time │ │ Brand │ │
│ │ Density │ │ Detect │ │ Verify │ │ Match │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ DELIVERY & ANALYTICS │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Raw Photo │ │ Metadata │ │ Landvex │ │ Change │ │
│ │ CDN │ │ JSON │ │ Analysis │ │ Detection │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
API Endpoints (v1)
1. Orders — Create and manage photo orders
POST /v1/orders
Create a new photo order.
Request:
{
"order_id": "ord_7f8a9b2c",
"client_reference": "malmo-stad-v2-2026",
"category": "cultural_exterior",
"description": "Exterior photos of all museums in Malmö municipality. Front facade + entrance signage. Daylight, any weather.",
"locations": [
{
"location_id": "loc_001",
"name": "Malmö Konstmuseum",
"address": "S:t Johannesgatan 7, 211 46 Malmö",
"coordinates": {"lat": 55.6050, "lng": 13.0038},
"requirements": {
"angles": ["front", "entrance"],
"minimum_resolution": "1920x1080",
"time_of_day": "daylight",
"avoid": ["construction scaffolding", "closed shutters"]
}
}
],
"delivery": {
"format": "structured_json",
"include_metadata": true,
"include_ai_analysis": true,
"webhook_url": "https://api.malmocity.se/quixzoom/webhook"
},
"recurring": {
"enabled": true,
"frequency": "monthly",
"seasonal_adjustments": true,
"notify_before_capture": 24
},
"budget": {
"max_total": 5000.00,
"currency": "USD",
"per_photo_max": 5.00
},
"timeline": {
"desired_completion": "2026-07-20T23:59:59Z",
"flexible": false
}
}
Response:
{
"order_id": "ord_7f8a9b2c",
"status": "accepted",
"estimated_price": {
"total": 2840.00,
"currency": "USD",
"breakdown": {
"base_mission_fee": 15.00,
"per_location": 8.00,
"ai_verification": 2.00,
"recurring_discount": -0.10
}
},
"estimated_completion": "2026-07-18T14:00:00Z",
"missions_created": 15,
"webhook_secret": "whsec_...",
"confirmation_url": "https://api.quixzoom.com/v1/orders/ord_7f8a9b2c/confirm"
}
GET /v1/orders/{order_id}
Retrieve order status and details.
Response:
{
"order_id": "ord_7f8a9b2c",
"status": "in_progress",
"progress": {
"total_missions": 15,
"completed": 7,
"in_progress": 5,
"pending": 3,
"failed": 0
},
"photos_delivered": 42,
"photos_pending": 18,
"next_recurring_date": "2026-08-14T00:00:00Z",
"total_spent": 1320.00,
"budget_remaining": 1680.00
}
PATCH /v1/orders/{order_id}
Modify an active order (add locations, change requirements, pause recurring).
DELETE /v1/orders/{order_id}
Cancel an order and stop any recurring missions.
2. Missions — Individual photo capture tasks
GET /v1/missions/{mission_id}
Get mission details and current status.
Response:
{
"mission_id": "mis_a3b4c5d6",
"order_id": "ord_7f8a9b2c",
"status": "completed",
"location": {
"name": "Malmö Konstmuseum",
"coordinates": {"lat": 55.6050, "lng": 13.0038}
},
"zoomer": {
"zoomer_id": "zmr_4721",
"rating": 4.8,
"missions_completed": 342
},
"timeline": {
"assigned_at": "2026-07-15T09:23:00Z",
"completed_at": "2026-07-15T11:45:00Z",
"verified_at": "2026-07-15T12:03:00Z"
},
"photos": [
{
"photo_id": "img_x7y8z9",
"url": "https://cdn.quixzoom.com/v1/photos/img_x7y8z9.jpg",
"thumbnail": "https://cdn.quixzoom.com/v1/photos/img_x7y8z9_thumb.jpg",
"angle": "front",
"resolution": "4032x3024",
"file_size_mb": 4.2,
"format": "jpeg",
"metadata": {
"captured_at": "2026-07-15T11:42:18Z",
"gps": {"lat": 55.6051, "lng": 13.0039, "accuracy_m": 3.2},
"device": "iPhone15,2",
"weather": {"condition": "partly_cloudy", "temp_c": 22}
},
"verification": {
"status": "approved",
"ai_checks": {
"location_match": {"score": 0.98, "passed": true},
"angle_match": {"score": 0.94, "passed": true},
"quality_check": {"score": 0.91, "passed": true},
"obstruction_check": {"score": 0.99, "passed": true}
},
"reviewed_by": null
}
}
]
}
3. Photos — Retrieve and manage delivered photos
GET /v1/photos/{photo_id}
Get photo metadata and URLs.
GET /v1/photos?order_id={order_id}&angle=front&status=approved
List photos with filtering.
GET /v1/photos/{photo_id}/download
Download original resolution photo (signed URL, expires in 1 hour).
4. Analytics — Insights from photo data
GET /v1/analytics/orders/{order_id}/changes
Detect changes between photo sets (for recurring missions).
Response:
{
"comparison_period": "2026-06-15 to 2026-07-15",
"changes_detected": [
{
"location_id": "loc_003",
"location_name": "Teknikens och Sjöfartens Hus",
"change_type": "new_construction",
"confidence": 0.87,
"description": "Scaffolding erected on east facade. Entrance temporarily relocated.",
"photos": {
"before": "img_abc123",
"after": "img_def456"
}
},
{
"location_id": "loc_007",
"location_name": "Moderna Museet Malmö",
"change_type": "seasonal_variation",
"confidence": 0.95,
"description": "Outdoor exhibition space now active. 23 visitors visible (vs 0 in June).",
"photos": {
"before": "img_ghi789",
"after": "img_jkl012"
}
}
]
}
GET /v1/analytics/orders/{order_id}/crowd-density
Crowd density analysis over time.
GET /v1/analytics/orders/{order_id}/sentiment
Emotional/sentiment analysis from facial expressions and body language.
AI Verification Pipeline
Every photo passes through multi-layer AI verification before delivery:
| Check | Description | Threshold |
|---|---|---|
| Location Match | GPS coordinates within 50m of target | ≥ 95% |
| Angle Match | Photo angle matches requirement (front/side/etc) | ≥ 90% |
| Quality Check | Resolution, blur, exposure, noise | ≥ 85% |
| Obstruction Check | No major obstructions (vehicles, scaffolding) | ≥ 95% |
| Object Detection | Required objects present (signage, building) | ≥ 90% |
| Time Verify | Photo taken within requested time window | ≥ 99% |
| Weather Detect | Actual weather conditions logged | Always |
| Brand Match | Logo/signage matches reference (if specified) | ≥ 85% |
Failed verification flow:
- Photo fails one or more checks
- Zoomer notified with specific failure reason
- Zoomer can retake within 2 hours (no extra charge)
- If still failing, mission reassigned to new Zoomer
- Client notified of delay with new ETA
Recurring Missions
Configuration
{
"recurring": {
"enabled": true,
"frequency": "monthly",
"day_of_month": 15,
"seasonal_adjustments": true,
"notify_before_capture": 24,
"pause_conditions": {
"weather_extreme": true,
"holiday_override": ["2026-12-25", "2026-12-26"]
}
}
}
Seasonal Adjustments
| Season | Adjustment | Example |
|---|---|---|
| Spring | Earlier capture time | Parks photographed at 10:00 (flowers blooming) |
| Summer | Extended hours | Beach photos at 18:00 (peak activity) |
| Autumn | Weather contingency | Indoor fallback for rain-sensitive locations |
| Winter | Reduced frequency | Monthly → Bi-monthly for outdoor venues |
Use Cases & Examples
1. Municipal Website (Malmö Stad)
// Initialize client
const quixzoom = new QuixzoomClient({
apiKey: process.env.QUIXZOOM_API_KEY,
environment: 'production'
});
// Order all museum exteriors — monthly refresh
const order = await quixzoom.orders.create({
client_reference: 'malmo-museums-2026',
category: 'cultural_exterior',
locations: museums.map(m => ({
name: m.name,
coordinates: m.coordinates,
requirements: {
angles: ['front', 'entrance'],
avoid: ['construction']
}
})),
recurring: {
frequency: 'monthly',
seasonal_adjustments: true
},
delivery: {
webhook_url: 'https://api.malmocity.se/photos/update'
}
});
// Webhook receives:
{
event: 'photos.delivered',
order_id: 'ord_7f8a9b2c',
mission_id: 'mis_a3b4c5d6',
photos: [{
url: 'https://cdn.quixzoom.com/...',
metadata: { ... },
ai_analysis: {
crowd_density: 'low',
weather: 'sunny',
condition: 'well_maintained'
}
}]
}
2. Restaurant Discovery App
# Python SDK example
from quixzoom import QuixzoomClient
client = QuixzoomClient(api_key="qz_live_...")
# Weekly ambiance updates for trending restaurants
order = client.orders.create(
category="restaurant_ambiance",
locations=[
{"name": "Lilla Kafferosteriet", "coordinates": (55.605, 13.0038)},
{"name": "Bullen", "coordinates": (55.603, 13.001)}
],
requirements={
"angles": ["interior", "outdoor_seating", "bar_area"],
"time_of_day": "evening",
"minimum_crowd": "moderate" # Capture real vibe
},
recurring={
"frequency": "weekly",
"day_of_week": "friday",
"time_window": "18:00-21:00"
}
)
# Use crowd density + sentiment for "vibe score"
for photo in order.photos:
vibe_score = (
photo.ai_analysis.crowd_density * 0.4 +
photo.ai_analysis.sentiment_positive * 0.3 +
photo.ai_analysis.ambiance_lighting * 0.3
)
update_restaurant_vibe(photo.location_id, vibe_score)
3. Event Venue Monitoring
# Real-time venue status for event planners
curl -X POST https://api.quixzoom.com/v1/orders \
-H "Authorization: Bearer $QUIXZOOM_API_KEY" \
-d '{
"category": "event_venue_status",
"locations": [
{"name": "Malmö Arena", "coordinates": {"lat": 55.563, "lng": 12.976}}
],
"requirements": {
"angles": ["entrance_queue", "parking_lot", "main_entrance"],
"time_of_day": "evening",
"recurring": {
"frequency": "daily",
"time_window": "19:00-23:00",
"event_nights_only": true
}
}
}'
# Returns real-time crowd estimates for app users:
# "Malmö Arena: Moderate crowd (450 people), 5 min queue, parking 80% full"
4. Retail Chain Compliance
// Monthly storefront audits for franchise compliance
const order = await quixzoom.orders.create({
client_reference: 'ica-stores-july-2026',
category: 'retail_compliance',
locations: icaStores.map(store => ({
name: store.name,
coordinates: store.coordinates,
requirements: {
angles: ['storefront', 'opening_hours_sign', 'promotional_display'],
brand_match: 'ICA', // AI verifies ICA logo present
obstruction_check: true
}
})),
recurring: {
frequency: 'monthly',
deliver_before: '5th of month' // For management reports
}
});
// Automated compliance report:
// - Store #234: Compliant ✓
// - Store #235: Non-compliant ✗ (promotional display missing)
// - Store #236: Non-compliant ✗ (opening hours sign obscured)
5. Beach & Outdoor Facility Status
# Daily beach status for summer season
order = client.orders.create(
category="beach_facility_status",
locations=malmo_beaches,
requirements={
"angles": ["overview", "water_quality_flag", "lifeguard_tower", "facilities"],
"time_of_day": "midday"
},
recurring={
"frequency": "daily",
"season": "summer_only", # June 1 - August 31
"weather_dependent": True # Skip if thunderstorm
}
)
# AI analysis delivers:
# - Water quality flag color (blue/yellow/red)
# - Crowd density estimate
# - Lifeguard presence (yes/no)
# - Facility condition (clean/moderate/poor)
Integration with Landvex Intelligence
When include_ai_analysis: true is set, photos are automatically processed through Landvex AI engines:
{
"ai_analysis": {
"amos_vision": {
"object_detection": ["building", "signage", "people", "vehicles"],
"scene_classification": "urban_cultural",
"condition_assessment": "well_maintained"
},
"amos_change": {
"changes_since_last": ["new_banner", "repainted_facade"],
"change_confidence": 0.89
},
"amos_risk": {
"safety_score": 0.94,
"accessibility_score": 0.87,
"maintenance_urgency": "low"
},
"amos_sentiment": {
"crowd_mood": "positive",
"engagement_level": "moderate",
"atmosphere": "welcoming"
}
}
}
Pricing
| Tier | Volume | Per Photo | Features |
|---|---|---|---|
| Developer | 0-1,000 photos/month | $3.00 | API access, basic verification, 48h delivery |
| Business | 1,000-10,000 photos/month | $2.00 | Priority delivery, advanced AI analysis, webhooks |
| Enterprise | 10,000+ photos/month | Custom | SLA guarantees, dedicated support, custom AI models |
Recurring mission discount: 10% off for monthly, 15% for weekly.
SDKs & Libraries
| Language | Package | Status |
|---|---|---|
| JavaScript/TypeScript | @quixzoom/sdk |
Available |
| Python | quixzoom-python |
Available |
| Go | github.com/quixzoom/go-sdk |
Beta |
| Ruby | quixzoom-ruby |
Coming Q3 2026 |
| PHP | quixzoom-php |
Coming Q3 2026 |
Webhooks
Events delivered to your endpoint:
| Event | Description |
|---|---|
order.created |
Order accepted and priced |
order.confirmed |
Payment received, missions dispatched |
mission.assigned |
Zoomer assigned to location |
mission.completed |
Photos captured, pending verification |
photos.verified |
AI verification passed |
photos.delivered |
Photos ready for download |
photos.rejected |
Verification failed, being retaken |
order.completed |
All missions complete |
recurring.triggered |
New recurring cycle started |
Error Handling
{
"error": {
"code": "location_unserviceable",
"message": "No Zoomers available within 50km of specified coordinates",
"details": {
"coordinates": {"lat": 67.8558, "lng": 20.2253},
"nearest_zoomer": {"distance_km": 127, "location": "Luleå"}
},
"suggested_action": "Increase budget for remote area surcharge or choose 'flexible' timeline"
}
}
Rate Limits
| Tier | Requests/minute | Concurrent orders |
|---|---|---|
| Developer | 60 | 5 |
| Business | 300 | 25 |
| Enterprise | 2000 | Unlimited |
Security
- All API requests require
Authorization: Bearer {api_key} - Webhook signatures verified with HMAC-SHA256
- Photo URLs are signed and expire after 1 hour
- GDPR compliant — all photos include consent metadata
- SOC 2 Type II certified infrastructure
Support
- Documentation: https://docs.quixzoom.com
- API Status: https://status.quixzoom.com
- Support Email: dev-support@quixzoom.com
- Slack Community: https://quixzoom.dev/slack
Changelog
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-07-14 | Initial release — Orders, Missions, Photos, Analytics endpoints |
quiXzoom Developer API is a product of Landvex Inc. All rights reserved.