{"openapi":"3.1.0","info":{"title":"Label Check (prototype)","description":"Prototype for verifying alcohol beverage label artwork against COLA application data. The tool recommends; the compliance agent decides. Nothing is stored.","version":"0.1.0"},"paths":{"/api/v1/health":{"get":{"tags":["system"],"summary":"Health","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/ready":{"get":{"tags":["system"],"summary":"Readiness probe: 200 once the OCR engines are warm, else 503","operationId":"ready_api_v1_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Ready Api V1 Ready Get"}}}}}}},"/api/v1/verify":{"post":{"tags":["verification"],"summary":"Verify one application against one or more label images","operationId":"verify_route_api_v1_verify_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_verify_route_api_v1_verify_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/extract":{"post":{"tags":["verification"],"summary":"Read a label without application data (batch and extract-only mode)","operationId":"extract_route_api_v1_extract_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_extract_route_api_v1_extract_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/compare":{"post":{"tags":["verification"],"summary":"Compare application data with previously extracted lines (no OCR, fast)","operationId":"compare_route_api_v1_compare_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/csv/template":{"get":{"tags":["batch"],"summary":"Download the batch CSV template","operationId":"csv_template_api_v1_csv_template_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/api/v1/csv/parse":{"post":{"tags":["batch"],"summary":"Parse and validate a batch CSV of application rows","operationId":"csv_parse_api_v1_csv_parse_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_csv_parse_api_v1_csv_parse_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvParseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ApplicationFields":{"properties":{"application_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Application Id","description":"Agent's reference, e.g. a TTB ID"},"beverage_type":{"$ref":"#/components/schemas/BeverageType"},"brand_name":{"type":"string","maxLength":200,"minLength":1,"title":"Brand Name"},"class_type":{"type":"string","maxLength":200,"minLength":1,"title":"Class Type"},"alcohol_content":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Alcohol Content","description":"As written, e.g. \"45% Alc./Vol. (90 Proof)\""},"net_contents":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Net Contents","description":"As written, e.g. \"750 mL\". May be blank (the COLA form carries none): the result then shows what the label says and asks the agent to confirm it"},"bottler":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Bottler","description":"Name and address of bottler/producer/importer"},"country_of_origin":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Country Of Origin"},"imported":{"type":"boolean","title":"Imported","default":false}},"type":"object","required":["beverage_type","brand_name","class_type"],"title":"ApplicationFields","description":"What the agent has in front of them from the COLA application, as written."},"BeverageType":{"type":"string","enum":["spirits","wine","malt"],"title":"BeverageType"},"Body_csv_parse_api_v1_csv_parse_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_csv_parse_api_v1_csv_parse_post"},"Body_extract_route_api_v1_extract_post":{"properties":{"images":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Images"}},"type":"object","required":["images"],"title":"Body_extract_route_api_v1_extract_post"},"Body_verify_route_api_v1_verify_post":{"properties":{"application":{"type":"string","title":"Application","description":"JSON object with the application fields"},"images":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Images","description":"1 to 6 label images (front, back, neck...)"}},"type":"object","required":["application","images"],"title":"Body_verify_route_api_v1_verify_post"},"Check":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"status":{"$ref":"#/components/schemas/Status"},"expected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected"},"found":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Found"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score","description":"0-100 similarity where applicable"},"note":{"type":"string","title":"Note","default":""},"rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rule","description":"Regulatory citation where applicable"},"evidence":{"items":{"$ref":"#/components/schemas/Evidence"},"type":"array","title":"Evidence"}},"type":"object","required":["id","label","status"],"title":"Check"},"CompareItem":{"properties":{"item_id":{"type":"string","maxLength":128,"title":"Item Id"},"application":{"$ref":"#/components/schemas/ApplicationFields"},"lines":{"items":{"$ref":"#/components/schemas/OcrLine"},"type":"array","maxItems":2000,"title":"Lines"},"images":{"items":{"$ref":"#/components/schemas/ImageInfo"},"type":"array","maxItems":64,"title":"Images"}},"type":"object","required":["item_id","application","lines"],"title":"CompareItem"},"CompareRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CompareItem"},"type":"array","minItems":1,"title":"Items"}},"type":"object","required":["items"],"title":"CompareRequest"},"CompareResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"results":{"items":{"$ref":"#/components/schemas/CompareResponseItem"},"type":"array","title":"Results"}},"type":"object","required":["request_id","results"],"title":"CompareResponse"},"CompareResponseItem":{"properties":{"verdict":{"$ref":"#/components/schemas/Verdict"},"checks":{"items":{"$ref":"#/components/schemas/Check"},"type":"array","title":"Checks"},"warning":{"$ref":"#/components/schemas/WarningReport"},"summary":{"type":"string","title":"Summary"},"item_id":{"type":"string","title":"Item Id"}},"type":"object","required":["verdict","checks","warning","summary","item_id"],"title":"CompareResponseItem"},"CsvParseResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"rows":{"items":{"$ref":"#/components/schemas/CsvRowOut"},"type":"array","title":"Rows"},"columns":{"items":{"type":"string"},"type":"array","title":"Columns"},"unmapped_columns":{"items":{"type":"string"},"type":"array","title":"Unmapped Columns"},"delimiter":{"type":"string","title":"Delimiter"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings"}},"type":"object","required":["request_id","rows","columns","unmapped_columns","delimiter","warnings"],"title":"CsvParseResponse"},"CsvRowOut":{"properties":{"row_number":{"type":"integer","title":"Row Number"},"application":{"anyOf":[{"$ref":"#/components/schemas/ApplicationFields"},{"type":"null"}]},"images":{"items":{"type":"string"},"type":"array","title":"Images"},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"}},"type":"object","required":["row_number","application"],"title":"CsvRowOut"},"EngineInfo":{"properties":{"name":{"type":"string","title":"Name"},"models":{"additionalProperties":{"type":"string"},"type":"object","title":"Models"},"workers":{"type":"integer","title":"Workers"}},"type":"object","required":["name","models","workers"],"title":"EngineInfo"},"Evidence":{"properties":{"image_index":{"type":"integer","title":"Image Index"},"box":{"prefixItems":[{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2}],"type":"array","maxItems":4,"minItems":4,"title":"Box"},"text":{"type":"string","title":"Text"}},"type":"object","required":["image_index","box","text"],"title":"Evidence"},"ExtractResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"images":{"items":{"$ref":"#/components/schemas/ImageInfo"},"type":"array","title":"Images"},"lines":{"items":{"$ref":"#/components/schemas/OcrLine"},"type":"array","title":"Lines"},"fields":{"$ref":"#/components/schemas/ExtractedFields"},"timing":{"$ref":"#/components/schemas/Timing"},"engine":{"$ref":"#/components/schemas/EngineInfo"}},"type":"object","required":["request_id","images","lines","fields","timing","engine"],"title":"ExtractResponse"},"ExtractedFields":{"properties":{"alcohol_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Alcohol Percent"},"proof":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Proof"},"net_contents_ml":{"items":{"type":"number"},"type":"array","title":"Net Contents Ml"},"warning_present":{"type":"boolean","title":"Warning Present","default":false},"origin_lines":{"items":{"type":"string"},"type":"array","title":"Origin Lines"},"bottler_lines":{"items":{"type":"string"},"type":"array","title":"Bottler Lines"},"largest_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Largest Text","description":"Tallest line, usually the brand"}},"type":"object","title":"ExtractedFields","description":"Best guesses read from the label without application data (extract-only mode)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"ready":{"type":"boolean","title":"Ready"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Set when OCR warm-up failed"},"engine":{"$ref":"#/components/schemas/EngineInfo"},"max_concurrency":{"type":"integer","title":"Max Concurrency"},"in_flight":{"type":"integer","title":"In Flight"},"requests_in_flight":{"type":"integer","title":"Requests In Flight","default":0},"version":{"type":"string","title":"Version"},"git_sha":{"type":"string","title":"Git Sha"}},"type":"object","required":["status","ready","engine","max_concurrency","in_flight","version","git_sha"],"title":"HealthResponse"},"ImageInfo":{"properties":{"index":{"type":"integer","title":"Index"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"width":{"type":"integer","title":"Width"},"height":{"type":"integer","title":"Height"},"format":{"type":"string","title":"Format"},"rotated_degrees":{"type":"integer","title":"Rotated Degrees","description":"Rotation applied by the orientation retry, if any","default":0},"quality":{"$ref":"#/components/schemas/ImageQuality"}},"type":"object","required":["index","filename","width","height","format","quality"],"title":"ImageInfo"},"ImageQuality":{"properties":{"mean_confidence":{"type":"number","title":"Mean Confidence"},"line_count":{"type":"integer","title":"Line Count"},"readable":{"type":"boolean","title":"Readable"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["mean_confidence","line_count","readable"],"title":"ImageQuality"},"OcrLine":{"properties":{"image_index":{"type":"integer","maximum":64.0,"minimum":0.0,"title":"Image Index"},"text":{"type":"string","maxLength":1000,"title":"Text"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"box":{"prefixItems":[{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2}],"type":"array","maxItems":4,"minItems":4,"title":"Box"}},"type":"object","required":["image_index","text","confidence","box"],"title":"OcrLine"},"Status":{"type":"string","enum":["match","needs_review","mismatch","not_found","not_checked","info"],"title":"Status"},"Timing":{"properties":{"total_ms":{"type":"integer","title":"Total Ms"},"queue_ms":{"type":"integer","title":"Queue Ms"},"ocr_ms":{"items":{"type":"integer"},"type":"array","title":"Ocr Ms"}},"type":"object","required":["total_ms","queue_ms","ocr_ms"],"title":"Timing"},"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"},"Verdict":{"type":"string","enum":["ready_for_approval","needs_review","issues_found","unreadable"],"title":"Verdict"},"VerifyResponse":{"properties":{"verdict":{"$ref":"#/components/schemas/Verdict"},"checks":{"items":{"$ref":"#/components/schemas/Check"},"type":"array","title":"Checks"},"warning":{"$ref":"#/components/schemas/WarningReport"},"summary":{"type":"string","title":"Summary"},"request_id":{"type":"string","title":"Request Id"},"application":{"$ref":"#/components/schemas/ApplicationFields"},"images":{"items":{"$ref":"#/components/schemas/ImageInfo"},"type":"array","title":"Images"},"lines":{"items":{"$ref":"#/components/schemas/OcrLine"},"type":"array","title":"Lines"},"timing":{"$ref":"#/components/schemas/Timing"},"engine":{"$ref":"#/components/schemas/EngineInfo"}},"type":"object","required":["verdict","checks","warning","summary","request_id","application","images","lines","timing","engine"],"title":"VerifyResponse"},"WarningReport":{"properties":{"present":{"type":"boolean","title":"Present"},"exact":{"type":"boolean","title":"Exact"},"assessment":{"type":"string","title":"Assessment","description":"exact | noise | wording | absent | not_required (how the read text relates to 16.21; exact ignores letter case and spacing, the anchor's capitals are anchor_caps)","default":"absent"},"similarity":{"type":"number","title":"Similarity"},"found_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Found Text"},"diff":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Diff","description":"Compact word diff: -expected +found"},"anchor_caps":{"$ref":"#/components/schemas/Status"},"anchor_bold":{"$ref":"#/components/schemas/Status"},"body_not_bold":{"$ref":"#/components/schemas/Status"},"evidence":{"items":{"$ref":"#/components/schemas/Evidence"},"type":"array","title":"Evidence"},"notes":{"items":{"type":"string"},"type":"array","title":"Notes"},"rule":{"type":"string","title":"Rule","default":"27 CFR 16.21 (text), 16.22 (format)"}},"type":"object","required":["present","exact","similarity","anchor_caps","anchor_bold","body_not_bold"],"title":"WarningReport"}}}}