{"openapi":"3.0.0","info":{"title":"RAG Insurance Wording","version":"1.0.0","description":"HTTP API for document-grounded answers and related utilities. See `/docs` for interactive OpenAPI."},"components":{"schemas":{"AskRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"End-user question in natural language.","example":"What does Travel Allianz Voiaj cover?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter market code for the document set (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Desired language of the answer (ISO 639-1/639-2 style code).","example":"en"},"profile":{"type":"string","enum":["speed","expert"],"description":"Answer preset: `speed` favors lower latency; `expert` favors more thorough answers.","example":"speed"},"memo":{"type":"string","description":"Optional client-supplied label for support/correlation (does not change the answer).","example":"agent 007"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with multiple event types before completion.","example":"sync"},"skip_semantic_cache":{"type":"boolean","description":"When true, do not reuse a previous cached answer for an equivalent query.","example":false},"debug":{"type":"object","properties":{"intent":{"type":"boolean"},"context":{"type":"boolean"},"metadata":{"type":"boolean"}},"description":"Optional flags; when set, the response may include extra diagnostic sections."}},"required":["user_id","api_key","query","country","lang","profile"]},"AskRagBody":{"type":"object","properties":{"query":{"type":"string","minLength":3,"description":"End-user question in natural language.","example":"What does Travel Allianz Voiaj cover?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter market code for the document set (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Desired language of the answer (ISO 639-1/639-2 style code).","example":"en"},"profile":{"type":"string","enum":["speed","expert"],"description":"Answer preset: `speed` favors lower latency; `expert` favors more thorough answers.","example":"speed"},"memo":{"type":"string","description":"Optional client-supplied label for support/correlation (does not change the answer).","example":"agent 007"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with multiple event types before completion.","example":"sync"},"skip_semantic_cache":{"type":"boolean","description":"When true, do not reuse a previous cached answer for an equivalent query.","example":false},"debug":{"type":"object","properties":{"intent":{"type":"boolean"},"context":{"type":"boolean"},"metadata":{"type":"boolean"}},"description":"Optional flags; when set, the response may include extra diagnostic sections."}},"required":["query","country","lang","profile"]},"AskSwaggerBody":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"End-user question in natural language.","example":"What does Travel Allianz Voiaj cover?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter market code for the document set (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Desired language of the answer (ISO 639-1/639-2 style code).","example":"en"},"profile":{"type":"string","enum":["speed","expert"],"description":"Answer preset: `speed` favors lower latency; `expert` favors more thorough answers.","example":"speed"},"memo":{"type":"string","description":"Optional client-supplied label for support/correlation (does not change the answer).","example":"agent 007"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with multiple event types before completion.","example":"sync"},"skip_semantic_cache":{"type":"boolean","description":"When true, do not reuse a previous cached answer for an equivalent query.","example":false},"debug":{"type":"object","properties":{"intent":{"type":"boolean"},"context":{"type":"boolean"},"metadata":{"type":"boolean"}},"description":"Optional flags; when set, the response may include extra diagnostic sections."}},"required":["user_id","api_key","query","country","lang","profile"]},"CompareExport":{"type":"object","properties":{"version":{"type":"number","enum":[1]},"kind":{"type":"string","enum":["product_compare"]},"answer_id":{"type":"string"},"country":{"type":"string"},"lang":{"type":"string"},"columns":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["label","product"]},"product_code":{"type":"string"},"header":{"type":"string"},"insurer":{"type":"string"}},"required":["role","header"]}},"rows":{"type":"array","items":{"type":"object","properties":{"row_id":{"type":"string"},"label":{"type":"string"},"cells":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string"},"coverage":{"type":"string","enum":["missing","stated","partial"]},"citation_indexes":{"type":"array","items":{"type":"integer","minimum":0}}},"required":["value"]}}},"required":["row_id","label","cells"]}},"notes":{"type":"array","items":{"type":"string"}}},"required":["version","kind","answer_id","country","lang","columns","rows"]},"AskResponse":{"type":"object","properties":{"answer":{"type":"string","description":"Natural-language answer grounded in the citations."},"citations":{"type":"array","items":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid","description":"Stable id of the cited wording document.","example":"b6575ba1-fb72-4404-924f-b1a5b2e98ea6"},"file_name":{"type":"string","description":"Published file name for the cited source.","example":"AllianzVoiaj.pdf"},"insurer":{"type":"string","description":"Insurer name for the cited source.","example":"Allianz"},"product_code":{"type":"string","description":"Product code for the cited wording.","example":"TRAVEL_VOIAJ"},"valid_from":{"type":"string","description":"Version start date for the cited wording (ISO 8601 date).","example":"2026-01-01"},"page_from":{"type":"number","description":"First page referenced in the source (1-based).","example":3},"page_to":{"type":"number","description":"Last page referenced in the source (1-based).","example":5}},"required":["document_id","file_name","insurer","product_code","valid_from"]},"description":"Sources used to support statements in the answer."},"chunks_used":{"type":"number","description":"Number of wording excerpts used to build the answer."},"retrieved_count":{"type":"number","description":"Number of candidate excerpts considered."},"reranked_count":{"type":"number","description":"Number of excerpts kept after relevance filtering."},"answer_id":{"type":"string","description":"Opaque id for this answer (support and correlation)."},"compare_export":{"type":"object","properties":{"version":{"type":"number","enum":[1]},"kind":{"type":"string","enum":["product_compare"]},"answer_id":{"type":"string"},"country":{"type":"string"},"lang":{"type":"string"},"columns":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["label","product"]},"product_code":{"type":"string"},"header":{"type":"string"},"insurer":{"type":"string"}},"required":["role","header"]}},"rows":{"type":"array","items":{"type":"object","properties":{"row_id":{"type":"string"},"label":{"type":"string"},"cells":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string"},"coverage":{"type":"string","enum":["missing","stated","partial"]},"citation_indexes":{"type":"array","items":{"type":"integer","minimum":0}}},"required":["value"]}}},"required":["row_id","label","cells"]}},"notes":{"type":"array","items":{"type":"string"}}},"required":["version","kind","answer_id","country","lang","columns","rows"],"description":"Present only for multi-product compare: structured matrix suitable for Excel export."}},"required":["answer","citations","chunks_used","retrieved_count","reranked_count","answer_id"],"example":{"answer":"Travel Allianz Voiaj covers ..","citations":[{"document_id":"b6575ba1-fb72-4404-924f-b1a5b2e98ea6","file_name":"AllianzVoiaj.pdf","insurer":"Allianz","product_code":"TRAVEL_VOIAJ","valid_from":"2026-01-01","page_from":1,"page_to":3}],"chunks_used":8,"retrieved_count":8,"reranked_count":8,"answer_id":"ans_237587e56243"}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]},"CountriesResponse":{"type":"object","properties":{"countries":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":2,"maxLength":2,"description":"ISO-like country code (2 letters).","example":"RO"},"name":{"type":"string","description":"Human-readable country name.","example":"Romania"}},"required":["code","name"]},"description":"Countries currently enabled for questions and documents."}},"required":["countries"]},"CountriesAccessRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"}},"required":["user_id","api_key"]},"LearningDiscoverRunRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"coverage_class":{"type":"string","enum":["TRAVEL","CASCO","HOME"],"description":"Product family / coverage class.","example":"TRAVEL"},"lang":{"type":"string","minLength":2,"maxLength":3,"default":"ro","description":"Language for /ask during learning.","example":"ro"},"topic_ids":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit run to these catalog topic_id values. Omit = all active topics for class.","example":["baggage_loss","minors"]},"product_codes":{"type":"array","items":{"type":"string","minLength":1},"description":"PRODUCT scope: one learning pass per product code (instead of insurer×topic)."},"insurer_names":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit batch to these insurer names (must already have published products in the class).","example":["Asirom","Generali"]},"user_query":{"type":"string","minLength":3,"description":"Learn from a single user-style question instead of the full batch loop.","example":"Asirom acopera pierderea bagajelor la asigurarea travel?"},"fill_missing_only":{"type":"boolean","default":true,"description":"When true (default), skip insurer×topic pairs that are already indexed.","example":true},"dry_run":{"type":"boolean","default":false,"description":"When true, run the job without writing results to the learning index.","example":false},"async":{"type":"boolean","default":false,"description":"When true, start the run in background and return run_id immediately (poll GET /learning/discover/run/:run_id).","example":false}},"required":["user_id","api_key","country","coverage_class"]},"LearningDiscoverRunResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"run_id":{"type":"string","nullable":true},"index_generation":{"type":"string"},"report":{"type":"object","properties":{"insurers_scanned":{"type":"integer"},"products_scanned":{"type":"integer"},"topics_scanned":{"type":"integer"},"facts_written":{"type":"integer"},"facts_skipped":{"type":"integer"},"facts_errors":{"type":"integer"},"fill_missing_only":{"type":"boolean"},"skipped_samples":{"type":"array","items":{"type":"string"}},"error_samples":{"type":"array","items":{"type":"string"}},"fatal":{"type":"string"}},"required":["insurers_scanned","products_scanned","topics_scanned","facts_written","facts_skipped","facts_errors"]},"async":{"type":"boolean"},"status":{"type":"string","enum":["RUNNING","COMPLETED","FAILED"]}},"required":["ok","run_id","index_generation"]},"LearningDiscoverRunSwaggerBody":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"coverage_class":{"type":"string","enum":["TRAVEL","CASCO","HOME"],"description":"Product family / coverage class.","example":"TRAVEL"},"lang":{"type":"string","minLength":2,"maxLength":3,"default":"ro","description":"Language for /ask during learning.","example":"ro"},"topic_ids":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit run to these catalog topic_id values. Omit = all active topics for class.","example":["baggage_loss","minors"]},"product_codes":{"type":"array","items":{"type":"string","minLength":1},"description":"PRODUCT scope: one learning pass per product code (instead of insurer×topic)."},"insurer_names":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit batch to these insurer names (must already have published products in the class).","example":["Asirom","Generali"]},"user_query":{"type":"string","minLength":3,"description":"Learn from a single user-style question instead of the full batch loop.","example":"Asirom acopera pierderea bagajelor la asigurarea travel?"},"fill_missing_only":{"type":"boolean","default":true,"description":"When true (default), skip insurer×topic pairs that are already indexed.","example":true},"dry_run":{"type":"boolean","default":false,"description":"When true, run the job without writing results to the learning index.","example":false},"async":{"type":"boolean","default":false,"description":"When true, start the run in background and return run_id immediately (poll GET /learning/discover/run/:run_id).","example":false}},"required":["user_id","api_key","country","coverage_class"]},"DiscoverByLearningRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"Discovery question (e.g. who covers winter sports for travel).","example":"Cine acopera pentru travel sporturi de iarna?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Answer language.","example":"ro"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with progress before completion.","example":"stream"},"learn_gaps":{"type":"boolean","default":false,"description":"When true, fill missing insurers via `/ask` before answering from the index.","example":false}},"required":["user_id","api_key","query","country","lang"]},"DiscoverByLearningResponse":{"type":"object","properties":{"answer_id":{"type":"string"},"answer":{"type":"string"},"coverage_class":{"type":"string"},"topic":{"type":"string"},"topic_id":{"type":"string"},"scanned_products":{"type":"integer"},"indexed_products":{"type":"integer"},"matches":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"},"verdict":{"type":"string","enum":["covered","excluded"]},"summary":{"type":"string"}},"required":["insurer","product_code","display_name","verdict"]}},"excluded":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"},"verdict":{"type":"string","enum":["covered","excluded"]},"summary":{"type":"string"}},"required":["insurer","product_code","display_name","verdict"]}},"unknown_products":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"}},"required":["insurer","product_code","display_name"]}},"disclaimer":{"type":"string"},"index_readiness":{"type":"string","enum":["complete","partial","empty"]},"total_insurers":{"type":"integer"},"indexed_insurers":{"type":"integer"},"has_synthesis":{"type":"boolean"},"tokens_in":{"type":"number"},"tokens_out":{"type":"number"},"tokens_used":{"type":"number"},"_debug":{"type":"object","additionalProperties":{"nullable":true}}},"required":["answer_id","answer","coverage_class","topic","topic_id","scanned_products","indexed_products","matches","excluded","unknown_products","disclaimer","index_readiness","total_insurers","indexed_insurers","has_synthesis"]},"DiscoverByLearningSwaggerBody":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"Discovery question (e.g. who covers winter sports for travel).","example":"Cine acopera pentru travel sporturi de iarna?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Answer language.","example":"ro"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with progress before completion.","example":"stream"},"learn_gaps":{"type":"boolean","default":false,"description":"When true, fill missing insurers via `/ask` before answering from the index.","example":false}},"required":["user_id","api_key","query","country","lang"]}},"parameters":{}},"paths":{"/ask":{"post":{"summary":"RAG query","description":"Answer a question using the configured insurance wording catalog. Responses are grounded in published policy documents only.\n\nSend a JSON body as documented below. **Required fields:** `user_id`, `api_key`, `query`, `country`, `lang`, and `profile`. `response_transport` defaults to `sync`. Other fields are optional.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"End-user question in natural language.","example":"What does Travel Allianz Voiaj cover?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter market code for the document set (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Desired language of the answer (ISO 639-1/639-2 style code).","example":"en"},"profile":{"type":"string","enum":["speed","expert"],"description":"Answer preset: `speed` favors lower latency; `expert` favors more thorough answers.","example":"speed"},"memo":{"type":"string","description":"Optional client-supplied label for support/correlation (does not change the answer).","example":"agent 007"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with multiple event types before completion.","example":"sync"},"skip_semantic_cache":{"type":"boolean","description":"When true, do not reuse a previous cached answer for an equivalent query.","example":false},"debug":{"type":"object","properties":{"intent":{"type":"boolean"},"context":{"type":"boolean"},"metadata":{"type":"boolean"}},"description":"Optional flags; when set, the response may include extra diagnostic sections."}},"required":["user_id","api_key","query","country","lang","profile"]}}}},"responses":{"200":{"description":"Successful answer with citations","content":{"application/json":{"schema":{"type":"object","properties":{"answer":{"type":"string","description":"Natural-language answer grounded in the citations."},"citations":{"type":"array","items":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid","description":"Stable id of the cited wording document.","example":"b6575ba1-fb72-4404-924f-b1a5b2e98ea6"},"file_name":{"type":"string","description":"Published file name for the cited source.","example":"AllianzVoiaj.pdf"},"insurer":{"type":"string","description":"Insurer name for the cited source.","example":"Allianz"},"product_code":{"type":"string","description":"Product code for the cited wording.","example":"TRAVEL_VOIAJ"},"valid_from":{"type":"string","description":"Version start date for the cited wording (ISO 8601 date).","example":"2026-01-01"},"page_from":{"type":"number","description":"First page referenced in the source (1-based).","example":3},"page_to":{"type":"number","description":"Last page referenced in the source (1-based).","example":5}},"required":["document_id","file_name","insurer","product_code","valid_from"]},"description":"Sources used to support statements in the answer."},"chunks_used":{"type":"number","description":"Number of wording excerpts used to build the answer."},"retrieved_count":{"type":"number","description":"Number of candidate excerpts considered."},"reranked_count":{"type":"number","description":"Number of excerpts kept after relevance filtering."},"answer_id":{"type":"string","description":"Opaque id for this answer (support and correlation)."},"compare_export":{"type":"object","properties":{"version":{"type":"number","enum":[1]},"kind":{"type":"string","enum":["product_compare"]},"answer_id":{"type":"string"},"country":{"type":"string"},"lang":{"type":"string"},"columns":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["label","product"]},"product_code":{"type":"string"},"header":{"type":"string"},"insurer":{"type":"string"}},"required":["role","header"]}},"rows":{"type":"array","items":{"type":"object","properties":{"row_id":{"type":"string"},"label":{"type":"string"},"cells":{"type":"object","additionalProperties":{"type":"object","properties":{"value":{"type":"string"},"coverage":{"type":"string","enum":["missing","stated","partial"]},"citation_indexes":{"type":"array","items":{"type":"integer","minimum":0}}},"required":["value"]}}},"required":["row_id","label","cells"]}},"notes":{"type":"array","items":{"type":"string"}}},"required":["version","kind","answer_id","country","lang","columns","rows"],"description":"Present only for multi-product compare: structured matrix suitable for Excel export."}},"required":["answer","citations","chunks_used","retrieved_count","reranked_count","answer_id"],"example":{"answer":"Travel Allianz Voiaj covers ..","citations":[{"document_id":"b6575ba1-fb72-4404-924f-b1a5b2e98ea6","file_name":"AllianzVoiaj.pdf","insurer":"Allianz","product_code":"TRAVEL_VOIAJ","valid_from":"2026-01-01","page_from":1,"page_to":3}],"chunks_used":8,"retrieved_count":8,"reranked_count":8,"answer_id":"ans_237587e56243"}}}}},"400":{"description":"Invalid input or unsupported request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Access denied (invalid credentials or caller not allowed)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/learning/discover/run":{"post":{"summary":"Build or refresh discover-by-learning index","description":"Batch job that builds/refreshes the discover-by-learning index for a market and coverage class.\n\nBy default processes all insurers in the class × all active topics. Narrow with `insurer_names`, `topic_ids`, or `user_query`. `fill_missing_only` (default true) skips pairs already indexed. Required: `user_id`, `api_key`, `country`, `coverage_class`.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"coverage_class":{"type":"string","enum":["TRAVEL","CASCO","HOME"],"description":"Product family / coverage class.","example":"TRAVEL"},"lang":{"type":"string","minLength":2,"maxLength":3,"default":"ro","description":"Language for /ask during learning.","example":"ro"},"topic_ids":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit run to these catalog topic_id values. Omit = all active topics for class.","example":["baggage_loss","minors"]},"product_codes":{"type":"array","items":{"type":"string","minLength":1},"description":"PRODUCT scope: one learning pass per product code (instead of insurer×topic)."},"insurer_names":{"type":"array","items":{"type":"string","minLength":1},"description":"Limit batch to these insurer names (must already have published products in the class).","example":["Asirom","Generali"]},"user_query":{"type":"string","minLength":3,"description":"Learn from a single user-style question instead of the full batch loop.","example":"Asirom acopera pierderea bagajelor la asigurarea travel?"},"fill_missing_only":{"type":"boolean","default":true,"description":"When true (default), skip insurer×topic pairs that are already indexed.","example":true},"dry_run":{"type":"boolean","default":false,"description":"When true, run the job without writing results to the learning index.","example":false},"async":{"type":"boolean","default":false,"description":"When true, start the run in background and return run_id immediately (poll GET /learning/discover/run/:run_id).","example":false}},"required":["user_id","api_key","country","coverage_class"]}}}},"responses":{"200":{"description":"Run completed (see `report` for counts)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"run_id":{"type":"string","nullable":true},"index_generation":{"type":"string"},"report":{"type":"object","properties":{"insurers_scanned":{"type":"integer"},"products_scanned":{"type":"integer"},"topics_scanned":{"type":"integer"},"facts_written":{"type":"integer"},"facts_skipped":{"type":"integer"},"facts_errors":{"type":"integer"},"fill_missing_only":{"type":"boolean"},"skipped_samples":{"type":"array","items":{"type":"string"}},"error_samples":{"type":"array","items":{"type":"string"}},"fatal":{"type":"string"}},"required":["insurers_scanned","products_scanned","topics_scanned","facts_written","facts_skipped","facts_errors"]},"async":{"type":"boolean"},"status":{"type":"string","enum":["RUNNING","COMPLETED","FAILED"]}},"required":["ok","run_id","index_generation"]}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Access denied","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Catalog not ready","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/discover/by-learning":{"post":{"summary":"Discover from pre-built learning index","description":"Answers a market discovery question from the pre-built learning index (certified facts per insurer/topic), with a mandatory disclaimer (indexed N / total products).\n\nOptional `learn_gaps`: when true, fills missing insurers via `/ask` before answering. Required: `user_id`, `api_key`, `query`, `country`, `lang`. `response_transport` defaults to `sync`; use `stream` for SSE.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"},"query":{"type":"string","minLength":3,"description":"Discovery question (e.g. who covers winter sports for travel).","example":"Cine acopera pentru travel sporturi de iarna?"},"country":{"type":"string","minLength":2,"maxLength":2,"description":"Market code (e.g. RO).","example":"RO"},"lang":{"type":"string","minLength":2,"maxLength":3,"description":"Answer language.","example":"ro"},"response_transport":{"type":"string","enum":["sync","stream"],"default":"sync","description":"`sync` returns one JSON payload. `stream` uses Server-Sent Events (SSE) with progress before completion.","example":"stream"},"learn_gaps":{"type":"boolean","default":false,"description":"When true, fill missing insurers via `/ask` before answering from the index.","example":false}},"required":["user_id","api_key","query","country","lang"]}}}},"responses":{"200":{"description":"Discovery answer from the learning index","content":{"application/json":{"schema":{"type":"object","properties":{"answer_id":{"type":"string"},"answer":{"type":"string"},"coverage_class":{"type":"string"},"topic":{"type":"string"},"topic_id":{"type":"string"},"scanned_products":{"type":"integer"},"indexed_products":{"type":"integer"},"matches":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"},"verdict":{"type":"string","enum":["covered","excluded"]},"summary":{"type":"string"}},"required":["insurer","product_code","display_name","verdict"]}},"excluded":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"},"verdict":{"type":"string","enum":["covered","excluded"]},"summary":{"type":"string"}},"required":["insurer","product_code","display_name","verdict"]}},"unknown_products":{"type":"array","items":{"type":"object","properties":{"insurer":{"type":"string"},"product_code":{"type":"string"},"display_name":{"type":"string"}},"required":["insurer","product_code","display_name"]}},"disclaimer":{"type":"string"},"index_readiness":{"type":"string","enum":["complete","partial","empty"]},"total_insurers":{"type":"integer"},"indexed_insurers":{"type":"integer"},"has_synthesis":{"type":"boolean"},"tokens_in":{"type":"number"},"tokens_out":{"type":"number"},"tokens_used":{"type":"number"},"_debug":{"type":"object","additionalProperties":{"nullable":true}}},"required":["answer_id","answer","coverage_class","topic","topic_id","scanned_products","indexed_products","matches","excluded","unknown_products","disclaimer","index_readiness","total_insurers","indexed_insurers","has_synthesis"]}}}},"400":{"description":"Invalid input or topic not mapped","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Access denied","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"503":{"description":"Catalog not ready","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}}}}},"/countries":{"get":{"summary":"List enabled countries","description":"Returns country codes and labels that are currently enabled for this API. Use these codes as `country` on POST /ask. Send credentials in the JSON request body below (`Content-Type: application/json`).","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"Account identifier issued to your integration.","example":"100"},"api_key":{"type":"string","minLength":1,"maxLength":128,"description":"API key for this account (paired with `user_id`).","example":"test1"}},"required":["user_id","api_key"]}}}},"responses":{"200":{"description":"List of enabled countries","content":{"application/json":{"schema":{"type":"object","properties":{"countries":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":2,"maxLength":2,"description":"ISO-like country code (2 letters).","example":"RO"},"name":{"type":"string","description":"Human-readable country name.","example":"Romania"}},"required":["code","name"]},"description":"Countries currently enabled for questions and documents."}},"required":["countries"]}}}},"400":{"description":"Missing required parameters.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Access denied (invalid credentials or caller not allowed)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Failed to load country list","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code.","example":"INVALID_INPUT"},"message":{"type":"string","description":"Human-readable error description.","example":"country is required and must be a valid country code"},"action":{"type":"string","description":"Suggested corrective action for the client.","example":"Provide a valid country code (e.g. RO)."}},"required":["code","message"]}},"required":["error"]}}}}}}}}}