Skip to content

Vision API Reference

This document provides complete API reference for vision analysis and image search capabilities.

Search property photos using natural language descriptions.

GET /api/admin/search/images?q={query}&limit={limit}&offset={offset}
ParameterTypeRequiredDefaultDescription
qstringYesSearch query (e.g., “granite countertops”)
limitintegerNo20Results per page (max: 100)
offsetintegerNo0Pagination offset
property_idstringNoLimit to specific property
{
"results": [
{
"image_id": "img_abc123",
"property_id": "prop_xyz789",
"url": "https://.../photos/kitchen-1.jpg",
"description": "Modern kitchen with white cabinets, granite countertops, and stainless steel appliances",
"room_type": "kitchen",
"score": 0.92,
"features": [
"granite_countertops",
"white_cabinets",
"stainless_appliances"
]
}
],
"total": 45,
"limit": 20,
"offset": 0
}
CodeMeaning
200Success
400Invalid query parameters
429Rate limit exceeded

Find photos that look similar using SigLIP embeddings.

GET /api/admin/search/images-visual?q={query}&limit={limit}
ParameterTypeRequiredDefaultDescription
qstringYesNatural language description of desired visual
limitintegerNo20Results per page (max: 100)
min_scorefloatNo0.5Minimum similarity score (0.0-1.0)
{
"results": [
{
"image_id": "img_abc123",
"property_id": "prop_xyz789",
"url": "https://.../photos/kitchen-1.jpg",
"similarity_score": 0.89,
"description": "Modern white kitchen with island",
"room_type": "kitchen"
}
],
"total": 32,
"query_embedding": [0.123, 0.456, ...],
"execution_time_ms": 45
}

Combine text and image search for comprehensive results.

POST /api/search/multimodal
Content-Type: application/json
{
"query": "open concept living room with vaulted ceilings",
"include_images": true,
"limit": 20
}
FieldTypeRequiredDescription
querystringYesSearch query
include_imagesbooleanNoInclude image-level results (default: false)
limitintegerNoResults per page (default: 20, max: 100)
offsetintegerNoPagination offset
{
"properties": [
{
"property_id": "prop_xyz789",
"address": "123 Main St",
"city": "Twin Falls",
"text_similarity": 0.85,
"image_similarity": 0.78,
"combined_score": 0.82,
"matching_images": [
{
"image_id": "img_abc123",
"url": "https://.../photos/living-1.jpg",
"description": "Spacious living room with vaulted ceiling",
"score": 0.91
}
]
}
],
"total": 18,
"execution_time_ms": 120
}
combined_score = (text_similarity × 0.6) + (image_similarity × 0.4)

Text is weighted higher because it includes structured listing data.


Retrieve statistics about the vision analysis index.

GET /api/admin/embeddings/images/stats
{
"total_properties": 1250,
"properties_with_images": 1180,
"total_images": 7500,
"description_embeddings": 6800,
"visual_embeddings": 5200,
"avg_images_per_property": 6.4,
"unindexed_images": 700,
"index_coverage": 0.91,
"last_indexed_at": "2024-01-15T10:30:00Z",
"storage_size_mb": 245.6
}
FieldDescription
total_propertiesTotal properties in database
properties_with_imagesProperties with at least one photo
total_imagesTotal photo count
description_embeddingsPhotos with text embeddings
visual_embeddingsPhotos with visual embeddings
unindexed_imagesPhotos pending analysis
index_coveragePercentage of photos indexed (0.0-1.0)

Process unindexed images or re-process existing images.

POST /api/admin/embeddings/reindex/images?limit={limit}&force={force}
Content-Type: application/json
ParameterTypeRequiredDefaultDescription
limitintegerNo100Max images to process
forcebooleanNofalseRe-process already indexed images
{
"property_ids": ["prop_123", "prop_456"],
"room_types": ["kitchen", "bathroom"],
"min_quality_score": 0.8
}
{
"started": true,
"job_id": "job_abc123",
"images_queued": 150,
"estimated_duration_minutes": 5,
"status_url": "/api/admin/embeddings/jobs/job_abc123"
}
CodeMeaning
202Job queued successfully
400Invalid parameters
429Another indexing job already running
503Ollama service unavailable

Monitor progress of an indexing job.

