{"openapi":"3.1.0","info":{"title":"PerPlant Image Search API","description":"POC API for PerPlant image filtering and DINOv2 visual similarity search. Images remain in S3; metadata and vectors are served from Qdrant.","version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/stats":{"get":{"summary":"Stats","operationId":"stats_api_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/filters":{"get":{"summary":"Filters","operationId":"filters_api_filters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/farmers":{"get":{"summary":"Farmers","operationId":"farmers_api_farmers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/fields":{"get":{"summary":"Fields","operationId":"fields_api_fields_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"farmer_id","in":"query","required":true,"schema":{"type":"string","title":"Farmer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/operations":{"get":{"summary":"Operations","operationId":"operations_api_operations_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"field_id","in":"query","required":true,"schema":{"type":"string","title":"Field Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/images":{"get":{"summary":"Images","operationId":"images_api_images_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"scene","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scene"}},{"name":"crop","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crop"}},{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"farmer_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Farmer Id"}},{"name":"field_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Id"}},{"name":"operation_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/images/{image_id}":{"get":{"summary":"Image Detail","operationId":"image_detail_api_images__image_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"image_id","in":"path","required":true,"schema":{"type":"string","title":"Image Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search/similar":{"post":{"summary":"Similar","operationId":"similar_api_search_similar_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimilarRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/nexus/start":{"post":{"tags":["Nexus"],"summary":"Start Nexus Job","operationId":"start_nexus_job_nexus_start_post","parameters":[{"name":"X-Nexus-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nexus-Key"}},{"name":"x-nexus-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nexus-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NexusStartRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/nexus/approve":{"post":{"tags":["Nexus"],"summary":"Approve Nexus Job","operationId":"approve_nexus_job_nexus_approve_post","parameters":[{"name":"X-Nexus-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nexus-Key"}},{"name":"x-nexus-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nexus-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NexusApproveRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImageS3Ref":{"properties":{"image_id":{"type":"string","title":"Image Id"},"s3_key":{"type":"string","title":"S3 Key"}},"type":"object","required":["image_id","s3_key"],"title":"ImageS3Ref"},"NexusApproveRequest":{"properties":{"job_id":{"type":"string","title":"Job Id"},"task_id":{"type":"string","title":"Task Id"},"app_id":{"type":"string","title":"App Id"},"farmer_id":{"type":"string","title":"Farmer Id"},"field_id":{"type":"string","title":"Field Id"},"operation_id":{"type":"string","title":"Operation Id"},"crop_context":{"type":"string","title":"Crop Context"},"detection_goal":{"type":"string","enum":["count","find_map","badspot"],"title":"Detection Goal"},"checkpoint_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkpoint S3 Key"},"config_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Config S3 Key"},"field_s3_prefix":{"type":"string","title":"Field S3 Prefix"},"detection_label":{"type":"string","title":"Detection Label"},"callback_url":{"type":"string","title":"Callback Url"}},"type":"object","required":["job_id","task_id","app_id","farmer_id","field_id","operation_id","crop_context","detection_goal","field_s3_prefix","detection_label","callback_url"],"title":"NexusApproveRequest"},"NexusStartRequest":{"properties":{"job_id":{"type":"string","title":"Job Id"},"task_id":{"type":"string","title":"Task Id"},"app_id":{"type":"string","title":"App Id"},"farmer_id":{"type":"string","title":"Farmer Id"},"field_id":{"type":"string","title":"Field Id"},"operation_id":{"type":"string","title":"Operation Id"},"crop_context":{"type":"string","title":"Crop Context"},"detection_goal":{"type":"string","enum":["count","find_map"],"title":"Detection Goal"},"coco_s3_key":{"type":"string","title":"Coco S3 Key"},"image_s3_keys":{"items":{"$ref":"#/components/schemas/ImageS3Ref"},"type":"array","title":"Image S3 Keys"},"field_s3_prefix":{"type":"string","title":"Field S3 Prefix"},"detection_label":{"type":"string","title":"Detection Label"},"callback_url":{"type":"string","title":"Callback Url"}},"type":"object","required":["job_id","task_id","app_id","farmer_id","field_id","operation_id","crop_context","detection_goal","coco_s3_key","image_s3_keys","field_s3_prefix","detection_label","callback_url"],"title":"NexusStartRequest"},"SimilarRequest":{"properties":{"image_id":{"type":"string","title":"Image Id"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":20},"scene":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scene"},"crop":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crop"},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"},"farmer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Farmer Id"},"field_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Id"},"operation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Id"}},"type":"object","required":["image_id"],"title":"SimilarRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}