API v1  ·  Stable

quiXzoom API

Build on the world's camera network.
REST API  ·  Webhooks  ·  SDKs

Get API access View OpenAPI spec
Private beta · Available to approved partners

Quick Start

Everything you need to make your first API call in under five minutes.

Base URL
api.quixzoom.com/api/qz/v1
Auth
Bearer token (OAuth 2.0)
Format
application/json
TLS
Required (TLS 1.2+)
bash — List active missions
# List active missions
curl -s https://api.quixzoom.com/api/qz/v1/missions \
  -H "Authorization: Bearer YOUR_TOKEN" \
  | jq .
json — Example response
{
  "data": [
    {
      "id":         "mission_01jxk7t2q",
      "title":      "City infrastructure survey — Stockholm",
      "status":     "active",
      "submissions": 14,
      "created_at":  "2026-06-01T09:00:00Z"
    }
  ],
  "meta": { "total": 1, "page": 1 }
}

Core Endpoints

All endpoints are relative to https://api.quixzoom.com/api/qz/v1

Method Path Description
GET /missions List active missions
POST /missions Create a new mission
GET /missions/{id} Get mission details
GET /missions/{id}/submissions List submissions for mission
GET /submissions/{id} Get submission + images
GET /submissions/{id}/images Download geo-tagged images
POST /webhooks Register webhook endpoint
POST /auth/token Obtain access token

Webhooks

Receive real-time events when missions and submissions change state. Register your endpoint with POST /webhooks.

Events

mission.created New mission published
submission.received Zoomer submitted photos
submission.approved Submission passed QA
submission.rejected Submission failed QA checks
mission.completed All required coverage collected

Payload Example

json — submission.received payload
{
  "event":      "submission.received",
  "timestamp":  "2026-06-17T10:32:00Z",
  "data": {
    "submission_id": "sub_03xpq9r",
    "mission_id":    "mission_01jxk7t2q",
    "zoomer_id":    "usr_7m2n4p",
    "image_count":  6,
    "location": {
      "lat": 59.3293,
      "lng": 18.0686
    }
  }
}

Signature Verification

Every webhook request includes an X-QZ-Signature header — an HMAC-SHA256 hex digest of the raw request body signed with your webhook secret.

javascript — Verify signature
const crypto = require('crypto');

function verifySignature(rawBody, secret, header) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(header)
  );
}

Authentication

quiXzoom uses OAuth 2.0 client credentials flow. All API requests must include a valid Bearer token in the Authorization header.

bash — Obtain access token
curl -X POST https://api.quixzoom.com/api/qz/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type":    "client_credentials",
    "client_id":     "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "scope":         "missions:read submissions:read"
  }'
json — Token response
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "token_type":   "Bearer",
  "expires_in":   86400,
  "scope":        "missions:read submissions:read"
}

Scopes

missions:read
List and retrieve mission details
missions:write
Create and modify missions
submissions:read
Access submission data and images
webhooks:manage
Register and delete webhook endpoints
Token TTL: 24 hours (86 400 s). Store tokens securely; never expose them client-side. Rotate secrets immediately if compromised — contact enterprise@quixzoom.com.

Rate Limits

Limits apply per client credentials pair. Exceeding limits returns HTTP 429 with a Retry-After header.

1 000
requests / hour
60
requests / minute (burst)
429
HTTP status when exceeded

Response Headers

X-RateLimit-Limit Maximum requests allowed in the current window
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix timestamp when the window resets
Retry-After Seconds to wait before retrying (429 responses only)

SDKs & Examples

Official SDKs launching August 2026. Contact enterprise@quixzoom.com for early access.

JavaScript / TypeScript

Full type definitions, Node.js and browser compatible, Promise-based API.

npm install @quixzoom/sdk

August 2026
🐍

Python

Async/sync client, Pydantic models, supports Python 3.10+.

pip install quixzoom

August 2026
🔗

REST / cURL

Language-agnostic. Use any HTTP client. OpenAPI spec available for code generation.

curl + jq

Available now
javascript — Create a mission (SDK preview)
import { QuiXzoom } from '@quixzoom/sdk';

const client = new QuiXzoom({
  clientId:     'YOUR_CLIENT_ID',
  clientSecret: 'YOUR_CLIENT_SECRET',
});

const mission = await client.missions.create({
  title:       'Parking lot survey — Gothenburg',
  description: 'Count and classify parking spaces',
  bounds: {
    type:        'Polygon',
    coordinates: [[11.97, 57.70], [12.00, 57.72], /* ... */],
  },
  requiredImages: 50,
});

console.log(mission.id); // mission_01jxk...

Data Formats

All geo data follows the GeoJSON standard (RFC 7946). Images include full EXIF metadata.

📍 GeoJSON

Mission boundaries and submission locations follow RFC 7946. Coordinates are WGS 84 (EPSG:4326).

🖼 Image EXIF

Every image includes GPS coordinates, timestamp, device model, and orientation. EXIF is preserved in downloads.

📦 Bulk Export

Download a ZIP archive of all images in a mission plus a metadata.json index file.

json — GeoJSON submission location
{
  "type": "Feature",
  "geometry": {
    "type":        "Point",
    "coordinates": [18.0686, 59.3293]
  },
  "properties": {
    "submission_id": "sub_03xpq9r",
    "captured_at":   "2026-06-17T10:31:44Z",
    "altitude_m":    28.4,
    "accuracy_m":    3.1,
    "image_count":   6
  }
}
Private Beta

Ready to build?

The quiXzoom API is currently available to approved enterprise partners. Apply for access and our team will get back to you within one business day.