GET /api/admin/embeddings/jobs/{job_id}
{
"job_id": "job_abc123",
"status": "running",
"progress": {
"processed": 75,
"total": 150,
"percentage": 50,
"current_image": "img_xyz789"
},
"started_at": "2024-01-15T10:30:00Z",
"estimated_completion": "2024-01-15T10:35:00Z",
"errors": [
{
"image_id": "img_bad123",
"error": "Image file corrupted"
}
]
}
StatusDescription
queuedWaiting to start
runningCurrently processing
completedFinished successfully
failedEncountered critical error
partialCompleted with some errors

Remove embeddings for specific images.

DELETE /api/admin/embeddings/images
Content-Type: application/json
{
"image_ids": ["img_abc123", "img_xyz789"]
}
FieldTypeRequiredDescription
image_idsarrayYesImage IDs to delete embeddings for
delete_descriptionsbooleanNoAlso delete text descriptions (default: false)
{
"deleted": 2,
"failed": 0,
"errors": []
}

Retrieve all photos categorized as a specific room type.

GET /api/admin/images/by-room/{room_type}?limit={limit}&offset={offset}
ParameterDescriptionValues
room_typeRoom categorykitchen, bedroom, bathroom, living_room, exterior, garage, other
{
"room_type": "kitchen",
"results": [
{
"image_id": "img_abc123",
"property_id": "prop_xyz789",
"url": "https://.../photos/kitchen-1.jpg",
"description": "Modern kitchen with granite counters",
"confidence": 0.95,
"features": ["granite_countertops", "island", "stainless_appliances"]
}
],
"total": 320
}

Manually correct an auto-detected room type.

PATCH /api/admin/images/{image_id}/room-type
Content-Type: application/json
{
"room_type": "bathroom",
"confidence": 1.0
}
{
"image_id": "img_abc123",
"room_type": "bathroom",
"previous_room_type": "kitchen",
"confidence": 1.0,
"manually_set": true
}

Retrieve all features detected in an image.

GET /api/admin/images/{image_id}/features
{
"image_id": "img_abc123",
"features": [
{
"key": "granite_countertops",
"label": "Granite Countertops",
"confidence": 0.89,
"category": "material"
},
{
"key": "island",
"label": "Kitchen Island",
"confidence": 0.92,
"category": "feature"
},
{
"key": "stainless_appliances",
"label": "Stainless Steel Appliances",
"confidence": 0.85,
"category": "appliance"
}
]
}

Manually tag a feature that wasn’t auto-detected.

POST /api/admin/images/{image_id}/features
Content-Type: application/json
{
"key": "wine_fridge",
"label": "Wine Refrigerator",
"category": "appliance"
}
{
"feature_id": "feat_abc123",
"key": "wine_fridge",
"label": "Wine Refrigerator",
"confidence": 1.0,
"manually_added": true
}

Analyze all photos for a specific property.

POST /api/admin/properties/{property_id}/analyze-images
{
"property_id": "prop_xyz789",
"images_analyzed": 18,
"features_detected": 127,
"avg_confidence": 0.84,
"execution_time_ms": 35000
}

Export all image descriptions for a property.

GET /api/admin/properties/{property_id}/image-descriptions
{
"property_id": "prop_xyz789",
"address": "123 Main St",
"images": [
{
"image_id": "img_abc123",
"order": 1,
"room_type": "kitchen",
"description": "Modern kitchen with white cabinets and granite countertops",
"features": ["granite_countertops", "white_cabinets"]
}
],
"export_format": "json"
}

Add ?format=csv or ?format=txt for alternate formats.


EndpointLimitWindowScope
/api/admin/search/images*100 requests1 minutePer API key
/api/admin/embeddings/reindex*5 requests1 hourGlobal
/api/search/multimodal30 requests1 minutePer session

Rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705329600

Vision analysis triggers webhook events for integration:

Fired when an image analysis completes.

{
"event": "image.analyzed",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"image_id": "img_abc123",
"property_id": "prop_xyz789",
"room_type": "kitchen",
"features_count": 8,
"confidence_avg": 0.87
}
}

Fired when a batch indexing job finishes.

{
"event": "indexing.completed",
"timestamp": "2024-01-15T10:35:00Z",
"data": {
"job_id": "job_abc123",
"images_processed": 150,
"success_count": 148,
"error_count": 2,
"duration_seconds": 300
}
}

CodeErrorMeaning
VISION_001ollama_unavailableOllama service not responding
VISION_002model_not_loadedRequired vision model not available
VISION_003image_corruptImage file is corrupted or invalid
VISION_004image_too_largeImage exceeds max size (10MB)
VISION_005embedding_failedFailed to generate embedding
VISION_006description_failedFailed to generate description
VISION_007index_fullVector index at capacity