openapi: 3.0.3 info: title: quiXzoom Developer API description: | Programmatically order, verify, and retrieve real-world geotagged photography. **Key capabilities:** - Order fresh photos of any physical location - AI-verified against your requirements - Recurring missions for ongoing monitoring - Structured metadata + optional Landvex AI analysis **Base URL:** `https://api.quixzoom.com/v1` **Authentication:** Bearer token in Authorization header version: 1.0.0 contact: name: quiXzoom Developer Support email: dev-support@quixzoom.com url: https://docs.quixzoom.com license: name: Landvex Inc Terms of Service url: https://www.quixzoom.com/terms/ servers: - url: https://api.quixzoom.com/v1 description: Production - url: https://api.sandbox.quixzoom.com/v1 description: Sandbox (test data, no real missions) security: - BearerAuth: [] paths: /orders: post: summary: Create a new photo order description: | Create an order for fresh photography at specified locations. The order is priced immediately and missions are dispatched once confirmed. **Example use cases:** - Municipal websites needing current photos of public facilities - Restaurant apps wanting real ambiance shots - Retail chains verifying storefront compliance - Event venues monitoring crowd levels operationId: createOrder tags: - Orders requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/OrderRequest' examples: museum-exteriors: summary: Museum exteriors — monthly recurring value: client_reference: "malmo-museums-2026" category: "cultural_exterior" description: "Exterior photos of all museums in Malmö municipality" locations: - location_id: "loc_001" name: "Malmö Konstmuseum" coordinates: lat: 55.6050 lng: 13.0038 requirements: angles: ["front", "entrance"] time_of_day: "daylight" delivery: format: "structured_json" include_metadata: true include_ai_analysis: true webhook_url: "https://api.malmocity.se/quixzoom/webhook" recurring: enabled: true frequency: "monthly" budget: max_total: 5000.00 currency: "USD" beach-status: summary: Daily beach status monitoring value: client_reference: "malmo-beaches-summer" category: "beach_facility_status" locations: - location_id: "beach_001" name: "Ribersborgsstranden" coordinates: lat: 55.6050 lng: 12.9780 requirements: angles: ["overview", "water_quality_flag", "facilities"] time_of_day: "midday" recurring: enabled: true frequency: "daily" season: "summer_only" responses: '201': description: Order created successfully content: application/json: schema: $ref: '#/components/schemas/OrderResponse' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '402': description: Payment required — budget insufficient content: application/json: schema: $ref: '#/components/schemas/Error' '422': description: Location unserviceable content: application/json: schema: $ref: '#/components/schemas/Error' get: summary: List orders description: Retrieve all orders for your account with optional filtering operationId: listOrders tags: - Orders parameters: - name: status in: query schema: type: string enum: [pending, confirmed, in_progress, completed, cancelled] - name: category in: query schema: type: string - name: recurring in: query schema: type: boolean - name: limit in: query schema: type: integer default: 20 maximum: 100 - name: offset in: query schema: type: integer default: 0 responses: '200': description: List of orders content: application/json: schema: type: object properties: orders: type: array items: $ref: '#/components/schemas/OrderSummary' total: type: integer limit: type: integer offset: type: integer /orders/{order_id}: get: summary: Get order details description: Retrieve full order status, progress, and delivery information operationId: getOrder tags: - Orders parameters: - name: order_id in: path required: true schema: type: string pattern: '^ord_[a-zA-Z0-9]+$' responses: '200': description: Order details content: application/json: schema: $ref: '#/components/schemas/OrderDetail' '404': description: Order not found patch: summary: Update order description: | Modify an active order. Supported changes: - Add/remove locations - Update requirements - Pause/resume recurring - Update webhook URL operationId: updateOrder tags: - Orders parameters: - name: order_id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/OrderUpdate' responses: '200': description: Order updated '400': description: Invalid update '409': description: Cannot modify — order already completed delete: summary: Cancel order description: Cancel order and stop any recurring missions operationId: cancelOrder tags: - Orders parameters: - name: order_id in: path required: true schema: type: string responses: '200': description: Order cancelled '404': description: Order not found /orders/{order_id}/confirm: post: summary: Confirm and pay for order description: | Confirm the order quote and initiate payment. Missions are dispatched immediately after payment confirmation. operationId: confirmOrder tags: - Orders parameters: - name: order_id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object properties: payment_method: type: string enum: [card, invoice, qz_tokens] description: Payment method responses: '200': description: Order confirmed, missions dispatched '402': description: Payment failed /missions/{mission_id}: get: summary: Get mission details description: Retrieve mission status, photos, and verification results operationId: getMission tags: - Missions parameters: - name: mission_id in: path required: true schema: type: string pattern: '^mis_[a-zA-Z0-9]+$' responses: '200': description: Mission details content: application/json: schema: $ref: '#/components/schemas/MissionDetail' /photos: get: summary: List photos description: Retrieve photos with filtering by order, mission, status, angle operationId: listPhotos tags: - Photos parameters: - name: order_id in: query schema: type: string - name: mission_id in: query schema: type: string - name: status in: query schema: type: string enum: [pending, verified, rejected, approved] - name: angle in: query schema: type: string - name: limit in: query schema: type: integer default: 20 maximum: 100 - name: offset in: query schema: type: integer default: 0 responses: '200': description: List of photos content: application/json: schema: type: object properties: photos: type: array items: $ref: '#/components/schemas/Photo' total: type: integer /photos/{photo_id}: get: summary: Get photo metadata description: Retrieve photo metadata, URLs, and AI analysis operationId: getPhoto tags: - Photos parameters: - name: photo_id in: path required: true schema: type: string pattern: '^img_[a-zA-Z0-9]+$' responses: '200': description: Photo metadata content: application/json: schema: $ref: '#/components/schemas/Photo' /photos/{photo_id}/download: get: summary: Download original photo description: | Get a signed URL to download the original resolution photo. URL expires after 1 hour. operationId: downloadPhoto tags: - Photos parameters: - name: photo_id in: path required: true schema: type: string responses: '200': description: Signed download URL content: application/json: schema: type: object properties: download_url: type: string format: uri expires_at: type: string format: date-time /analytics/orders/{order_id}/changes: get: summary: Detect changes between photo sets description: | Compare photos from different time periods to detect changes. Only available for recurring missions with 2+ completed cycles. operationId: getChanges tags: - Analytics parameters: - name: order_id in: path required: true schema: type: string - name: period_start in: query schema: type: string format: date - name: period_end in: query schema: type: string format: date responses: '200': description: Change detection results content: application/json: schema: $ref: '#/components/schemas/ChangeDetectionResult' /analytics/orders/{order_id}/crowd-density: get: summary: Crowd density analysis description: Analyze crowd density trends over time operationId: getCrowdDensity tags: - Analytics parameters: - name: order_id in: path required: true schema: type: string responses: '200': description: Crowd density data content: application/json: schema: type: object properties: location_id: type: string location_name: type: string measurements: type: array items: type: object properties: date: type: string format: date density_level: type: string enum: [empty, low, moderate, high, very_high] estimated_count: type: integer confidence: type: number minimum: 0 maximum: 1 /analytics/orders/{order_id}/sentiment: get: summary: Sentiment analysis description: Analyze emotional tone and engagement from photos operationId: getSentiment tags: - Analytics parameters: - name: order_id in: path required: true schema: type: string responses: '200': description: Sentiment analysis results content: application/json: schema: type: object properties: overall_mood: type: string enum: [very_negative, negative, neutral, positive, very_positive] engagement_level: type: string enum: [low, moderate, high] atmosphere: type: string trends: type: array items: type: object properties: date: type: string format: date mood_score: type: number minimum: 0 maximum: 1 components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: API key description: | Your quiXzoom API key. Get one at https://www.quixzoom.com/developers Example: `Authorization: Bearer qz_live_abc123...` schemas: OrderRequest: type: object required: - category - locations properties: client_reference: type: string description: Your internal reference ID example: "malmo-museums-2026" category: type: string description: Photo category enum: - cultural_exterior - cultural_interior - restaurant_ambiance - retail_compliance - event_venue_status - beach_facility_status - park_recreation - infrastructure_condition - custom description: type: string description: Detailed description of what you need example: "Exterior photos of all museums in Malmö municipality" locations: type: array minItems: 1 maxItems: 1000 items: $ref: '#/components/schemas/Location' requirements: $ref: '#/components/schemas/PhotoRequirements' delivery: $ref: '#/components/schemas/DeliveryConfig' recurring: $ref: '#/components/schemas/RecurringConfig' budget: $ref: '#/components/schemas/BudgetConfig' timeline: $ref: '#/components/schemas/TimelineConfig' Location: type: object required: - coordinates properties: location_id: type: string description: Your internal location ID name: type: string description: Human-readable location name example: "Malmö Konstmuseum" address: type: string example: "S:t Johannesgatan 7, 211 46 Malmö" coordinates: type: object required: - lat - lng properties: lat: type: number minimum: -90 maximum: 90 example: 55.6050 lng: type: number minimum: -180 maximum: 180 example: 13.0038 requirements: $ref: '#/components/schemas/PhotoRequirements' PhotoRequirements: type: object properties: angles: type: array items: type: string enum: [front, back, side, entrance, interior, overview, detail, custom] example: ["front", "entrance"] minimum_resolution: type: string pattern: '^\d+x\d+$' example: "1920x1080" time_of_day: type: string enum: [dawn, morning, midday, afternoon, evening, night, any] weather: type: string enum: [sunny, cloudy, any] avoid: type: array items: type: string example: ["construction scaffolding", "closed shutters"] brand_match: type: string description: Verify specific brand/logo is visible example: "ICA" minimum_crowd: type: string enum: [empty, low, moderate, high, any] description: Minimum crowd level for ambiance shots DeliveryConfig: type: object properties: format: type: string enum: [structured_json, raw_urls, zip_archive] default: structured_json include_metadata: type: boolean default: true include_ai_analysis: type: boolean default: false webhook_url: type: string format: uri description: URL to receive webhook events RecurringConfig: type: object properties: enabled: type: boolean default: false frequency: type: string enum: [daily, weekly, bi_weekly, monthly, quarterly] day_of_week: type: integer minimum: 1 maximum: 7 description: For weekly frequency (1=Monday) day_of_month: type: integer minimum: 1 maximum: 31 time_window: type: string pattern: '^\d{2}:\d{2}-\d{2}:\d{2}$' example: "09:00-17:00" seasonal_adjustments: type: boolean default: false season: type: string enum: [year_round, summer_only, winter_only] notify_before_capture: type: integer description: Hours before capture to notify example: 24 pause_conditions: type: object properties: weather_extreme: type: boolean holiday_override: type: array items: type: string format: date BudgetConfig: type: object properties: max_total: type: number minimum: 0 currency: type: string default: USD per_photo_max: type: number minimum: 0 TimelineConfig: type: object properties: desired_completion: type: string format: date-time flexible: type: boolean default: false OrderResponse: type: object properties: order_id: type: string example: "ord_7f8a9b2c" status: type: string enum: [accepted, pending_confirmation] estimated_price: $ref: '#/components/schemas/PriceEstimate' estimated_completion: type: string format: date-time missions_created: type: integer webhook_secret: type: string confirmation_url: type: string format: uri PriceEstimate: type: object properties: total: type: number example: 2840.00 currency: type: string example: "USD" breakdown: type: object properties: base_mission_fee: type: number per_location: type: number ai_verification: type: number recurring_discount: type: number OrderSummary: type: object properties: order_id: type: string client_reference: type: string status: type: string category: type: string created_at: type: string format: date-time total_locations: type: integer photos_delivered: type: integer recurring: type: boolean OrderDetail: allOf: - $ref: '#/components/schemas/OrderSummary' - type: object properties: progress: type: object properties: total_missions: type: integer completed: type: integer in_progress: type: integer pending: type: integer failed: type: integer photos_delivered: type: integer photos_pending: type: integer next_recurring_date: type: string format: date-time total_spent: type: number budget_remaining: type: number locations: type: array items: $ref: '#/components/schemas/Location' OrderUpdate: type: object properties: locations: type: array items: $ref: '#/components/schemas/Location' requirements: $ref: '#/components/schemas/PhotoRequirements' recurring: $ref: '#/components/schemas/RecurringConfig' webhook_url: type: string format: uri status: type: string enum: [paused, active] MissionDetail: type: object properties: mission_id: type: string order_id: type: string status: type: string enum: [pending, assigned, in_progress, completed, failed, cancelled] location: $ref: '#/components/schemas/Location' zoomer: type: object properties: zoomer_id: type: string rating: type: number missions_completed: type: integer timeline: type: object properties: assigned_at: type: string format: date-time completed_at: type: string format: date-time verified_at: type: string format: date-time photos: type: array items: $ref: '#/components/schemas/Photo' Photo: type: object properties: photo_id: type: string url: type: string format: uri thumbnail: type: string format: uri angle: type: string resolution: type: string file_size_mb: type: number format: type: string metadata: type: object properties: captured_at: type: string format: date-time gps: type: object properties: lat: type: number lng: type: number accuracy_m: type: number device: type: string weather: type: object properties: condition: type: string temp_c: type: number verification: type: object properties: status: type: string enum: [pending, approved, rejected] ai_checks: type: object additionalProperties: type: object properties: score: type: number passed: type: boolean reviewed_by: type: string nullable: true ai_analysis: type: object properties: amos_vision: type: object properties: object_detection: type: array items: type: string scene_classification: type: string condition_assessment: type: string amos_change: type: object properties: changes_since_last: type: array items: type: string change_confidence: type: number amos_risk: type: object properties: safety_score: type: number accessibility_score: type: number maintenance_urgency: type: string amos_sentiment: type: object properties: crowd_mood: type: string engagement_level: type: string atmosphere: type: string ChangeDetectionResult: type: object properties: comparison_period: type: string changes_detected: type: array items: type: object properties: location_id: type: string location_name: type: string change_type: type: string enum: [new_construction, renovation, seasonal_variation, damage, new_signage, removed_object, crowd_change, other] confidence: type: number description: type: string photos: type: object properties: before: type: string after: type: string Error: type: object properties: error: type: object properties: code: type: string message: type: string details: type: object suggested_action: type: string