openapi: 3.0.0 info: title: Landvex / quiXzoom API description: | Infrastructure Object Model (IOM) API for urban intelligence. ## Authentication All endpoints require Bearer token authentication. ## Rate Limiting - Free tier: 100 requests/minute - Basic tier: 1000 requests/minute - Professional tier: 10,000 requests/minute - Enterprise tier: Unlimited version: 1.0.0 contact: name: Landvex Support email: api@landvex.com url: https://landvex.com/support license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.landvex.com/v1 description: Production - url: https://api.quixzoom.com/v1 description: quiXzoom - url: https://localhost:8000 description: Local Development security: - BearerAuth: [] paths: # === Health === /health: get: summary: Health check description: Check API status and component health security: [] responses: '200': description: API is healthy content: application/json: schema: $ref: '#/components/schemas/HealthResponse' example: status: healthy version: "1.0.0" components: goid: ok taxonomy: ok visual_geolocation: ok # === Auth === /auth/register: post: summary: Register new user description: Create a new user account security: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterRequest' responses: '200': description: User registered successfully content: application/json: schema: $ref: '#/components/schemas/AuthResponse' /auth/login: post: summary: Login description: Authenticate and get access token security: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LoginRequest' responses: '200': description: Login successful content: application/json: schema: $ref: '#/components/schemas/AuthResponse' # === Visual Geolocation === /visual-geolocation/analyze: post: summary: Analyze image description: | Extract evidence from image and estimate geolocation. Returns: - Position estimate with confidence - Evidence package (7 layers) - Map matches - Similar images requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AnalyzeRequest' multipart/form-data: schema: type: object properties: image: type: string format: binary description: Image file (JPEG/PNG) image_id: type: string description: Optional image identifier responses: '200': description: Analysis complete content: application/json: schema: $ref: '#/components/schemas/AnalyzeResponse' /visual-geolocation/batch: post: summary: Batch analyze images description: Analyze multiple images in one request requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BatchAnalyzeRequest' responses: '200': description: Batch analysis complete content: application/json: schema: $ref: '#/components/schemas/BatchAnalyzeResponse' /visual-geolocation/temporal: post: summary: Temporal analysis description: Compare observations over time requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TemporalRequest' responses: '200': description: Temporal analysis complete content: application/json: schema: $ref: '#/components/schemas/TemporalResponse' # === Taxonomy === /taxonomy/domains: get: summary: List domains description: Get all IOM domains responses: '200': description: List of domains content: application/json: schema: type: array items: $ref: '#/components/schemas/Domain' /taxonomy/systems: get: summary: List systems description: Get all systems for a domain parameters: - name: domain in: query required: true schema: type: string responses: '200': description: List of systems content: application/json: schema: type: array items: $ref: '#/components/schemas/System' # === GOID === /goid/generate: post: summary: Generate GOID description: Generate a new Global Object Identifier requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GOIDGenerateRequest' responses: '200': description: GOID generated content: application/json: schema: $ref: '#/components/schemas/GOIDResponse' /goid/validate/{goid}: get: summary: Validate GOID description: Validate a GOID format parameters: - name: goid in: path required: true schema: type: string responses: '200': description: Validation result content: application/json: schema: $ref: '#/components/schemas/GOIDValidationResponse' # === Observations === /observations: get: summary: List observations description: Get observations with filtering parameters: - name: lat in: query schema: type: number - name: lng in: query schema: type: number - name: radius in: query schema: type: number default: 1000 - name: limit in: query schema: type: integer default: 100 responses: '200': description: List of observations content: application/json: schema: type: array items: $ref: '#/components/schemas/Observation' post: summary: Create observation description: Submit a new observation requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ObservationCreate' responses: '201': description: Observation created content: application/json: schema: $ref: '#/components/schemas/Observation' /observations/{id}: get: summary: Get observation description: Get a specific observation by ID parameters: - name: id in: path required: true schema: type: string responses: '200': description: Observation details content: application/json: schema: $ref: '#/components/schemas/Observation' # === Reality Signals === /signals: get: summary: Get signals description: Get reality signals for a location parameters: - name: lat in: query required: true schema: type: number - name: lng in: query required: true schema: type: number - name: type in: query schema: type: string responses: '200': description: Reality signals content: application/json: schema: $ref: '#/components/schemas/SignalsResponse' # === Indexes === /indexes/rgi: get: summary: Calculate RGI description: Calculate Reality Gap Index for location parameters: - name: lat in: query required: true schema: type: number - name: lng in: query required: true schema: type: number responses: '200': description: RGI score content: application/json: schema: $ref: '#/components/schemas/RGIResponse' /indexes/umi: get: summary: Calculate UMI description: Calculate Urban Morphology Index parameters: - name: lat in: query required: true schema: type: number - name: lng in: query required: true schema: type: number responses: '200': description: UMI score content: application/json: schema: $ref: '#/components/schemas/UMIResponse' # === Decisions === /decisions/recommend: post: summary: Get recommendations description: Get decision recommendations for location requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RecommendRequest' responses: '200': description: Recommendations content: application/json: schema: $ref: '#/components/schemas/RecommendResponse' # === Global === /global/query: post: summary: Global query description: Query global reality model requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GlobalQueryRequest' responses: '200': description: Query results content: application/json: schema: $ref: '#/components/schemas/GlobalQueryResponse' components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: HealthResponse: type: object properties: status: type: string example: healthy version: type: string example: "1.0.0" components: type: object additionalProperties: type: string RegisterRequest: type: object required: - username - password properties: username: type: string password: type: string role: type: string enum: [admin, municipality, property_owner, zoomer, readonly] LoginRequest: type: object required: - username - password properties: username: type: string password: type: string AuthResponse: type: object properties: token: type: string role: type: string AnalyzeRequest: type: object properties: image_path: type: string image_id: type: string AnalyzeResponse: type: object properties: image_id: type: string position: type: object properties: lat: type: number lng: type: number accuracy: type: number confidence: type: number method: type: string evidence_summary: type: object confidence_report: type: object map_matches: type: array similar_images: type: array BatchAnalyzeRequest: type: object properties: images: type: array items: type: object properties: path: type: string id: type: string TemporalRequest: type: object properties: observations: type: array items: type: object Domain: type: object properties: code: type: string name: type: string description: type: string System: type: object properties: code: type: string name: type: string domain: type: string GOIDGenerateRequest: type: object required: - domain - system - object_type properties: domain: type: string system: type: string object_type: type: string GOIDResponse: type: object properties: goid: type: string domain: type: string system: type: string GOIDValidationResponse: type: object properties: valid: type: boolean parsed: type: object Observation: type: object properties: id: type: string goid: type: string lat: type: number lng: type: number condition: type: integer findings: type: array timestamp: type: string ObservationCreate: type: object required: - lat - lng properties: image_url: type: string lat: type: number lng: type: number evidence: type: object SignalsResponse: type: object properties: signals: type: array items: type: object properties: signal_type: type: string value: type: number unit: type: string RGIResponse: type: object properties: rgi: type: number dimensions: type: object UMIResponse: type: object properties: umi: type: number gui_level: type: integer RecommendRequest: type: object properties: stakeholder: type: string lat: type: number lng: type: number RecommendResponse: type: object properties: recommendations: type: array items: type: object properties: type: type: string recommendation: type: string expected_impact: type: number cost: type: number GlobalQueryRequest: type: object properties: query: type: string location: type: object GlobalQueryResponse: type: object properties: results: type: array confidence: type: number