{"openapi":"3.1.0","info":{"title":"HebrewCore API","version":"1.0.0","description":"HebrewCore by [baba Hebrew](https://itsbaba.com) is the language layer for products that work in Hebrew. One REST API for:\n\n- **Translation** between Hebrew, English, Russian and more, with RTL/LTR metadata on both sides.\n- **Protected translation** that keeps prices, quantities, dates, codes, product names and interface variables exactly as written, and verifies every sentence.\n- **Account terms**: a list of names (drugs, products, brands) kept exactly in every protected translation.\n- **Render-ready display** of mixed Hebrew and English lines, and **language detection** for code-switched input.\n- **Transliteration** and **nikud** (vowel points) for display and speech.\n- The **Clinical API** for health products: verified clinical translation, streaming, record-search queries and verification.\n\n## Quick start\n\n1. Get an API key in the [dashboard](https://hc.itsbaba.com/dashboard). Access is by invitation.\n2. Send it as a bearer token.\n3. Call an endpoint:\n\n```bash\ncurl https://hc.itsbaba.com/v1/translate \\\n  -H \"Authorization: Bearer hc_live_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"text\": \"Welcome to your account\", \"target_lang\": \"he\" }'\n```\n\n## Authentication\n\nEvery endpoint except `GET /v1/health` needs `Authorization: Bearer <key>`. Keys are `hc_live_…` (production) or `hc_test_…` (sandbox), are shown once, and are stored only as a hash. Use them from your server only. TLS 1.2 or newer.\n\n## Limits\n\n| Limit | Default |\n|---|---|\n| Requests | 600 per minute per account, across all its keys, on every plan. `429 rate_limited` with `Retry-After`. |\n| Characters | Monthly characters set by your [plan](/pricing). Protected balanced counts 2×, nikud and the Clinical API 3×, smartest up to 5×; direction, detection and wrap are free. `429 quota_exceeded`. |\n| Request size | 20,000 characters (5,000 for transliterate, 10,000 for nikud). |\n\nResponses carry `X-Usage-Chars-Used`, `X-Usage-Chars-Limit`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-Content-Stored` and `Server-Timing`. Errors use one envelope: `{ \"error\": { \"type\", \"message\", \"code\" } }`.\n\n## Docs for people and for AI\n\n- [Documentation](https://hc.itsbaba.com/docs) with guides\n- [docs.md](https://hc.itsbaba.com/docs.md): the whole documentation as Markdown\n- [llms.txt](https://hc.itsbaba.com/llms.txt) and [llms-full.txt](https://hc.itsbaba.com/llms-full.txt): an index and the complete docs plus this reference, for language models\n- [openapi.json](https://hc.itsbaba.com/openapi.json): this spec\n- [API catalog](https://hc.itsbaba.com/.well-known/api-catalog) (RFC 9727) and [apis.json](https://hc.itsbaba.com/apis.json): machine-readable discovery\n","contact":{"name":"HebrewCore by baba Hebrew","url":"https://hc.itsbaba.com","email":"admin@itsbaba.com"}},"externalDocs":{"description":"Documentation (also as Markdown at /docs.md and /llms-full.txt)","url":"https://hc.itsbaba.com/docs"},"servers":[{"url":"https://hc.itsbaba.com","description":"Production"}],"tags":[{"name":"Translation","description":"Translation, protected translation, batches and transliteration. Model-backed: consumes the character quota."},{"name":"Account Terms","description":"A persistent list of names that must never change in translation: drug names, product names, brand names. Applied to every protected translation by placeholder masking."},{"name":"Directionality","description":"Deterministic RTL/LTR analysis, render-ready display output and language detection. No model, no character quota."},{"name":"Hebrew","description":"Nikud (vowel points) for display and speech, and removing them for search and normalization."},{"name":"Medical","x-displayName":"Clinical API","description":"Verified clinical translation from English to Hebrew, streaming, record-search queries and verification. Enabled per account; keys need the `medical` scope and must be used from a server."},{"name":"Reference","description":"Supported languages and the public health check."}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","description":"HebrewCore API key, sent as `Authorization: Bearer <key>`: `hc_live_…` for production, `hc_test_…` for the sandbox. Create keys in the dashboard."}},"schemas":{"TranslateResponse":{"type":"object","properties":{"id":{"type":"string","description":"Request identifier. Include it when you contact support.","example":"txn_a1b2c3d4e5f6"},"source":{"$ref":"#/components/schemas/SourceBlock"},"translation":{"$ref":"#/components/schemas/TranslationBlock"},"quality":{"type":"string","description":"Quality tier used.","example":"balanced"},"usage":{"type":"object","properties":{"characters":{"type":"integer","description":"Characters charged to the monthly quota for this request.","example":23}},"required":["characters"],"description":"What this request consumed."}},"required":["id","source","translation","quality","usage"]},"SourceBlock":{"allOf":[{"$ref":"#/components/schemas/DirectionAnalysis"},{"type":"object","properties":{"text":{"type":"string","description":"The source text as sent.","example":"Welcome to your account"}},"required":["text"]}],"description":"The source text with its directionality metadata."},"DirectionRun":{"type":"object","properties":{"text":{"type":"string","description":"The run text. Equals `input.slice(start, end)`.","example":"שלום "},"dir":{"type":"string","enum":["ltr","rtl"],"description":"Resolved direction of the run.","example":"rtl"},"script":{"type":"string","description":"ISO 15924 script of the run: `Hebr`, `Latn`, `Cyrl`, `Arab`, or `Zyyy` for digits and punctuation only.","example":"Hebr"},"lang":{"type":"string","description":"Best-effort BCP 47 language of the run, from its script. `und` when undetermined (numbers, symbols).","example":"he"},"start":{"type":"integer","description":"UTF-16 offset of the first character, inclusive.","example":0},"end":{"type":"integer","description":"UTF-16 offset after the last character, exclusive.","example":5}},"required":["text","dir","script","lang","start","end"],"description":"A maximal stretch of text with one direction, in logical order."},"DirectionAnalysis":{"type":"object","properties":{"dir":{"type":"string","enum":["ltr","rtl"],"description":"Paragraph base direction. With `base: \"auto\"` this follows the Unicode first-strong rule, matching CSS `dir=\"auto\"`.","example":"rtl"},"mixed":{"type":"boolean","description":"True when the text contains both strong right-to-left and strong left-to-right letters. Digits and invisible marks do not count.","example":true},"lang":{"type":"string","description":"Dominant BCP 47 language, from the dominant script.","example":"he"},"script":{"type":"string","description":"Dominant ISO 15924 script.","example":"Hebr"},"runs":{"type":"array","items":{"$ref":"#/components/schemas/DirectionRun"},"description":"Runs exactly as the Unicode Bidirectional Algorithm resolves them."},"display_runs":{"type":"array","items":{"$ref":"#/components/schemas/DirectionRun"},"description":"Runs for display: every left-to-right unit (a Latin term, a number with its unit, a range, a date, a percentage, a comparison such as <5) is one run, so it never splits or mirrors. Render these, or use /v1/wrap."}},"required":["dir","mixed","lang","script","runs"],"description":"Directionality metadata for one string."},"TranslationBlock":{"allOf":[{"$ref":"#/components/schemas/DirectionAnalysis"},{"type":"object","properties":{"text":{"type":"string","description":"The translation, or the source text for sentences that fell back.","example":"ברוכים הבאים לחשבון שלך"},"transliteration":{"type":["string","null"],"description":"Latin transliteration of a Hebrew result when `transliterate` was true, otherwise null.","example":"Bruchim haba'im lakheshbon shelkha"},"protection":{"$ref":"#/components/schemas/Protection"}},"required":["text","transliteration"]}],"description":"The translation with its directionality metadata."},"Protection":{"type":"object","properties":{"status":{"type":"string","enum":["ok","retried","fallback","passthrough"],"description":"Worst sentence status. `ok`: verified first time. `retried`: a sentence was retried with a stronger model and then passed. `fallback`: at least one sentence could not be verified and is returned in the source language. `passthrough`: no model was needed.","example":"ok"},"source_lang":{"type":"string","description":"Source language used for protection (detected when `source_lang` is `auto`).","example":"en"},"spans":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"What was protected: `term`, `glossary`, `number`, `ordinal`, `date`, `identifier`, `email`, `url`, `template` (interface variables), `keep`, `markup`, `code_inline`, `name` (redacted); in the clinical domain `drug`, `dose`, `abbreviation`, `code`; in the finance domain `account` (IBAN, BIC, bank account), `id_number`, `card` (all three redacted), `reference`; in the legal domain `clause`, `citation`, `defined_term` (its `render` is the rendering used throughout).","example":"date"},"value":{"type":"string","description":"The protected source value. Omitted for redacted values.","example":"04/03/2026"},"render":{"type":"string","description":"How the value was written in the translation, when it was rewritten (dates).","example":"3 באפריל 2026"},"ambiguous_date":{"type":"boolean","description":"True when a numeric date could be read two ways and `date_order` decided it.","example":true}},"required":["type"]},"description":"Every protected value, in source order."},"issues":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Check that failed, e.g. `term_missing`, `date_missing`, `number_added`, `digits_added`, `negation_lost`, `laterality_lost`, `gender_mismatch`, `meaning`, `placeholder_missing`; finance: `direction_swapped` (error), `direction_lost` (warning); legal: `modality_changed`, `defined_term_changed`.","example":"term_missing"},"severity":{"type":"string","enum":["error","warning"],"example":"error"},"detail":{"type":"string","example":"\"A-10234\" (term) is missing or altered."}},"required":["code","severity","detail"]},"description":"Problems found by the checks. Empty when every sentence passed."},"segments":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","example":"Would you like me to schedule delivery for 04/03/2026?"},"text":{"type":"string","example":"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?"},"status":{"type":"string","enum":["ok","retried","fallback","passthrough"],"example":"ok"}},"required":["source","text","status"]},"description":"Per-sentence result, in order."}},"required":["status","source_lang","spans","issues","segments"],"description":"Present when the request used protected translation."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Stable error class: `invalid_request`, `unauthorized`, `forbidden`, `not_found`, `rate_limited`, `quota_exceeded`, `internal`, `bad_gateway` or `service_unavailable`. Branch on this.","example":"unauthorized"},"message":{"type":"string","description":"Human-readable explanation. Wording may change; do not parse it.","example":"Invalid or revoked API key."},"code":{"type":"string","description":"Finer-grained reason. Equals `type` unless a more specific code applies, e.g. `unsupported_language`, `same_language`, `invalid_message_format`, `message_too_complex`, `scope_required`, `server_only`, `upstream_error`, `not_configured`, `terms_limit`, `tls_version`.","example":"unauthorized"}},"required":["type","message","code"],"description":"Error details."}},"required":["error"],"description":"Every error response uses this envelope."},"TranslateRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":20000,"description":"Text to translate, 1 to 20,000 characters. Counts toward the monthly character quota.","example":"Welcome to your account"},"source_lang":{"type":"string","description":"BCP 47 source language, or `auto` (default) to detect it.","example":"auto"},"target_lang":{"type":"string","description":"BCP 47 target language, e.g. `he`, `en`, `ru`. See GET /v1/languages.","example":"he"},"transliterate":{"type":"boolean","default":false,"description":"Include a Latin transliteration when the target is Hebrew.","example":false},"quality":{"type":"string","enum":["fast","balanced","smartest"],"default":"balanced","description":"`fast`: lowest latency, for high volume and short strings. `balanced`: the default. `smartest`: maximum nuance for long or sensitive text.","example":"balanced"},"gender":{"type":"string","enum":["male","female","general"],"description":"Grammatical gender for the reader where the target language marks it. For assistants, prefer `listener_gender` and `speaker_gender`.","example":"general"},"store":{"type":"boolean","description":"Accepted for compatibility and has no effect: HebrewCore never stores request or response text.","example":false},"message_format":{"type":"string","enum":["icu"],"description":"`icu`: the text is an ICU MessageFormat message. The result is a valid ICU message in the target language: arguments ({name}, {count, number}, {d, date, short}) and `#` are kept, plural and selectordinal branches are rewritten for the target language's CLDR categories (Hebrew one, two, other; Russian one, few, many, other; English one, other; exact matches such as =0 kept), and select keys are kept. A plural or select inside a sentence is moved to the top so every branch is a whole sentence; `protection.segments` lists each branch sentence. Always protected; Hebrew, English and Russian. Invalid ICU returns 400 `invalid_message_format`; a message that cannot be verified comes back unchanged with `protection.status: \"fallback\"`.","example":"icu"},"protect":{"type":"boolean","description":"Keep prices, quantities, numbers, dates, codes, identifiers, product names, interface variables ({name}, %s) and <keep>…</keep> text exactly as written, and verify every sentence. Implied by any protection field. Hebrew, English and Russian. Account terms switch it on automatically for these pairs.","example":true},"domain":{"type":"string","enum":["general","clinical","finance","legal"],"description":"`general` (default) for product, commerce, support and interface text. `clinical` adds clinical register and drug, dose, lab and abbreviation detection. `finance` adds a formal banking register, protects IBANs, SWIFT/BIC codes, bank account numbers (including Israeli bank-branch-account), Israeli ID numbers and card numbers (check digits verified; these values are never shown to the model), invoice, policy and transaction references, signed amounts, rates and basis points, and checks that every money direction (credit/debit, deposit/withdrawal, buy/sell, increase/decrease, gain/loss, who owes whom) is kept. `legal` adds a formal legal register, protects clause and section references (Section 4.2, Clause 7(b), סעיף 12(א), § 3) and case and statute citations, renders each defined term (\"the Company\") the same way throughout, and checks that modality (shall, may, shall not, is not required to) is kept. Any value implies `protect`.","example":"finance"},"audience":{"type":"string","enum":["clinician","patient"],"description":"Clinical domain register. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes it as plain words.","example":"patient"},"protected_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":500,"description":"Terms kept exactly as written: product names, brand names, SKUs. Up to 500, each up to 200 characters. Added to the account terms list for this request.","example":["Wireless Earbuds Pro","A-10234"]},"redact_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":200,"description":"Kept exactly and never shown to the model: customer names and other personal data. Up to 200.","example":["Dana Levi"]},"glossary":{"type":"object","additionalProperties":{"type":"string","minLength":1,"maxLength":200},"description":"Source term → required rendering in the target language. Up to 500 entries. Wins over an account term with the same text.","example":{"Checkout":"לתשלום"}},"listener_gender":{"type":"string","enum":["male","female"],"description":"Gender of the reader (\"you\"): תרצי / תרצה. Hebrew and Russian mark it; English does not. Without it, Hebrew interface text uses neutral forms.","example":"female"},"speaker_gender":{"type":"string","enum":["male","female"],"description":"Gender of the speaker (\"I\"), for an assistant or brand voice: מצאתי, я нашла / я нашёл.","example":"female"},"patient_gender":{"type":"string","enum":["male","female"],"description":"Clinical domain: gender of a patient referred to in the third person.","example":"male"},"date_order":{"type":"string","enum":["MDY","DMY"],"description":"How to read ambiguous numeric dates such as 04/03/2026. Default MDY for English sources, DMY for Hebrew and Russian.","example":"MDY"},"date_style":{"type":"string","enum":["hebrew","iso","keep"],"description":"`hebrew` (default) spells the month out in the target language (\"4 במרץ 2026\", \"4 марта 2026 г.\"); `iso`; `keep` (unambiguous dates only).","example":"hebrew"},"bidi":{"type":"string","enum":["isolate","none"],"description":"`isolate` wraps protected values in Unicode isolates in Hebrew output. Default none; see /v1/wrap.","example":"none"}},"required":["text","target_lang"]},"AnalyzeResponse":{"type":"object","properties":{"analysis":{"allOf":[{"$ref":"#/components/schemas/DirectionAnalysis"},{"description":"Present when the request sent `text`."}]},"fields":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/DirectionAnalysis"},"description":"Present when the request sent `fields`: one analysis per field name."}}},"DetectResponse":{"type":"object","properties":{"lang":{"type":"string","description":"Dominant language (BCP 47). Latin script is tagged `en`.","example":"ru"},"script":{"type":"string","description":"Dominant ISO 15924 script.","example":"Cyrl"},"dir":{"type":"string","enum":["ltr","rtl"],"description":"Base direction of the dominant language.","example":"ltr"},"confidence":{"type":"number","description":"Share of letters in the dominant language, 0 to 1.","example":0.941},"segments":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","example":"PayPal "},"start":{"type":"integer","example":21},"end":{"type":"integer","example":28},"script":{"type":"string","example":"Latn"},"lang":{"type":"string","example":"en"}},"required":["text","start","end","script","lang"]},"description":"Same-script stretches in order, e.g. ru · en (\"CBC\") · ru. Latin script is tagged en."},"languages":{"type":"array","items":{"type":"object","properties":{"lang":{"type":"string","example":"ru"},"share":{"type":"number","description":"Share of letters, 0 to 1.","example":0.941}},"required":["lang","share"]},"description":"Every language found, largest share first."}},"required":["lang","script","dir","confidence","segments","languages"]},"DetectRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":20000,"description":"Text to classify, up to 20,000 characters. Built for short, code-switched input.","example":"Можно оплатить через PayPal сегодня?"}},"required":["text"]},"TransliterateResponse":{"type":"object","properties":{"text":{"type":"string","description":"The input.","example":"שלום"},"transliteration":{"type":"string","description":"The transliterated text.","example":"shalom"},"scheme":{"type":"string","description":"Romanization scheme used.","example":"general"},"direction":{"type":"string","description":"Direction used.","example":"he-to-latin"}},"required":["text","transliteration","scheme","direction"]},"TransliterateRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":5000,"description":"Text to transliterate, up to 5,000 characters.","example":"שלום"},"direction":{"type":"string","enum":["he-to-latin","latin-to-he"],"default":"he-to-latin","description":"`he-to-latin` (default) romanizes Hebrew. `latin-to-he` writes Latin spelling in Hebrew letters, for name entry and search.","example":"he-to-latin"}},"required":["text"]},"NikudResponse":{"type":"object","properties":{"text":{"type":"string","description":"The input.","example":"שלום עולם"},"nikud":{"type":"string","description":"The vocalized text, or the input unchanged when `verified` is false.","example":"שָׁלוֹם עוֹלָם"},"verified":{"type":"boolean","description":"True when removing the points gives back exactly the input. When false, `nikud` is the input unchanged: send it to speech unvocalized or retry.","example":true}},"required":["text","nikud","verified"]},"NikudRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":10000,"description":"Hebrew text to vocalize, up to 10,000 characters. English terms and numbers pass through.","example":"שלום עולם"}},"required":["text"]},"StripNikudResponse":{"type":"object","properties":{"text":{"type":"string","description":"The input.","example":"שָׁלוֹם"},"stripped":{"type":"string","description":"The text without nikud, dagesh or cantillation. Punctuation such as the maqaf is kept.","example":"שלום"}},"required":["text","stripped"]},"StripNikudRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":20000,"description":"Hebrew text with nikud or cantillation, up to 20,000 characters.","example":"שָׁלוֹם"}},"required":["text"]},"WrapResponse":{"type":"object","properties":{"dir":{"type":"string","enum":["ltr","rtl"],"description":"Paragraph direction used.","example":"rtl"},"format":{"type":"string","description":"Format used.","example":"html"},"output":{"type":"string","description":"Render-ready text: HTML with `dir` spans, or the text with Unicode isolates or direction marks inserted.","example":"<span dir=\"rtl\">הנחה: <span dir=\"ltr\" lang=\"und\">10–20%</span> על <span dir=\"ltr\" lang=\"en\">Galaxy S25</span> עד <span dir=\"ltr\" lang=\"und\">31/12</span></span>"},"runs":{"type":"array","items":{"$ref":"#/components/schemas/DirectionRun"},"description":"The display runs the output was built from."}},"required":["dir","format","output","runs"]},"WrapRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":20000,"description":"The display line, up to 20,000 characters.","example":"הנחה: 10–20% על Galaxy S25 עד 31/12"},"format":{"type":"string","enum":["html","isolate","marks"],"default":"html","description":"`html` for the web; `isolate` (Unicode isolates) for modern text engines; `marks` (LRM/RLM) for every renderer, including older Android.","example":"html"},"base":{"type":"string","enum":["auto","ltr","rtl"],"default":"auto","description":"Paragraph direction of the display surface. Pass `rtl` for a Hebrew line even when it starts with a Latin term.","example":"rtl"}},"required":["text"]},"BatchTranslateResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/TranslationBlock"},"description":"One translation per item, in input order."},"usage":{"type":"object","properties":{"characters":{"type":"integer","description":"Characters charged to the monthly quota for this request.","example":23}},"required":["characters"],"description":"What this request consumed."}},"required":["results","usage"]},"BatchTranslateRequest":{"type":"object","properties":{"items":{"type":"array","items":{"type":"string","minLength":1,"maxLength":5000},"minItems":1,"maxItems":50,"description":"1 to 50 strings, each up to 5,000 characters. A protected batch carries at most 20,000 characters in total.","example":["{count} items in your cart","Checkout","Last updated %s ago"]},"target_lang":{"type":"string","description":"BCP 47 target language, applied to every item.","example":"he"},"source_lang":{"type":"string","description":"BCP 47 source language, or `auto` (default).","example":"auto"},"transliterate":{"type":"boolean","default":false,"description":"Include a Latin transliteration when the target is Hebrew.","example":false},"quality":{"type":"string","enum":["fast","balanced","smartest"],"default":"balanced","description":"Quality tier, applied to every item.","example":"balanced"},"gender":{"type":"string","enum":["male","female","general"],"description":"Grammatical gender for the reader where the target language marks it.","example":"general"},"message_format":{"type":"string","enum":["icu"],"description":"`icu`: every item is an ICU MessageFormat message. Each result is a valid ICU message in the target language: arguments ({name}, {count, number}, {d, date, short}) and `#` are kept, plural and selectordinal branches are rewritten for the target language's CLDR categories (Hebrew one, two, other; Russian one, few, many, other; English one, other; exact matches such as =0 kept), and select keys are kept. A plural or select inside a sentence is moved to the top so every branch is a whole sentence; `protection.segments` lists each branch sentence. Always protected; Hebrew, English and Russian. Invalid ICU returns 400 `invalid_message_format`; a message that cannot be verified comes back unchanged with `protection.status: \"fallback\"`.","example":"icu"},"protect":{"type":"boolean","description":"Keep prices, quantities, numbers, dates, codes, identifiers, product names, interface variables ({name}, %s) and <keep>…</keep> text exactly as written, and verify every sentence. Implied by any protection field. Hebrew, English and Russian. Account terms switch it on automatically for these pairs.","example":true},"domain":{"type":"string","enum":["general","clinical","finance","legal"],"description":"`general` (default) for product, commerce, support and interface text. `clinical` adds clinical register and drug, dose, lab and abbreviation detection. `finance` adds a formal banking register, protects IBANs, SWIFT/BIC codes, bank account numbers (including Israeli bank-branch-account), Israeli ID numbers and card numbers (check digits verified; these values are never shown to the model), invoice, policy and transaction references, signed amounts, rates and basis points, and checks that every money direction (credit/debit, deposit/withdrawal, buy/sell, increase/decrease, gain/loss, who owes whom) is kept. `legal` adds a formal legal register, protects clause and section references (Section 4.2, Clause 7(b), סעיף 12(א), § 3) and case and statute citations, renders each defined term (\"the Company\") the same way throughout, and checks that modality (shall, may, shall not, is not required to) is kept. Any value implies `protect`.","example":"finance"},"audience":{"type":"string","enum":["clinician","patient"],"description":"Clinical domain register. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes it as plain words.","example":"patient"},"protected_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":500,"description":"Terms kept exactly as written: product names, brand names, SKUs. Up to 500, each up to 200 characters. Added to the account terms list for this request.","example":["Wireless Earbuds Pro","A-10234"]},"redact_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":200,"description":"Kept exactly and never shown to the model: customer names and other personal data. Up to 200.","example":["Dana Levi"]},"glossary":{"type":"object","additionalProperties":{"type":"string","minLength":1,"maxLength":200},"description":"Source term → required rendering in the target language. Up to 500 entries. Wins over an account term with the same text.","example":{"Checkout":"לתשלום"}},"listener_gender":{"type":"string","enum":["male","female"],"description":"Gender of the reader (\"you\"): תרצי / תרצה. Hebrew and Russian mark it; English does not. Without it, Hebrew interface text uses neutral forms.","example":"female"},"speaker_gender":{"type":"string","enum":["male","female"],"description":"Gender of the speaker (\"I\"), for an assistant or brand voice: מצאתי, я нашла / я нашёл.","example":"female"},"patient_gender":{"type":"string","enum":["male","female"],"description":"Clinical domain: gender of a patient referred to in the third person.","example":"male"},"date_order":{"type":"string","enum":["MDY","DMY"],"description":"How to read ambiguous numeric dates such as 04/03/2026. Default MDY for English sources, DMY for Hebrew and Russian.","example":"MDY"},"date_style":{"type":"string","enum":["hebrew","iso","keep"],"description":"`hebrew` (default) spells the month out in the target language (\"4 במרץ 2026\", \"4 марта 2026 г.\"); `iso`; `keep` (unambiguous dates only).","example":"hebrew"},"bidi":{"type":"string","enum":["isolate","none"],"description":"`isolate` wraps protected values in Unicode isolates in Hebrew output. Default none; see /v1/wrap.","example":"none"}},"required":["items","target_lang"]},"LanguagesResponse":{"type":"object","properties":{"languages":{"type":"array","items":{"$ref":"#/components/schemas/Language"},"description":"Every supported language."}},"required":["languages"]},"Language":{"type":"object","properties":{"code":{"type":"string","description":"BCP 47 code to pass as `source_lang` or `target_lang`.","example":"he"},"name":{"type":"string","description":"English name.","example":"Hebrew"},"native":{"type":"string","description":"Name in the language itself.","example":"עברית"},"dir":{"type":"string","enum":["ltr","rtl"],"description":"Writing direction.","example":"rtl"}},"required":["code","name","native","dir"]},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","description":"`ok` when the API is serving.","example":"ok"},"db":{"type":"string","description":"`ok`, or `error` when the database check failed.","example":"ok"},"version":{"type":"string","description":"API version.","example":"1.0.0"}},"required":["status","db","version"]},"MedicalTranslateResponse":{"type":"object","properties":{"id":{"type":"string","description":"Request identifier.","example":"med_a1b2c3d4e5f6"},"text":{"type":"string","description":"The whole Hebrew document: every segment joined with its prefix and suffix.","example":"את נוטלת Eliquis 5 mg פעמיים ביום. המינון שלך שונה ב־4 במרץ 2026."},"segments":{"type":"array","items":{"$ref":"#/components/schemas/MedicalSegment"},"description":"One entry per sentence, in order."},"stats":{"$ref":"#/components/schemas/MedicalStats"},"usage":{"type":"object","properties":{"characters":{"type":"integer","description":"Characters charged.","example":77}},"required":["characters"]}},"required":["id","text","segments","stats","usage"]},"MedicalSegment":{"type":"object","properties":{"index":{"type":"integer","description":"Position of the sentence, from 0.","example":0},"prefix":{"type":"string","description":"Markdown structure emitted before the text (list marker, heading).","example":"- "},"suffix":{"type":"string","description":"Whitespace or structure after the text. Join `prefix + text + suffix` for every segment to rebuild the document.","example":"\n"},"source":{"type":"string","description":"The English sentence.","example":"You are taking Eliquis 5 mg twice a day."},"text":{"type":"string","description":"Verified Hebrew, or the English source when status is `fallback`.","example":"את נוטלת Eliquis 5 mg פעמיים ביום."},"status":{"type":"string","enum":["ok","retried","fallback","passthrough"],"description":"`ok`: verified first time. `retried`: passed after one retry with a stronger model. `fallback`: no translation passed, `text` is the English. `passthrough`: structure or values only, no model needed.","example":"ok"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/MedicalIssue"},"description":"Why a sentence was retried or fell back. Empty for `ok`."},"spans":{"type":"array","items":{"$ref":"#/components/schemas/MedicalSpan"},"description":"Protected values in this sentence. Redacted names and identifiers are left out."}},"required":["index","prefix","suffix","source","text","status","issues","spans"]},"MedicalIssue":{"type":"object","properties":{"code":{"type":"string","description":"Check that failed: `term_missing`, `date_missing`, `number_added`, `digits_added`, `negation_lost`, `laterality_lost`, `laterality_swapped`, `gender_mismatch`, `meaning`, `placeholder_missing`, `length_ratio`, `provider_error` and others.","example":"negation_lost"},"severity":{"type":"string","enum":["error","warning"],"description":"`error` blocks the sentence; `warning` is informational.","example":"error"},"detail":{"type":"string","description":"Human-readable explanation.","example":"The source says \"no known allergies\"; the translation drops the negation."}},"required":["code","severity","detail"]},"MedicalSpan":{"type":"object","properties":{"type":{"type":"string","description":"What was protected: `drug`, `dose`, `abbreviation`, `code`, `number`, `date`, `term`, `glossary`, `identifier`, `name` and others.","example":"dose"},"value":{"type":"string","description":"The protected source value. Omitted for names and identifiers.","example":"5 mg"},"render":{"type":"string","description":"How the value was written in the Hebrew, when it was rewritten (dates).","example":"4 במרץ 2026"},"ambiguous_date":{"type":"boolean","description":"True when a numeric date could be read two ways and `date_order` decided it.","example":true}},"required":["type"]},"MedicalStats":{"type":"object","properties":{"segments":{"type":"integer","description":"Total sentences.","example":2},"ok":{"type":"integer","example":2},"retried":{"type":"integer","example":0},"fallback":{"type":"integer","description":"Sentences returned in English. Treat them as untranslated.","example":0},"passthrough":{"type":"integer","example":0}},"required":["segments","ok","retried","fallback","passthrough"]},"MedicalTranslateRequest":{"type":"object","properties":{"audience":{"type":"string","enum":["clinician","patient"],"default":"clinician","description":"Who reads the Hebrew. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes dosing shorthand (BID, PRN) as plain words.","example":"patient"},"reader_gender":{"type":"string","enum":["male","female"],"description":"Gender of the reader, the person the text calls \"you\". Omit when unknown.","example":"female"},"patient_gender":{"type":"string","enum":["male","female"],"description":"Gender of the patient in third-person references. Inferred from he/she when omitted.","example":"male"},"protected_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":500,"description":"Kept verbatim. Pass the patient's medication and problem lists from the record. Up to 500, each up to 200 characters. Added to the account terms list for this request.","example":["Eliquis 5 mg BID","atrial fibrillation"]},"redact_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":200,"description":"Kept verbatim and never shown to the model (patient and staff names). Up to 200.","example":["Dana Levi"]},"glossary":{"type":"object","additionalProperties":{"type":"string","minLength":1,"maxLength":200},"description":"English term → required Hebrew rendering. Up to 500 entries.","example":{"hypertension":"יתר לחץ דם"}},"date_order":{"type":"string","enum":["MDY","DMY"],"default":"MDY","description":"How to read ambiguous numeric dates in the source. US records are MDY.","example":"MDY"},"date_style":{"type":"string","enum":["hebrew","iso","keep"],"default":"hebrew","description":"`hebrew` writes \"4 במרץ 2026\"; `iso` writes 2026-03-04; `keep` leaves unambiguous dates as written (an ambiguous one is still rewritten). A two-digit year is kept as written.","example":"hebrew"},"bidi":{"type":"string","enum":["isolate","none"],"default":"isolate","description":"`isolate` wraps English values in Unicode isolates so \"5 mg\" never renders as \"mg 5\". `none` returns plain text.","example":"isolate"},"text":{"type":"string","minLength":1,"maxLength":20000,"description":"English text, 1 to 20,000 characters. Markdown lists, headings and tables keep their structure. Counts toward the monthly character quota.","example":"Based on your records, you are taking Eliquis 5 mg twice a day. Your dose was changed on 03/04/2026."}},"required":["text"]},"MedicalQueryResponse":{"type":"object","properties":{"query":{"type":"string","description":"English query for your record search.","example":"Is the patient still taking metformin?"},"terms":{"type":"array","items":{"type":"object","properties":{"hebrew":{"type":"string","example":"מטפורמין"},"english":{"type":"string","example":"metformin"},"source":{"type":"string","enum":["known_terms","lexicon","glossary"],"description":"Where the mapping came from.","example":"known_terms"}},"required":["hebrew","english","source"]},"description":"Hebrew spellings that were mapped back to English terms."},"usage":{"type":"object","properties":{"characters":{"type":"integer","example":33}},"required":["characters"]}},"required":["query","terms","usage"]},"MedicalQueryRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The Hebrew question, up to 2,000 characters.","example":"האם המטופלת עדיין לוקחת מטפורמין?"},"known_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":500,"description":"English terms from the patient's record, used to map Hebrew spellings back. Up to 500. Account terms are added automatically.","example":["metformin","lisinopril"]},"glossary":{"type":"object","additionalProperties":{"type":"string","minLength":1,"maxLength":200},"description":"English term → Hebrew rendering, used to map the Hebrew back to English.","example":{"metformin":"מטפורמין"}}},"required":["text"]},"MedicalVerifyResponse":{"type":"object","properties":{"pass":{"type":"boolean","description":"True when no issue has severity `error`.","example":false},"issues":{"type":"array","items":{"$ref":"#/components/schemas/MedicalIssue"},"description":"Every problem found."},"usage":{"type":"object","properties":{"characters":{"type":"integer","description":"Characters charged: source plus translation.","example":72}},"required":["characters"]}},"required":["pass","issues","usage"]},"MedicalVerifyRequest":{"type":"object","properties":{"source":{"type":"string","minLength":1,"maxLength":20000,"description":"The English source, up to 20,000 characters.","example":"Metformin 500 mg BID since 03/04/2026."},"translation":{"type":"string","minLength":1,"maxLength":40000,"description":"The Hebrew to check, up to 40,000 characters.","example":"Metformin 50 mg BID מאז 03/04/2026."},"protected_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":500,"description":"Terms that must appear verbatim. Up to 500.","example":["Metformin"]},"redact_terms":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":200,"description":"Names replaced before the reviewer sees the text. Up to 200.","example":["Dana Levi"]},"glossary":{"type":"object","additionalProperties":{"type":"string","minLength":1,"maxLength":200},"description":"English term → required Hebrew rendering.","example":{"hypertension":"יתר לחץ דם"}},"date_order":{"type":"string","enum":["MDY","DMY"],"default":"MDY","description":"How to read ambiguous numeric dates in the source.","example":"MDY"},"verification":{"type":"string","enum":["strict","standard"],"default":"standard","description":"`standard` (default) runs the deterministic checks. `strict` adds an independent model review for meaning changes.","example":"standard"}},"required":["source","translation"]},"AccountTermList":{"type":"object","properties":{"terms":{"type":"array","items":{"$ref":"#/components/schemas/AccountTerm"}},"limit":{"type":"integer","example":2000}},"required":["terms","limit"]},"AccountTerm":{"type":"object","properties":{"id":{"type":"string","example":"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f"},"term":{"type":"string","example":"Acamol","description":"Kept exactly as written in every protected translation."},"translations":{"type":"object","properties":{"he":{"type":"string"},"en":{"type":"string"},"ru":{"type":"string"}},"example":{"he":"אקמול"},"description":"Optional required rendering per target language. When set for the target, it replaces the term; otherwise the term is kept verbatim."},"note":{"type":["string","null"],"example":"paracetamol 500 mg brand","description":"Your own note, up to 500 characters."},"created_at":{"type":"string","example":"2026-01-15T09:30:00.000Z","description":"ISO 8601 timestamp."}},"required":["id","term","translations","note","created_at"]},"AccountTermsUpserted":{"type":"object","properties":{"terms":{"type":"array","items":{"$ref":"#/components/schemas/AccountTerm"}},"count":{"type":"integer"}},"required":["terms","count"]},"AccountTermsUpsert":{"type":"object","properties":{"terms":{"type":"array","items":{"type":"object","properties":{"term":{"type":"string","minLength":1,"maxLength":200,"example":"Optalgin"},"translations":{"type":"object","properties":{"he":{"type":"string","minLength":1,"maxLength":200},"en":{"type":"string","minLength":1,"maxLength":200},"ru":{"type":"string","minLength":1,"maxLength":200}},"additionalProperties":false,"example":{"he":"אופטלגין","ru":"Оптальгин"}},"note":{"type":["string","null"],"maxLength":500}},"required":["term"]},"minItems":1,"maxItems":2000}},"required":["terms"]}},"parameters":{}},"paths":{"/v1/translate":{"post":{"operationId":"translate","tags":["Translation"],"summary":"Translate text","description":"Translate one text between Hebrew, English, Russian and the other languages in GET /v1/languages, and attach RTL/LTR metadata (`dir`, `mixed`, `lang`, `script`, `runs`) to both the source and the result.\n\n**Protected translation.** Add `protect: true` or any protection field (`protected_terms`, `redact_terms`, `glossary`, `listener_gender`, `speaker_gender`, `domain` (`general`, `clinical`, `finance`, `legal`), `date_order`, `date_style`) to keep prices, quantities, numbers, dates, codes, identifiers, product names and interface variables exactly as written. Every sentence is then checked; one that cannot be verified comes back in the source language with `status: \"fallback\"`. Protection is available between Hebrew, English and Russian, and switches on automatically for these pairs when the account has [account terms](/docs#terms).\n\n**ICU messages.** With `message_format: \"icu\"`, `text` is an ICU MessageFormat message and the result is a valid ICU message in the target language, with arguments and `#` kept and plural branches rewritten for the target language (Hebrew one, two, other; Russian one, few, many, other).\n\n**Quota.** Consumes the monthly character quota: the length of `text`. A request that fails upstream is not charged.\n\n**Limits.** `text` up to 20,000 characters. Not idempotent: the same request translated twice may differ in wording, never in protected values.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranslateRequest"},"examples":{"simple":{"summary":"Interface text to Hebrew","value":{"text":"Welcome to your account","target_lang":"he","transliterate":true}},"commerce":{"summary":"Shopping assistant reply, protected","description":"Prices, quantities, the order number, the product name and the date come back unchanged; the date is rewritten so it cannot be misread.","value":{"text":"I found your order #A-10234: 2 × Wireless Earbuds Pro for $129.99. Would you like me to schedule delivery for 04/03/2026?","source_lang":"en","target_lang":"he","protect":true,"protected_terms":["Wireless Earbuds Pro","A-10234"],"listener_gender":"female","speaker_gender":"female","quality":"fast"}},"support_ru":{"summary":"Support reply to Russian, protected","value":{"text":"Your refund of €45.00 was issued on 12/05/2026. I could not find any other open requests.","target_lang":"ru","protect":true,"speaker_gender":"female","date_order":"DMY","quality":"fast"}},"hebrew_to_english":{"summary":"Hebrew customer message to English","value":{"text":"ההזמנה שלי מס׳ A-10234 עוד לא הגיעה, אפשר לבדוק?","target_lang":"en","protect":true}},"clinical":{"summary":"Clinical text for a patient","value":{"text":"Take Eliquis 5 mg twice a day. Do not stop taking it before your procedure on 03/04/2026 unless your doctor tells you to.","target_lang":"he","domain":"clinical","audience":"patient","listener_gender":"male","protected_terms":["Eliquis 5 mg"]}},"finance":{"summary":"Bank transfer confirmation, finance domain","description":"The amount keeps its sign, the IBAN is never shown to the model, the reference stays exact, and the translation is rejected if debit and credit are swapped.","value":{"text":"We debited -$1,250.00 from your account and credited it to IBAN IL62 0108 0000 0009 9999 999 on 03/04/2026. Reference: TRX-88412.","source_lang":"en","target_lang":"he","domain":"finance"}},"legal":{"summary":"Contract clause, legal domain","description":"Section references stay exact, \"the Company\" is rendered the same way in every sentence, and the translation is rejected if \"may\" and \"shall not\" change force.","value":{"text":"Acme Ltd. (the \"Company\") may terminate this Agreement under Section 12.3, but the Customer shall not assign its rights without the Company's prior written consent.","source_lang":"en","target_lang":"he","domain":"legal"}},"icu":{"summary":"ICU plural message","description":"The result is an ICU message with the Hebrew plural categories one, two and other.","value":{"text":"{count, plural, one {# item} other {# items}} in your cart","source_lang":"en","target_lang":"he","message_format":"icu"}}}}}},"responses":{"200":{"description":"Translation result","headers":{"X-Usage-Chars-Used":{"description":"Characters used this month by the account, including this request.","schema":{"type":"integer","example":1523}},"X-Usage-Chars-Limit":{"description":"Monthly character quota of the account.","schema":{"type":"integer","example":100000}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranslateResponse"},"examples":{"simple":{"summary":"Plain translation","value":{"id":"txn_a1b2c3d4e5f6","source":{"text":"Welcome to your account","dir":"ltr","mixed":false,"lang":"en","script":"Latn","runs":[{"text":"Welcome to your account","dir":"ltr","script":"Latn","lang":"en","start":0,"end":23}]},"translation":{"text":"ברוכים הבאים לחשבון שלך","transliteration":"Bruchim haba'im lakheshbon shelkha","dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"ברוכים הבאים לחשבון שלך","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":23}]},"quality":"balanced","usage":{"characters":23}}},"protected":{"summary":"Protected translation","value":{"id":"txn_9f8e7d6c5b4a","source":{"text":"Would you like me to schedule delivery for 04/03/2026?","dir":"ltr","mixed":false,"lang":"en","script":"Latn","runs":[{"text":"Would you like me to schedule delivery for 04/03/2026?","dir":"ltr","script":"Latn","lang":"en","start":0,"end":54}]},"translation":{"text":"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?","transliteration":null,"dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":41}],"protection":{"status":"ok","source_lang":"en","spans":[{"type":"date","value":"04/03/2026","render":"3 באפריל 2026","ambiguous_date":true}],"issues":[],"segments":[{"source":"Would you like me to schedule delivery for 04/03/2026?","text":"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?","status":"ok"}]}},"quality":"fast","usage":{"characters":54}}},"icu":{"summary":"ICU plural message","value":{"id":"txn_4d3c2b1a0f9e","source":{"text":"{count, plural, one {# item} other {# items}} in your cart","dir":"ltr","mixed":false,"lang":"en","script":"Latn","runs":[{"text":"{count, plural, one {# item} other {# items}} in your cart","dir":"ltr","script":"Latn","lang":"en","start":0,"end":58}]},"translation":{"text":"{count, plural, one {פריט אחד בעגלת הקניות} two {שני פריטים בעגלת הקניות} other {# פריטים בעגלת הקניות}}","transliteration":null,"dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"{count, plural, one {פריט אחד בעגלת הקניות} two {שני פריטים בעגלת הקניות} other {# פריטים בעגלת הקניות}}","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":104}],"protection":{"status":"ok","source_lang":"en","spans":[],"issues":[],"segments":[{"source":"# item in your cart","text":"פריט אחד בעגלת הקניות","status":"ok"},{"source":"# items in your cart","text":"שני פריטים בעגלת הקניות","status":"ok"},{"source":"# items in your cart","text":"# פריטים בעגלת הקניות","status":"ok"}]}},"quality":"balanced","usage":{"characters":58}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"unsupported_language":{"summary":"Protection outside Hebrew, English and Russian","value":{"error":{"type":"invalid_request","message":"Protected translation supports Hebrew (he), English (en) and Russian (ru).","code":"unsupported_language"}}},"same_language":{"summary":"Source and target are the same","value":{"error":{"type":"invalid_request","message":"source_lang and target_lang must differ.","code":"same_language"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}},"502":{"description":"The model provider failed or returned an empty result. Nothing was charged. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Model provider error","value":{"error":{"type":"bad_gateway","message":"Translation provider error.","code":"upstream_error"}}}}}}},"503":{"description":"A model feature is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Feature not configured","value":{"error":{"type":"service_unavailable","message":"Translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/analyze":{"post":{"operationId":"analyze","tags":["Directionality"],"summary":"Analyze directionality","description":"Resolve the RTL/LTR structure of one string (`text`) or a whole record at once (`fields`, a map of name → string). Returns the base direction, whether the text mixes directions, the dominant language and script, and two run lists: `runs` exactly as the Unicode Bidirectional Algorithm resolves them, and `display_runs` that keep every left-to-right unit (a price, a range, a date, a model number) whole.\n\n**Quota.** Deterministic, no model. Does not consume the character quota; counts toward the rate limit only.\n\n**Limits.** Send exactly one of `text` or `fields`. Up to 100 fields and 20,000 characters in total. Idempotent: the same input always gives the same output.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":20000,"description":"A single string, up to 20,000 characters. Send this or `fields`.","example":"שלום world"},"fields":{"type":"object","additionalProperties":{"type":"string","maxLength":20000},"description":"A map of field name → string, up to 100 fields and 20,000 characters in total. Send this or `text`.","example":{"title":"מסמך Q3 ready","subtitle":"Read the summary"}},"base":{"type":"string","enum":["auto","ltr","rtl"],"default":"auto","description":"Paragraph direction to resolve against. `auto` (default) uses the first strong letter.","example":"auto"}},"title":"AnalyzeRequest","description":"Provide exactly one of `text` (a single string) or `fields` (a map of name → string). Max 20,000 chars per string; up to 100 fields."},"examples":{"text":{"summary":"Single string","value":{"text":"שלום world"}},"fields":{"summary":"A whole record at once","value":{"fields":{"title":"מסמך Q3 ready","subtitle":"Read the summary"}}}}}}},"responses":{"200":{"description":"Directionality analysis","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeResponse"},"examples":{"text":{"summary":"Single string","value":{"analysis":{"dir":"rtl","mixed":true,"lang":"he","script":"Hebr","runs":[{"text":"שלום ","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":5},{"text":"world","dir":"ltr","script":"Latn","lang":"en","start":5,"end":10}],"display_runs":[{"text":"שלום ","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":5},{"text":"world","dir":"ltr","script":"Latn","lang":"en","start":5,"end":10}]}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"fields_or_text":{"summary":"Both or neither of text and fields","value":{"error":{"type":"invalid_request","message":"Provide either \"text\" or \"fields\".","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/detect":{"post":{"operationId":"detect","tags":["Directionality"],"summary":"Detect language","description":"Detect the dominant language, script and base direction of a string, with one segment per language. Built for short, code-switched input such as chat messages, search queries and voice transcripts: a brand, product name or acronym inside a Hebrew or Russian sentence (\"PayPal\", \"iPhone\", \"API\") does not change the dominant language, and Hebrew prefixes joined by a hyphen (\"ה-API\") are split correctly. Links and email addresses are ignored. Latin script is tagged `en`.\n\n**Quota.** Deterministic, no model. Does not consume the character quota.\n\n**Limits.** `text` up to 20,000 characters. Idempotent.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectRequest"},"examples":{"russian":{"summary":"Russian with a brand name","value":{"text":"Можно оплатить через PayPal сегодня?"}},"hebrew":{"summary":"Hebrew with an English term","value":{"text":"איך מחברים את ה-API לחשבון?"}}}}}},"responses":{"200":{"description":"Detection","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectResponse"},"examples":{"russian":{"summary":"Russian with a brand name","value":{"lang":"ru","script":"Cyrl","dir":"ltr","confidence":0.941,"segments":[{"text":"Можно оплатить через ","start":0,"end":21,"script":"Cyrl","lang":"ru"},{"text":"PayPal ","start":21,"end":28,"script":"Latn","lang":"en"},{"text":"сегодня?","start":28,"end":36,"script":"Cyrl","lang":"ru"}],"languages":[{"lang":"ru","share":0.941},{"lang":"en","share":0.059}]}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"fields_or_text":{"summary":"Both or neither of text and fields","value":{"error":{"type":"invalid_request","message":"Provide either \"text\" or \"fields\".","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/transliterate":{"post":{"operationId":"transliterate","tags":["Translation"],"summary":"Transliterate between Hebrew and Latin script","description":"Romanize Hebrew into Latin letters (`direction: \"he-to-latin\"`, the default), or write Latin spelling in Hebrew letters (`direction: \"latin-to-he\"`), which is useful for name entry and search.\n\n**Quota.** Consumes the monthly character quota: the length of `text`.\n\n**Limits.** `text` up to 5,000 characters.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransliterateRequest"},"examples":{"romanize":{"summary":"Hebrew to Latin","value":{"text":"שלום"}},"name_entry":{"summary":"Latin spelling to Hebrew letters","value":{"text":"Rivka Cohen","direction":"latin-to-he"}}}}}},"responses":{"200":{"description":"Transliteration","headers":{"X-Usage-Chars-Used":{"description":"Characters used this month by the account, including this request.","schema":{"type":"integer","example":1523}},"X-Usage-Chars-Limit":{"description":"Monthly character quota of the account.","schema":{"type":"integer","example":100000}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransliterateResponse"},"examples":{"romanize":{"summary":"Hebrew to Latin","value":{"text":"שלום","transliteration":"shalom","scheme":"general","direction":"he-to-latin"}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"unsupported_language":{"summary":"Protection outside Hebrew, English and Russian","value":{"error":{"type":"invalid_request","message":"Protected translation supports Hebrew (he), English (en) and Russian (ru).","code":"unsupported_language"}}},"same_language":{"summary":"Source and target are the same","value":{"error":{"type":"invalid_request","message":"source_lang and target_lang must differ.","code":"same_language"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}},"502":{"description":"The model provider failed or returned an empty result. Nothing was charged. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Model provider error","value":{"error":{"type":"bad_gateway","message":"Translation provider error.","code":"upstream_error"}}}}}}},"503":{"description":"A model feature is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Feature not configured","value":{"error":{"type":"service_unavailable","message":"Translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/nikud":{"post":{"operationId":"addNikud","tags":["Hebrew"],"summary":"Add nikud (vowel points)","description":"Add full nikud to Hebrew text, for vocalized display, learning materials and text-to-speech, where unvocalized Hebrew is ambiguous. English terms and numbers are left untouched.\n\nThe result is checked: `verified: true` means removing the points gives back your text (only the vowel letters ו and י may differ, which does not change pronunciation). When `verified` is false, `nikud` is your text unchanged; send it to speech unvocalized or retry.\n\n**Quota.** Consumes the monthly character quota: the length of `text`.\n\n**Limits.** `text` up to 10,000 characters.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NikudRequest"},"examples":{"speech":{"summary":"Text for speech","value":{"text":"שלום עולם"}},"mixed":{"summary":"Hebrew with an English term and a number","value":{"text":"ההזמנה שלך ל-Galaxy S25 תגיע בעוד 3 ימים"}}}}}},"responses":{"200":{"description":"Vocalized text","headers":{"X-Usage-Chars-Used":{"description":"Characters used this month by the account, including this request.","schema":{"type":"integer","example":1523}},"X-Usage-Chars-Limit":{"description":"Monthly character quota of the account.","schema":{"type":"integer","example":100000}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NikudResponse"},"examples":{"speech":{"summary":"Verified","value":{"text":"שלום עולם","nikud":"שָׁלוֹם עוֹלָם","verified":true}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"unsupported_language":{"summary":"Protection outside Hebrew, English and Russian","value":{"error":{"type":"invalid_request","message":"Protected translation supports Hebrew (he), English (en) and Russian (ru).","code":"unsupported_language"}}},"same_language":{"summary":"Source and target are the same","value":{"error":{"type":"invalid_request","message":"source_lang and target_lang must differ.","code":"same_language"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}},"502":{"description":"The model provider failed or returned an empty result. Nothing was charged. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Model provider error","value":{"error":{"type":"bad_gateway","message":"Translation provider error.","code":"upstream_error"}}}}}}},"503":{"description":"A model feature is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Feature not configured","value":{"error":{"type":"service_unavailable","message":"Translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/strip-nikud":{"post":{"operationId":"stripNikud","tags":["Hebrew"],"summary":"Remove nikud","description":"Remove nikud, dagesh and cantillation marks, keeping punctuation such as the maqaf. Use it for normalization, search keys and de-duplication, or to get display text back from vocalized speech text.\n\n**Quota.** Deterministic, no model. Does not consume the character quota.\n\n**Limits.** `text` up to 20,000 characters. Idempotent.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripNikudRequest"},"examples":{"basic":{"summary":"Vocalized word","value":{"text":"שָׁלוֹם"}}}}}},"responses":{"200":{"description":"Stripped text","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripNikudResponse"},"examples":{"basic":{"summary":"Stripped","value":{"text":"שָׁלוֹם","stripped":"שלום"}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"fields_or_text":{"summary":"Both or neither of text and fields","value":{"error":{"type":"invalid_request","message":"Provide either \"text\" or \"fields\".","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/wrap":{"post":{"operationId":"wrap","tags":["Directionality"],"summary":"Wrap a line for display","description":"Render-ready bidirectional output for one display line. Every left-to-right unit (a Latin term, a price, a number with its unit, a range such as \"10–20%\", a date, a percentage, a comparison such as \"<5\") is kept whole and in order, so no digit, range or sign is reversed or mirrored inside a Hebrew line.\n\nPick `format` for the surface: `html` for the web, React and webviews; `isolate` (Unicode isolates) for iOS, Android 7+ and current browsers; `marks` (LRM/RLM) for older Android, embedded displays and any renderer you cannot test. Pass `base: \"rtl\"` for a Hebrew line even when it starts with a Latin term.\n\n**Quota.** Deterministic, no model. Does not consume the character quota. Fast enough to call per line at render time.\n\n**Limits.** `text` up to 20,000 characters. Idempotent.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WrapRequest"},"examples":{"html":{"summary":"Hebrew sale line for the web","value":{"text":"הנחה: 10–20% על Galaxy S25 עד 31/12","format":"html","base":"rtl"}},"marks":{"summary":"Order status for an older Android screen","value":{"text":"ההזמנה A-10234 יוצאת ב־08:30","format":"marks","base":"rtl"}}}}}},"responses":{"200":{"description":"Wrapped output","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WrapResponse"},"examples":{"html":{"summary":"HTML output","value":{"dir":"rtl","format":"html","output":"<span dir=\"rtl\">הנחה: <span dir=\"ltr\" lang=\"und\">10–20%</span> על <span dir=\"ltr\" lang=\"en\">Galaxy S25</span> עד <span dir=\"ltr\" lang=\"und\">31/12</span></span>","runs":[{"text":"הנחה: ","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":6},{"text":"10–20%","dir":"ltr","script":"Zyyy","lang":"und","start":6,"end":12},{"text":" על ","dir":"rtl","script":"Hebr","lang":"he","start":12,"end":16},{"text":"Galaxy S25","dir":"ltr","script":"Latn","lang":"en","start":16,"end":26},{"text":" עד ","dir":"rtl","script":"Hebr","lang":"he","start":26,"end":30},{"text":"31/12","dir":"ltr","script":"Zyyy","lang":"und","start":30,"end":35}]}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"fields_or_text":{"summary":"Both or neither of text and fields","value":{"error":{"type":"invalid_request","message":"Provide either \"text\" or \"fields\".","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/translate/batch":{"post":{"operationId":"translateBatch","tags":["Translation"],"summary":"Translate a batch of strings","description":"Translate up to 50 strings to one target language in a single call, for example the interface strings of a screen or the fields of a product. Results come back in input order. Every option of /v1/translate applies to all items.\n\nWith protection (any protection field, or account terms for Hebrew, English and Russian pairs), each item carries its own `protection` block and interface variables such as `{count}`, `{{name}}` and `%s` stay in place.\n\n**Quota.** Consumes the monthly character quota: the total length of all items.\n\n**Limits.** 1 to 50 items, each up to 5,000 characters. A protected batch carries at most 20,000 characters in total.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTranslateRequest"},"examples":{"ui_strings":{"summary":"Interface strings with variables and a glossary","value":{"items":["{count} items in your cart","Checkout","Last updated %s ago"],"target_lang":"he","protect":true,"glossary":{"Checkout":"לתשלום"}}},"russian":{"summary":"Short labels to Russian","value":{"items":["Save","Cancel","Delete account"],"target_lang":"ru","quality":"fast"}},"icu":{"summary":"ICU messages to Russian","value":{"items":["{count, plural, one {# file} other {# files}} uploaded","{name} invited you"],"target_lang":"ru","message_format":"icu"}}}}}},"responses":{"200":{"description":"Batch results (input order)","headers":{"X-Usage-Chars-Used":{"description":"Characters used this month by the account, including this request.","schema":{"type":"integer","example":1523}},"X-Usage-Chars-Limit":{"description":"Monthly character quota of the account.","schema":{"type":"integer","example":100000}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTranslateResponse"},"examples":{"ui_strings":{"summary":"Results in input order","value":{"results":[{"text":"{count} פריטים בעגלת הקניות שלך","transliteration":null,"dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"{count} פריטים בעגלת הקניות שלך","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":31}]},{"text":"לתשלום","transliteration":null,"dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"לתשלום","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":6}]},{"text":"עודכן לאחרונה לפני %s","transliteration":null,"dir":"rtl","mixed":false,"lang":"he","script":"Hebr","runs":[{"text":"עודכן לאחרונה לפני %s","dir":"rtl","script":"Hebr","lang":"he","start":0,"end":21}]}],"usage":{"characters":53}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}},"unsupported_language":{"summary":"Protection outside Hebrew, English and Russian","value":{"error":{"type":"invalid_request","message":"Protected translation supports Hebrew (he), English (en) and Russian (ru).","code":"unsupported_language"}}},"same_language":{"summary":"Source and target are the same","value":{"error":{"type":"invalid_request","message":"source_lang and target_lang must differ.","code":"same_language"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}},"502":{"description":"The model provider failed or returned an empty result. Nothing was charged. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Model provider error","value":{"error":{"type":"bad_gateway","message":"Translation provider error.","code":"upstream_error"}}}}}}},"503":{"description":"A model feature is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Feature not configured","value":{"error":{"type":"service_unavailable","message":"Translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/languages":{"get":{"operationId":"listLanguages","tags":["Reference"],"summary":"List supported languages","description":"Every language HebrewCore translates to and from, with its English and native name and its writing direction. Use `code` as `source_lang` or `target_lang`. Protected translation covers Hebrew, English and Russian. Does not consume the character quota.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Languages","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguagesResponse"},"examples":{"list":{"summary":"Supported languages (truncated)","value":{"languages":[{"code":"he","name":"Hebrew","native":"עברית","dir":"rtl"},{"code":"en","name":"English","native":"English","dir":"ltr"},{"code":"ar","name":"Arabic","native":"العربية","dir":"rtl"},{"code":"ru","name":"Russian","native":"Русский","dir":"ltr"}]}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/health":{"get":{"operationId":"health","tags":["Reference"],"summary":"Health check","description":"Liveness and database check. Public: no API key needed, no rate limit, no quota. Use it for uptime monitoring.","security":[],"responses":{"200":{"description":"Health","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"examples":{"ok":{"summary":"Healthy","value":{"status":"ok","db":"ok","version":"1.0.0"}}}}}}}}},"/v1/medical/translate":{"post":{"operationId":"medicalTranslate","tags":["Medical"],"summary":"Translate clinical English into verified Hebrew","description":"Translate a complete English clinical text into Israeli medical Hebrew for a clinician or a patient. Drug names, doses, lab values, units, ICD-10 codes, clinical abbreviations, identifiers and every number are replaced with placeholders the model cannot change, and restored afterwards. Sentences are translated in parallel and returned in order.\n\nEvery sentence is checked (placeholders, numbers, negation, laterality, length) and reviewed by an independent model for meaning changes. A rejected sentence is retried once with a stronger model; if it still fails, the English is returned with `status: \"fallback\"`. Unverified Hebrew is never returned. Account terms apply, with their Hebrew rendering when one is set.\n\n**Access.** Needs a key with the `medical` scope, called from a server (a browser `Origin` header is refused). Nothing is stored; responses carry `Cache-Control: no-store`.\n\n**Quota.** Consumes the monthly character quota: the length of `text`. Refunded when the provider fails for every sentence.\n\n**Limits.** `text` up to 20,000 characters.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalTranslateRequest"},"examples":{"patient":{"summary":"Medication summary for a patient","value":{"text":"You are taking Eliquis 5 mg twice a day. Your dose was changed on 03/04/2026.","audience":"patient","reader_gender":"female","protected_terms":["Eliquis 5 mg","atrial fibrillation"]}},"clinician":{"summary":"Note for a clinician, with a redacted name and a glossary","value":{"text":"Dana Levi, 67F, hx of hypertension and T2DM. Metformin 500 mg PO BID. Denies chest pain. Follow up in 2 weeks.","audience":"clinician","patient_gender":"female","redact_terms":["Dana Levi"],"glossary":{"hypertension":"יתר לחץ דם"}}}}}}},"responses":{"200":{"description":"Translation","headers":{"Cache-Control":{"description":"Always `no-store` on the Clinical API.","schema":{"type":"string","example":"no-store"}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalTranslateResponse"},"examples":{"patient":{"summary":"Verified sentences","value":{"id":"med_a1b2c3d4e5f6","text":"את נוטלת Eliquis 5 mg פעמיים ביום. המינון שלך שונה ב־4 במרץ 2026.","segments":[{"index":0,"prefix":"","suffix":" ","source":"You are taking Eliquis 5 mg twice a day.","text":"את נוטלת Eliquis 5 mg פעמיים ביום.","status":"ok","issues":[],"spans":[{"type":"term","value":"Eliquis 5 mg"}]},{"index":1,"prefix":"","suffix":"","source":"Your dose was changed on 03/04/2026.","text":"המינון שלך שונה ב־4 במרץ 2026.","status":"ok","issues":[],"spans":[{"type":"date","value":"03/04/2026","render":"4 במרץ 2026","ambiguous_date":true}]}],"stats":{"segments":2,"ok":2,"retried":0,"fallback":0,"passthrough":0},"usage":{"characters":77}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_required":{"summary":"Key not enabled for the Clinical API","value":{"error":{"type":"forbidden","message":"This API key is not enabled for medical translation. Contact HebrewCore to enable it.","code":"scope_required"}}},"server_only":{"summary":"Called from a browser","value":{"error":{"type":"forbidden","message":"Medical endpoints must be called from your server, never from a browser.","code":"server_only"}}},"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"502":{"description":"The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Provider unavailable","value":{"error":{"type":"bad_gateway","message":"The model provider is unavailable. No Hebrew was produced.","code":"upstream_error"}}},"unverified":{"summary":"Query could not be verified (query endpoint)","value":{"error":{"type":"bad_gateway","message":"The query could not be translated without losing a protected value.","code":"unverified"}}}}}}},"503":{"description":"Medical translation is not configured on this server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Not configured","value":{"error":{"type":"service_unavailable","message":"Medical translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/medical/translate/stream":{"post":{"operationId":"medicalTranslateStream","tags":["Medical"],"summary":"Translate clinical English, streamed as Server-Sent Events","description":"Same body and checks as /v1/medical/translate, answered as Server-Sent Events so the first verified sentence can be shown before the last is done.\n\nEvents: `segment` (a MedicalSegment, strictly in order), then `done` (`{ stats, usage }`) or `error` (`{ error: { type, message } }`). For English that your model is still generating, use the WebSocket at `wss://hc.itsbaba.com/v1/medical/stream` instead (see [the docs](/docs#medical-stream)).\n\n**Quota.** Charged up front for the length of `text`; refunded when the provider fails for every sentence.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalTranslateRequest"},"examples":{"patient":{"summary":"Medication summary for a patient","value":{"text":"You are taking Eliquis 5 mg twice a day. Your dose was changed on 03/04/2026.","audience":"patient","reader_gender":"female","protected_terms":["Eliquis 5 mg","atrial fibrillation"]}},"clinician":{"summary":"Note for a clinician, with a redacted name and a glossary","value":{"text":"Dana Levi, 67F, hx of hypertension and T2DM. Metformin 500 mg PO BID. Denies chest pain. Follow up in 2 weeks.","audience":"clinician","patient_gender":"female","redact_terms":["Dana Levi"],"glossary":{"hypertension":"יתר לחץ דם"}}}}}}},"responses":{"200":{"description":"A stream of `segment` events, then `done` or `error`.","headers":{"Cache-Control":{"description":"Always `no-store` on the Clinical API.","schema":{"type":"string","example":"no-store"}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"text/event-stream":{"schema":{"type":"string"},"example":"event: segment\ndata: {\"index\":0,\"prefix\":\"\",\"suffix\":\" \",\"source\":\"You are taking Eliquis 5 mg twice a day.\",\"text\":\"את נוטלת Eliquis 5 mg פעמיים ביום.\",\"status\":\"ok\",\"issues\":[],\"spans\":[{\"type\":\"term\",\"value\":\"Eliquis 5 mg\"}]}\n\nevent: segment\ndata: {\"index\":1,\"prefix\":\"\",\"suffix\":\"\",\"source\":\"Your dose was changed on 03/04/2026.\",\"text\":\"המינון שלך שונה ב־4 במרץ 2026.\",\"status\":\"ok\",\"issues\":[],\"spans\":[{\"type\":\"date\",\"value\":\"03/04/2026\",\"render\":\"4 במרץ 2026\",\"ambiguous_date\":true}]}\n\nevent: done\ndata: {\"stats\":{\"segments\":2,\"ok\":2,\"retried\":0,\"fallback\":0,\"passthrough\":0},\"usage\":{\"characters\":77}}\n"}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_required":{"summary":"Key not enabled for the Clinical API","value":{"error":{"type":"forbidden","message":"This API key is not enabled for medical translation. Contact HebrewCore to enable it.","code":"scope_required"}}},"server_only":{"summary":"Called from a browser","value":{"error":{"type":"forbidden","message":"Medical endpoints must be called from your server, never from a browser.","code":"server_only"}}},"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"502":{"description":"The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Provider unavailable","value":{"error":{"type":"bad_gateway","message":"The model provider is unavailable. No Hebrew was produced.","code":"upstream_error"}}},"unverified":{"summary":"Query could not be verified (query endpoint)","value":{"error":{"type":"bad_gateway","message":"The query could not be translated without losing a protected value.","code":"unverified"}}}}}}},"503":{"description":"Medical translation is not configured on this server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Not configured","value":{"error":{"type":"service_unavailable","message":"Medical translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/medical/stream":{"get":{"operationId":"medicalStreamSocket","tags":["Medical"],"summary":"Clinical translation over a WebSocket, for English that is still being generated","description":"Open a WebSocket (`wss://hc.itsbaba.com/v1/medical/stream`) with the usual `Authorization: Bearer` key, from your server. Use it when the English text is itself streaming from a language model: send it as it arrives and receive verified Hebrew one sentence at a time, in order.\n\n**You send** JSON text frames (each under 64 KB):\n- `{\"type\":\"start\", ...options}` once, with the same options as /v1/medical/translate (audience, reader_gender, patient_gender, protected_terms, redact_terms, glossary, date_order, date_style, bidi).\n- `{\"type\":\"delta\",\"text\":\"...\"}` for each piece of English, as it arrives.\n- `{\"type\":\"end\"}` when the English is complete.\n\n**You receive** `{\"type\":\"ready\"}`, then `{\"type\":\"segment\", ...}` for each verified sentence (same shape as a /v1/medical/translate segment), then `{\"type\":\"done\",\"stats\":{...},\"usage\":{\"characters\",\"billed_characters\"}}`. Errors arrive as `{\"type\":\"error\",\"error\":{\"type\",\"message\"}}` and close the socket.\n\n**Limits.** 100,000 characters, 5,000 messages, 1,000 sentences and 30 minutes per session; the socket closes after 60 seconds without a message; at most 10 open sessions per account. Each sentence is charged as it starts (3× characters), so a quota stop is exact.","security":[{"ApiKeyAuth":[]}],"responses":{"101":{"description":"Switching Protocols: the WebSocket is open."},"400":{"description":"Not a WebSocket upgrade request (`upgrade_required`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks Clinical access, or the request came from a browser.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit, or too many open sessions (`too_many_sessions`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/medical/query":{"post":{"operationId":"medicalQuery","tags":["Medical"],"summary":"Turn a Hebrew question into an English record query","description":"Translate a Hebrew question into an English query for your record search and model. English terms, numbers and dates in the question are kept exactly (Hebrew day-first dates become ISO dates). Hebrew spellings of English drug names are mapped back to English, preferring the patient's own terms from `known_terms` and the account terms over the built-in lexicon.\n\n**Quota.** Consumes the monthly character quota: the length of `text`. Refunded when the query cannot be verified (`502 unverified`) or the provider fails.\n\n**Limits.** `text` up to 2,000 characters.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalQueryRequest"},"examples":{"medication":{"summary":"Medication question","value":{"text":"האם המטופלת עדיין לוקחת מטפורמין?","known_terms":["metformin","lisinopril"]}},"lab":{"summary":"Lab question with a date","value":{"text":"מה היה ה-HbA1c בבדיקה מ-12/05/2026?"}}}}}},"responses":{"200":{"description":"English query","headers":{"Cache-Control":{"description":"Always `no-store` on the Clinical API.","schema":{"type":"string","example":"no-store"}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalQueryResponse"},"examples":{"medication":{"summary":"English query","value":{"query":"Is the patient still taking metformin?","terms":[{"hebrew":"מטפורמין","english":"metformin","source":"known_terms"}],"usage":{"characters":33}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_required":{"summary":"Key not enabled for the Clinical API","value":{"error":{"type":"forbidden","message":"This API key is not enabled for medical translation. Contact HebrewCore to enable it.","code":"scope_required"}}},"server_only":{"summary":"Called from a browser","value":{"error":{"type":"forbidden","message":"Medical endpoints must be called from your server, never from a browser.","code":"server_only"}}},"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"502":{"description":"The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Provider unavailable","value":{"error":{"type":"bad_gateway","message":"The model provider is unavailable. No Hebrew was produced.","code":"upstream_error"}}},"unverified":{"summary":"Query could not be verified (query endpoint)","value":{"error":{"type":"bad_gateway","message":"The query could not be translated without losing a protected value.","code":"unverified"}}}}}}},"503":{"description":"Medical translation is not configured on this server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Not configured","value":{"error":{"type":"service_unavailable","message":"Medical translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/medical/verify":{"post":{"operationId":"medicalVerify","tags":["Medical"],"summary":"Verify a Hebrew translation against its English source","description":"Check Hebrew that was produced some other way, for example by your own model answering in Hebrew, against its English source. Every drug, dose, lab value, code and number from the English must appear verbatim, dates must be unambiguous, no number may be added, and negation and laterality must survive.\n\n`verification: \"strict\"` adds an independent model review for meaning changes; names in `redact_terms` and identifiers are replaced before the reviewer sees the text. `standard` is deterministic.\n\n**Quota.** Consumes the monthly character quota: the length of `source` plus `translation`.\n\n**Limits.** `source` up to 20,000 characters, `translation` up to 40,000.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalVerifyRequest"},"examples":{"failing":{"summary":"A translation with a changed dose and a misreadable date","value":{"source":"Metformin 500 mg BID since 03/04/2026.","translation":"Metformin 50 mg BID מאז 03/04/2026."}},"strict":{"summary":"Strict review of a patient message","value":{"source":"No known drug allergies. Stop ibuprofen 3 days before surgery.","translation":"אין אלרגיות ידועות לתרופות. יש להפסיק ibuprofen 3 ימים לפני הניתוח.","protected_terms":["ibuprofen"],"verification":"strict"}}}}}},"responses":{"200":{"description":"Verdict","headers":{"Cache-Control":{"description":"Always `no-store` on the Clinical API.","schema":{"type":"string","example":"no-store"}},"X-Content-Stored":{"description":"Whether the request text or the result was stored. `false` in the default no-retention mode.","schema":{"type":"boolean","example":false}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalVerifyResponse"},"examples":{"failing":{"summary":"Three errors","value":{"pass":false,"issues":[{"code":"term_missing","severity":"error","detail":"\"500 mg\" (dose) is missing or altered."},{"code":"date_missing","severity":"error","detail":"The date \"03/04/2026\" is missing or kept in an order a Hebrew reader will misread."},{"code":"number_added","severity":"error","detail":"The number 50 does not appear in the source."}],"usage":{"characters":72}}},"passing":{"summary":"Passes","value":{"pass":true,"issues":[],"usage":{"characters":118}}}}}}},"400":{"description":"Invalid request: the body failed validation or a value is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Invalid body","value":{"error":{"type":"invalid_request","message":"Required","code":"invalid_request"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_required":{"summary":"Key not enabled for the Clinical API","value":{"error":{"type":"forbidden","message":"This API key is not enabled for medical translation. Contact HebrewCore to enable it.","code":"scope_required"}}},"server_only":{"summary":"Called from a browser","value":{"error":{"type":"forbidden","message":"Medical endpoints must be called from your server, never from a browser.","code":"server_only"}}},"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute (`rate_limited`), or the monthly character quota is used up (`quota_exceeded`). Retry `rate_limited` after a short wait; `quota_exceeded` lasts until the quota resets or the plan changes.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}},"quota_exceeded":{"summary":"Monthly character quota","value":{"error":{"type":"quota_exceeded","message":"Monthly character quota of 100,000 reached.","code":"quota_exceeded"}}}}}}},"502":{"description":"The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"upstream_error":{"summary":"Provider unavailable","value":{"error":{"type":"bad_gateway","message":"The model provider is unavailable. No Hebrew was produced.","code":"upstream_error"}}},"unverified":{"summary":"Query could not be verified (query endpoint)","value":{"error":{"type":"bad_gateway","message":"The query could not be translated without losing a protected value.","code":"unverified"}}}}}}},"503":{"description":"Medical translation is not configured on this server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_configured":{"summary":"Not configured","value":{"error":{"type":"service_unavailable","message":"Medical translation is not configured on this server.","code":"not_configured"}}}}}}}}}},"/v1/terms":{"get":{"operationId":"listTerms","tags":["Account Terms"],"summary":"List the account's protected terms","description":"Every account term, sorted by term, with the account limit. Account terms are names that must never change in translation (drug, product and brand names). Every protected translation on the account keeps them exactly as written, or uses `translations[target]` when it is set: /v1/translate, /v1/translate/batch and the Clinical API. They are applied by placeholder masking, so the model never sees them and cannot alter them, and they switch protection on automatically for Hebrew, English and Russian pairs.\n\n**Quota.** Does not consume the character quota.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Terms","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountTermList"},"examples":{"list":{"summary":"Two terms","value":{"terms":[{"id":"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f","term":"Optalgin","translations":{"he":"אופטלגין","ru":"Оптальгин"},"note":"brand name","created_at":"2026-01-15T09:30:00.000Z"},{"id":"7a1d2e3f-4b5c-4d6e-8f90-1a2b3c4d5e6f","term":"Wireless Earbuds Pro","translations":{},"note":null,"created_at":"2026-01-15T09:30:00.000Z"}],"limit":2000}}}}}},"400":{"description":"Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Empty term","value":{"error":{"type":"invalid_request","message":"Each term needs a non-empty \"term\".","code":"invalid_request"}}},"unsupported_language":{"summary":"Unsupported rendering language","value":{"error":{"type":"invalid_request","message":"translations: unsupported language \"fr\". Use he, en or ru.","code":"invalid_request"}}},"terms_limit":{"summary":"Account limit","value":{"error":{"type":"invalid_request","message":"An account may hold at most 2000 terms.","code":"terms_limit"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}},"post":{"operationId":"upsertTerms","tags":["Account Terms"],"summary":"Add or update protected terms (upsert by exact term)","description":"Add terms, or update existing ones. Terms are matched by exact text after trimming and collapsing spaces: sending an existing term replaces its `translations` and `note`. When one request names the same term twice, the later entry wins. Returns the stored terms.\n\n`translations` accepts `he`, `en` and `ru`. Leave it out to keep the term exactly as written in every language.\n\n**Limits.** 2,000 terms per account. A term or rendering is up to 200 characters and may not contain ⟦ or ⟧; a note is up to 500 characters. Changes reach new requests within 30 seconds. Idempotent: repeating a request leaves the same list.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountTermsUpsert"},"examples":{"products":{"summary":"Product and brand names kept as written","value":{"terms":[{"term":"Wireless Earbuds Pro"},{"term":"Galaxy S25","note":"product line"}]}},"drugs":{"summary":"Drug names with fixed renderings","value":{"terms":[{"term":"Optalgin","translations":{"he":"אופטלגין","ru":"Оптальгин"},"note":"brand name"},{"term":"Eliquis","translations":{"he":"אליקוויס"}}]}}}}}},"responses":{"200":{"description":"Stored terms","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountTermsUpserted"},"examples":{"products":{"summary":"Stored","value":{"terms":[{"id":"9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d","term":"Galaxy S25","translations":{},"note":"product line","created_at":"2026-01-15T09:30:00.000Z"},{"id":"7a1d2e3f-4b5c-4d6e-8f90-1a2b3c4d5e6f","term":"Wireless Earbuds Pro","translations":{},"note":null,"created_at":"2026-01-15T09:30:00.000Z"}],"count":2}}}}}},"400":{"description":"Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Empty term","value":{"error":{"type":"invalid_request","message":"Each term needs a non-empty \"term\".","code":"invalid_request"}}},"unsupported_language":{"summary":"Unsupported rendering language","value":{"error":{"type":"invalid_request","message":"translations: unsupported language \"fr\". Use he, en or ru.","code":"invalid_request"}}},"terms_limit":{"summary":"Account limit","value":{"error":{"type":"invalid_request","message":"An account may hold at most 2000 terms.","code":"terms_limit"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}},"/v1/terms/{id}":{"delete":{"operationId":"deleteTerm","tags":["Account Terms"],"summary":"Delete one protected term","description":"Remove one term by id. New requests stop using it within 30 seconds.","security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","example":"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}},"Server-Timing":{"description":"Time spent on our side, in milliseconds: `auth` (with the key lookup source), `ratelimit` and `total`. Compare `total` with your measured latency to separate network time.","schema":{"type":"string","example":"auth;desc=\"memory\";dur=0, ratelimit;dur=0, total;dur=842"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"]},"examples":{"deleted":{"summary":"Deleted","value":{"deleted":true}}}}}},"400":{"description":"Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"Empty term","value":{"error":{"type":"invalid_request","message":"Each term needs a non-empty \"term\".","code":"invalid_request"}}},"unsupported_language":{"summary":"Unsupported rendering language","value":{"error":{"type":"invalid_request","message":"translations: unsupported language \"fr\". Use he, en or ru.","code":"invalid_request"}}},"terms_limit":{"summary":"Account limit","value":{"error":{"type":"invalid_request","message":"An account may hold at most 2000 terms.","code":"terms_limit"}}}}}}},"401":{"description":"Missing, malformed, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_key":{"summary":"No API key","value":{"error":{"type":"unauthorized","message":"Missing or malformed API key. Use header: Authorization: Bearer hc_live_…","code":"unauthorized"}}},"revoked_key":{"summary":"Invalid or revoked key","value":{"error":{"type":"unauthorized","message":"Invalid or revoked API key.","code":"unauthorized"}}}}}}},"403":{"description":"The connection used TLS older than 1.2.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"tls_version":{"summary":"TLS older than 1.2","value":{"error":{"type":"forbidden","message":"TLS 1.2 or newer is required.","code":"tls_version"}}}}}}},"404":{"description":"No term with this id on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_found":{"summary":"Unknown id","value":{"error":{"type":"not_found","message":"No such term.","code":"not_found"}}}}}}},"429":{"description":"Too many requests this minute. Retry after a short wait.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key: 60 on Standard, 600 on Scale.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer","example":59}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"summary":"Per-minute rate limit","value":{"error":{"type":"rate_limited","message":"Rate limit of 600/min exceeded. Slow down and retry.","code":"rate_limited"}}}}}}},"500":{"description":"Unexpected server error. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal":{"summary":"Unexpected error","value":{"error":{"type":"internal","message":"Internal error.","code":"internal"}}}}}}}}}}},"webhooks":{}}