{"openapi":"3.0.3","info":{"title":"Sunglasses Specifications and Comparison API","version":"1.0","description":"Read-only, source-cited sunglasses variant, size and lens facts for the US market (USD, millimetres). Same business layer as the MCP server at /mcp. Anonymous trial without a key; optional API keys raise quotas.","contact":{"url":"https://sunglassesguides.com/data-quality"}},"servers":[{"url":"https://sunglassesguides.com"}],"externalDocs":{"url":"https://sunglassesguides.com/docs/index.md","description":"Machine-readable documentation (Markdown)"},"paths":{"/api/v1/coverage":{"get":{"operationId":"get_sunglasses_coverage","summary":"Catalog coverage","description":"Describe what this service covers right now: brands, models, published variants, field completeness, offer coverage, freshness and which demo tasks have verified answers.\n\nWhen to use: Before relying on this service, to check whether a brand or task is in scope. To explain to a user why a search returned nothing.\n\nWhen not to use: To search for frames (use find_sunglasses).\n\nReturns: Counts computed from published records, field coverage, fit label definitions, offer coverage status, task_coverage_matrix and capability support flags.\n\nRead-only. MCP tool with the same name: get_sunglasses_coverage.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"get_sunglasses_coverage","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of COVERAGE. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"304":{"description":"Not modified (If-None-Match matched the ETag). Quota still applies."},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"parameters":[]}},"/api/v1/resolve":{"post":{"operationId":"resolve_sunglasses","summary":"Identify a frame","description":"Turn what a user knows (brand, model name, code on the temple, size marking, lens) into exact catalog variants, or say precisely which detail is missing.\n\nWhen to use: The user names a brand/model/code and you need the exact size and lens version. A model name is ambiguous (several sizes or lenses).\n\nWhen not to use: The user only has a size marking like 52-18-140 and wants alternatives: call find_sunglasses directly. You already have a variant_id: call get_sunglasses_variant.\n\nReturns: status RESOLVED (one variant), NEEDS_VARIANT (candidates + missing_fields), SIZE_ONLY_NOT_IDENTIFIABLE, NOT_FOUND_IN_CATALOG or OUT_OF_SCOPE. Never silently picks a size or lens.\n\nRead-only. MCP tool with the same name: resolve_sunglasses.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"resolve_sunglasses","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of RESOLVED, NEEDS_VARIANT, SIZE_ONLY_NOT_IDENTIFIABLE, NOT_FOUND_IN_CATALOG, OUT_OF_SCOPE. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"description":"Free text as the user wrote it, e.g. \"Ray-Ban RB2140F 52\" or \"Holbrook OO9102 polarized\".","type":"string","minLength":1,"maxLength":200},"brand":{"description":"Brand name, e.g. \"Ray-Ban\", \"Oakley\", \"Maui Jim\".","type":"string","maxLength":40},"model":{"description":"Model name or model code, e.g. \"Wayfarer\", \"RB2140\", \"Holbrook\".","type":"string","maxLength":80},"manufacturer_code":{"description":"Maker style/variant code as printed on the temple or product page, e.g. \"RB2140F 901/58\" or \"OO9102-F455\".","type":"string","maxLength":40},"size":{"description":"Known frame size, if printed on the temple.","type":"object","properties":{"lens_width_mm":{"type":"integer","minimum":30,"maximum":80,"description":"Lens width in mm (first number of a temple marking like 52-18-140)."},"bridge_width_mm":{"type":"integer","minimum":8,"maximum":30,"description":"Bridge width in mm (second number)."},"temple_length_mm":{"description":"Temple length in mm (third number). Optional.","type":"integer","minimum":100,"maximum":170}},"required":["lens_width_mm","bridge_width_mm"],"additionalProperties":false},"size_text":{"description":"Temple size marking as text, e.g. \"52-18-140\" (frames print a small square between the first two numbers; that form is accepted too).","type":"string","maxLength":40},"lens":{"description":"Lens color or lens name if known, e.g. \"G-15\", \"Prizm Black\".","type":"string","maxLength":60},"frame_color":{"description":"Frame color if known.","type":"string","maxLength":60},"polarized":{"description":"Whether the user knows their lens is polarized.","type":"boolean"},"market":{"type":"string","maxLength":8,"description":"Market code. Only \"US\" is supported; anything else returns 422 UNSUPPORTED_MARKET."},"limit":{"description":"Maximum candidates returned when ambiguous. Default 5, max 10.","type":"integer","minimum":1,"maximum":10},"expected_data_version":{"type":"string","pattern":"^c\\d+\\.o\\d+$","description":"data_version returned by an earlier call. If the catalog changed since, the call fails with DATA_VERSION_CHANGED instead of mixing old and new facts."}},"additionalProperties":false},"example":{"query":"Ray-Ban Original Wayfarer"}}}}}},"/api/v1/search":{"post":{"operationId":"find_sunglasses","summary":"Find by size and conditions","description":"Filter the covered catalog by a reference size with per-dimension tolerances and hard conditions (polarized, maker-labeled bridge fit, brand, optional offer conditions). Every condition is evaluated per candidate as pass/fail/unknown/conflict/stale with evidence.\n\nWhen to use: The user has a size (e.g. 52-18-140) and wants alternatives. The user needs frames that are confirmed polarized and/or maker-labeled low bridge fit. One call usually answers the task: it returns size differences, evidence and detail links.\n\nWhen not to use: To identify which exact frame the user owns (use resolve_sunglasses). To compare 2-4 known variants field by field (use compare_sunglasses).\n\nReturns: status MATCHES_FOUND, NO_MATCH_IN_COVERED_CATALOG, INSUFFICIENT_EVIDENCE, NO_OFFER_COVERAGE, OUT_OF_SCOPE or EMPTY_CATALOG; normalized_constraints; non-overlapping counts; matches (only all-pass candidates); undecided candidates with blocking conditions; relaxation suggestions that require user confirmation.\n\nRead-only. MCP tool with the same name: find_sunglasses.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"find_sunglasses","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of MATCHES_FOUND, NO_MATCH_IN_COVERED_CATALOG, INSUFFICIENT_EVIDENCE, NO_OFFER_COVERAGE, OUT_OF_SCOPE, EMPTY_CATALOG. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"description":"Reference size to compare against (e.g. from the user's current glasses).","type":"object","properties":{"lens_width_mm":{"type":"integer","minimum":30,"maximum":80,"description":"Lens width in mm (first number of a temple marking like 52-18-140)."},"bridge_width_mm":{"type":"integer","minimum":8,"maximum":30,"description":"Bridge width in mm (second number)."},"temple_length_mm":{"description":"Temple length in mm (third number). Optional.","type":"integer","minimum":100,"maximum":170}},"required":["lens_width_mm","bridge_width_mm"],"additionalProperties":false},"reference_text":{"description":"Reference size as printed, e.g. \"52-18-140\". Parsed to reference.","type":"string","maxLength":40},"reference_variant_id":{"description":"Use a known catalog variant's size as the reference. Requires expected_data_version if it came from an earlier call.","type":"string","pattern":"^[a-z0-9][a-z0-9-]{2,95}$"},"tolerance_mm":{"description":"Allowed absolute difference per dimension in mm. Defaults (disclosed in normalized_constraints): lens 2, bridge 2, temple 5.","type":"object","properties":{"lens_width":{"type":"number","minimum":0,"maximum":10},"bridge_width":{"type":"number","minimum":0,"maximum":10},"temple_length":{"type":"number","minimum":0,"maximum":20}},"additionalProperties":false},"require":{"type":"object","properties":{"polarized":{"description":"Hard condition. true = maker states polarized for this variant. Unknown polarization never passes.","type":"boolean"},"bridge_fit":{"description":"Hard condition on the normalized maker fit label, e.g. \"low_bridge_fit\". Only maker-labeled variants pass.","type":"string","enum":["low_bridge_fit","standard_fit","high_bridge_fit","universal_fit","unmapped"]},"brands":{"description":"Restrict to these brands.","maxItems":5,"type":"array","items":{"type":"string","maxLength":40}},"max_item_price_usd":{"description":"Hard offer condition: item price (before shipping/tax) at or below this. Needs offer coverage.","type":"number","minimum":0,"exclusiveMinimum":true,"maximum":10000},"max_landed_total_usd":{"description":"Hard offer condition: item + shipping + tax at or below this. Unknown fees never pass.","type":"number","minimum":0,"exclusiveMinimum":true,"maximum":10000},"in_stock":{"description":"Hard offer condition: current, non-stale in-stock observation required.","type":"boolean"},"ship_to_zip":{"description":"Hard offer condition: 5-digit US ZIP the offer must ship to.","type":"string","maxLength":10}},"additionalProperties":false},"market":{"type":"string","maxLength":8,"description":"Market code. Only \"US\" is supported; anything else returns 422 UNSUPPORTED_MARKET."},"currency":{"type":"string","maxLength":8,"description":"Currency code. Only \"USD\" is supported."},"limit":{"description":"Matches per page. Default 5, max 20.","type":"integer","minimum":1,"maximum":20},"cursor":{"description":"Opaque cursor from a previous page of the SAME query.","type":"string","maxLength":400},"include_undecided":{"description":"Also list up to 5 candidates that could not be decided (unknown/conflicting/stale evidence). Default true.","type":"boolean"},"expected_data_version":{"type":"string","pattern":"^c\\d+\\.o\\d+$","description":"data_version returned by an earlier call. If the catalog changed since, the call fails with DATA_VERSION_CHANGED instead of mixing old and new facts."}},"additionalProperties":false},"example":{"reference_text":"52-18-140","require":{"polarized":true},"limit":3}}}}}},"/api/v1/compare":{"post":{"operationId":"compare_sunglasses","summary":"Compare variants","description":"Side-by-side comparison of 2-4 variants: every field with its status and sources, which fields differ, conflicts, and size differences against a reference.\n\nWhen to use: The user wants to see how 2-4 specific frames differ (fit label, lens, sizes).\n\nWhen not to use: To search (use find_sunglasses). More than 4 variants (not supported).\n\nReturns: status COMPARED with fields[], differing_fields, size_differences (vs reference and vs the first variant).\n\nRead-only. MCP tool with the same name: compare_sunglasses.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"compare_sunglasses","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of COMPARED. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variant_ids":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{2,95}$","description":"Stable variant_id from this catalog, e.g. returned by find_sunglasses or resolve_sunglasses."},"description":"2 to 4 distinct variant_ids."},"reference":{"description":"Optional reference size; per-dimension differences are returned for each variant.","type":"object","properties":{"lens_width_mm":{"type":"integer","minimum":30,"maximum":80,"description":"Lens width in mm (first number of a temple marking like 52-18-140)."},"bridge_width_mm":{"type":"integer","minimum":8,"maximum":30,"description":"Bridge width in mm (second number)."},"temple_length_mm":{"description":"Temple length in mm (third number). Optional.","type":"integer","minimum":100,"maximum":170}},"required":["lens_width_mm","bridge_width_mm"],"additionalProperties":false},"reference_text":{"type":"string","maxLength":40},"expected_data_version":{"type":"string","pattern":"^c\\d+\\.o\\d+$","description":"data_version returned by an earlier call. If the catalog changed since, the call fails with DATA_VERSION_CHANGED instead of mixing old and new facts."}},"required":["variant_ids"],"additionalProperties":false},"example":{"variant_ids":["mauijim-668-02","mauijim-h668-10"],"reference_text":"52-18-140"}}}}}},"/api/v1/variants/{variant_id}":{"get":{"operationId":"get_sunglasses_variant","summary":"Variant details","description":"Full record of one exact variant: every field with value, field_status, evidence excerpts, sources, check times and unknowns.\n\nWhen to use: You have a variant_id and need all facts and sources.\n\nWhen not to use: You do not have a variant_id yet (use resolve_sunglasses or find_sunglasses).\n\nReturns: status FOUND with the variant, or HTTP 404 NOT_FOUND for an unknown id.\n\nRead-only. MCP tool with the same name: get_sunglasses_variant.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"get_sunglasses_variant","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of FOUND. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"304":{"description":"Not modified (If-None-Match matched the ETag). Quota still applies."},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{2,95}$","description":"Stable variant_id from this catalog, e.g. returned by find_sunglasses or resolve_sunglasses."},"example":"mauijim-668-02"},{"name":"expected_data_version","in":"query","required":false,"schema":{"type":"string","pattern":"^c\\d+\\.o\\d+$","description":"data_version returned by an earlier call. If the catalog changed since, the call fails with DATA_VERSION_CHANGED instead of mixing old and new facts."}}]}},"/api/v1/variants/{variant_id}/offers":{"get":{"operationId":"get_sunglasses_offers","summary":"Covered offers","description":"Return covered US offers for one exact variant with item price, shipping, tax, landed-total status, availability and observation time, each kept separate.\n\nWhen to use: The user needs a purchase option for a specific variant.\n\nWhen not to use: To find the cheapest price on the web (not supported). To check spec facts (use get_sunglasses_variant).\n\nReturns: status OFFERS_FOUND or NO_OFFER_COVERAGE with an empty list. Never returns simulated prices in production.\n\nRead-only. MCP tool with the same name: get_sunglasses_offers.","tags":["sunglasses"],"x-read-only":true,"x-mcp-tool":"get_sunglasses_offers","security":[{},{"bearerApiKey":[]},{"headerApiKey":[]}],"responses":{"200":{"description":"Processed. result.status is one of OFFERS_FOUND, NO_OFFER_COVERAGE. success=true does not mean a match was found.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"Quota policy: per-minute and per-day windows."},"RateLimit":{"schema":{"type":"string"},"description":"Remaining requests (r) and seconds until reset (t) of the tightest window."},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Epoch seconds"},"X-Request-Id":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"304":{"description":"Not modified (If-None-Match matched the ETag). Quota still applies."},"400":{"description":"INVALID_INPUT: The body is not valid JSON or is not an object.; INVALID_CURSOR: The cursor is malformed or belongs to a different query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"UNAUTHENTICATED: An API key was sent but it is unknown or malformed. Omit the key to use the anonymous trial.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"403":{"description":"FORBIDDEN: The key is valid but revoked or lacks access to this resource (for example admin endpoints).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"404":{"description":"NOT_FOUND: An explicit variant_id does not exist in the published catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"405":{"description":"METHOD_NOT_ALLOWED: Wrong HTTP method for this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"409":{"description":"DATA_VERSION_CHANGED: expected_data_version no longer matches the published catalog. Re-run the original query without expected_data_version (keep your hard conditions) and continue with the new version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"413":{"description":"PAYLOAD_TOO_LARGE: Request body exceeds 16 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"422":{"description":"VALIDATION_FAILED: A parameter is out of range, of the wrong type, or not an allowed enum value. error.details lists each issue.; UNSUPPORTED_MARKET: market/currency other than US/USD was requested. This service only covers the US market in USD.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"429":{"description":"RATE_LIMITED: Per-minute or per-day quota exhausted. Wait retry_after_seconds (also sent as Retry-After).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"500":{"description":"INTERNAL_ERROR: Unexpected server error. Safe to retry once; include request_id when reporting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"503":{"description":"SERVICE_UNAVAILABLE: The database or a dependency is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}},"parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{2,95}$","description":"Stable variant_id from this catalog, e.g. returned by find_sunglasses or resolve_sunglasses."},"example":"mauijim-668-02"},{"name":"ship_to_zip","in":"query","required":false,"schema":{"type":"string","maxLength":10}},{"name":"market","in":"query","required":false,"schema":{"type":"string","maxLength":8,"description":"Market code. Only \"US\" is supported; anything else returns 422 UNSUPPORTED_MARKET."}},{"name":"expected_data_version","in":"query","required":false,"schema":{"type":"string","pattern":"^c\\d+\\.o\\d+$","description":"data_version returned by an earlier call. If the catalog changed since, the call fails with DATA_VERSION_CHANGED instead of mixing old and new facts."}}]}}},"components":{"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","description":"Optional API key \"sgk_live_...\" as a Bearer token. Omit for the anonymous trial."},"headerApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Optional API key in a header."}},"schemas":{"Envelope":{"type":"object","properties":{"request_id":{"type":"string"},"success":{"type":"boolean","description":"true = the request was processed correctly. It does NOT mean anything matched."},"schema_version":{"type":"string"},"data_version":{"nullable":true,"description":"Published catalog + offer batch version this answer was computed from.","type":"string"},"data_mode":{"type":"string","enum":["production","demo"]},"generated_at":{"type":"string","description":"When this response was generated (UTC). Not a product fact timestamp."},"request":{"type":"object","properties":{"operation":{"type":"string"},"params":{"type":"object","additionalProperties":{}}},"required":["operation","params"],"additionalProperties":false},"result":{"nullable":true,"type":"object","additionalProperties":{}},"sources":{"type":"array","items":{"type":"object","properties":{"source_id":{"type":"string"},"source_url":{"type":"string"},"source_name":{"type":"string"},"source_type":{"type":"string"},"publisher":{"type":"string"},"source_region":{"nullable":true,"type":"string"},"original_source_id":{"nullable":true,"type":"string"},"retrieved_at":{"nullable":true,"type":"string"},"source_updated_at":{"nullable":true,"type":"string"},"retrieval_method":{"type":"string"},"usage_basis":{"type":"string"}},"required":["source_id","source_url","source_name","source_type","publisher","source_region","original_source_id","retrieved_at","source_updated_at","retrieval_method","usage_basis"],"additionalProperties":false}},"freshness":{"nullable":true,"type":"object","additionalProperties":{}},"cache":{"type":"object","properties":{"layer":{"type":"string"},"hit":{"nullable":true,"type":"boolean"},"age_seconds":{"nullable":true,"type":"number"},"expires_at":{"nullable":true,"type":"string"},"note":{"type":"string"}},"required":["layer","hit","age_seconds","expires_at","note"],"additionalProperties":false},"next_actions":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string","description":"Name of a read-only tool (MCP tool name == REST operationId)."},"reason":{"type":"string"},"arguments":{"type":"object","additionalProperties":{},"description":"Arguments that can be passed as-is, keeping the original hard conditions."},"missing_inputs":{"type":"array","items":{"type":"string"},"description":"Inputs the user must supply before this call is useful."},"requires_user_confirmation":{"type":"boolean","description":"true when the action relaxes a hard condition or needs the user to choose."}},"required":["tool","reason","arguments","missing_inputs","requires_user_confirmation"],"additionalProperties":false}},"error":{"nullable":true,"description":"null when success is true.","type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"retry_after_seconds":{"type":"number"},"details":{}},"required":["code","message","retryable"],"additionalProperties":false}},"required":["request_id","success","schema_version","data_version","data_mode","generated_at","request","result","sources","freshness","cache","next_actions","error"],"additionalProperties":false}}},"x-data-units":{"length":"mm","currency":"USD","market":"US"}}