# HebrewCore API: documentation and reference > HebrewCore by baba Hebrew (https://itsbaba.com) is a REST API for products that work in Hebrew: translation between Hebrew, English, Russian and more; protected translation that keeps prices, names, codes, numbers and dates exact, with general, finance, legal and clinical domains; ICU plural messages; account terms; render-ready RTL/LTR display; language detection for code-switched input; transliteration; nikud; and the Clinical API. Solution guides cover commerce, customer support, app localization, finance, legal, education and healthcare. Base URL: https://hc.itsbaba.com. Authenticate every request (except GET /v1/health) with `Authorization: Bearer hc_live_…`. Requests and responses are JSON. Errors use `{ "error": { "type", "message", "code" } }`. This file holds the whole HebrewCore documentation followed by the complete API reference generated from https://hc.itsbaba.com/openapi.json. Web: https://hc.itsbaba.com/docs · Interactive reference: https://hc.itsbaba.com/reference · Index: https://hc.itsbaba.com/llms.txt # Documentation ## Introduction HebrewCore by [baba Hebrew](https://itsbaba.com) is the language layer for products that work in Hebrew. One REST API covers translation between Hebrew, English, Russian and more; protected translation that keeps prices, product names, codes, numbers and dates exactly as written; render-ready right-to-left / left-to-right display for any surface; language detection for code-switched input; transliteration; and nikud for display and speech. Teams use it for [commerce, customer support, app localization, finance, legal, education and healthcare](https://hc.itsbaba.com/docs#solutions). Four [domains](https://hc.itsbaba.com/docs#domains) (general, finance, legal and clinical) tune protection to the values and wording each field cannot afford to get wrong, and the [Clinical API](https://hc.itsbaba.com/docs#medical) adds streaming, record search and verification for health products. The API speaks standard JSON over HTTPS. Every endpoint lives under one base URL: ```text https://hc.itsbaba.com ``` > Prefer to explore interactively? The [API reference](https://hc.itsbaba.com/reference) renders the live OpenAPI 3.1 spec and lets you run authenticated calls in the browser. The [playground](https://hc.itsbaba.com/dashboard/playground) gives a guided UI for the most common calls. ## Quickstart 1. Create an API key in the [console](https://hc.itsbaba.com/dashboard/api-keys). 2. Send it as a bearer token on every request. 3. Call an endpoint: ```bash curl https://hc.itsbaba.com/v1/translate \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Welcome to your account", "target_lang": "he", "transliterate": true }' ``` ### Node (fetch) ```js const res = await fetch("https://hc.itsbaba.com/v1/translate", { method: "POST", headers: { "Authorization": "Bearer hc_live_YOUR_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ text: "Welcome to your account", target_lang: "he" }), }); const data = await res.json(); console.log(data.translation.text, data.translation.dir); // "…", "rtl" ``` ### Python (requests) ```python import requests r = requests.post( "https://hc.itsbaba.com/v1/translate", headers={"Authorization": "Bearer hc_live_YOUR_KEY"}, json={"text": "Welcome to your account", "target_lang": "he"}, ) print(r.json()["translation"]["text"]) ``` ## Authentication Machine-to-machine requests authenticate with an **API key** sent as a bearer token. Keys come in two modes, `hc_live_…` and `hc_test_…`. Both work the same way, with the same limits and billing; use test keys to keep development traffic separate. ```http Authorization: Bearer hc_live_… ``` Keys are shown once at creation and stored only as a hash. Create, name, and revoke them in the dashboard. The dashboard itself signs in with an email one-time code; the API never uses that session, only the bearer key. An account can hold several active keys at once, which is how you rotate without downtime: create a new key, deploy it to your servers, confirm traffic has moved (the dashboard shows each key's last use), then revoke the old one. A revoked key stops working within 30 seconds. > Treat keys as secrets. Use them from your server, never from untrusted client code or a device. Rotate immediately if one is exposed. The API accepts TLS 1.2 or newer only. ## Dashboard Sign-In The [console](https://hc.itsbaba.com/dashboard) is where you create and revoke API keys, see usage, and manage [account terms](https://hc.itsbaba.com/docs#terms). Sign in with your email address: we send a one-time code, and you type it in. There is no password and no magic link. Access is by invitation. Only invited email addresses can sign in; ask your HebrewCore contact to add a colleague. Colleagues on the same team share one account: the same keys, account terms, usage and limits. The dashboard session is separate from the API: API calls always authenticate with a bearer key. ## Playground The [playground](https://hc.itsbaba.com/dashboard/playground) runs the API from the browser with a guided form: translation, protected translation, batches, display, detection, transliteration, nikud, account terms and, when your account has it, the Clinical API. | Rule | Detail | | --- | --- | | Sign-in | Requires [dashboard sign-in](https://hc.itsbaba.com/docs#dashboard-signin) with the email one-time code. No API key is needed or stored in the browser. | | Quota and rate limit | Runs on your account's own monthly character quota and per-minute rate limit, exactly like an API call, with the same validation and response headers. | | Request size | 4,000 characters per request, across all text fields. | Use synthetic data only in the playground, since it runs in your browser. Send real patient data only from your server with an API key. ## MCP Server HebrewCore is also a remote [Model Context Protocol](https://modelcontextprotocol.io) server, so AI agents and assistants can call every capability as a tool. Each tool call runs the matching REST endpoint with your key, so validation, rate limits, the monthly character quota, account terms and Clinical access work exactly as they do over REST. | Setting | Value | | --- | --- | | Endpoint | `https://hc.itsbaba.com/mcp` | | Transport | Streamable HTTP (JSON responses, no session). Protocol versions `2026-07-28`, `2025-11-25`, `2025-06-18` and `2025-03-26`. | | Authentication | Your API key as the header `Authorization: Bearer hc_live_…`. Listing the tools works without a key; calling one needs it. | | Server card | [`/.well-known/mcp.json`](https://hc.itsbaba.com/.well-known/mcp.json) (also at `/.well-known/mcp/server-card.json`) | | Registry name | `com.itsbaba/hebrewcore` | ### Tools | Tool | What it does | | --- | --- | | `translate` | One text between Hebrew, English, Russian and more, with protected values, domains, gender and ICU plurals | | `translate_batch` | Up to 50 strings to one target language | | `analyze_direction` | RTL/LTR structure and display runs of a string or a record (free) | | `detect_language` | Dominant language, script and per-language segments (free) | | `wrap_for_display` | Render-ready HTML, isolates or marks for one display line (free) | | `transliterate` | Hebrew to Latin letters, or Latin spelling to Hebrew letters | | `add_nikud` | Full vowel points, verified | | `strip_nikud` | Remove nikud and cantillation (free) | | `list_languages` | Supported languages and their codes (free) | | `list_terms` | The account's protected terms (free) | | `add_terms` | Add or update protected terms (free) | | `delete_term` | Delete one protected term (free) | | `clinical_translate` | Clinical English to verified Hebrew (Clinical access) | | `clinical_query` | Hebrew clinical question to an English record query (Clinical access) | | `clinical_verify` | Check Hebrew against its English clinical source (Clinical access) | | `health` | Service health; needs no key | Tools marked free use no characters; the rest use the monthly character quota like the endpoint they call. Protected values (prices, amounts, account numbers, dates, doses, codes, product names) come back exactly as written, and the server tells the agent not to change them. API errors such as `quota_exceeded`, `rate_limited` or `scope_required` come back as tool errors with the same message. ### Claude Code ```text claude mcp add --transport http hebrewcore https://hc.itsbaba.com/mcp \ --header "Authorization: Bearer hc_live_YOUR_KEY" ``` ### Claude Desktop and claude.ai The server authenticates with a static API key, and Claude custom connectors that only offer OAuth cannot send it. Connect Claude Desktop through `mcp-remote`, which adds the header. In `claude_desktop_config.json`: ```json { "mcpServers": { "hebrewcore": { "command": "npx", "args": ["-y", "mcp-remote", "https://hc.itsbaba.com/mcp", "--header", "Authorization:${HC_AUTH}"], "env": { "HC_AUTH": "Bearer hc_live_YOUR_KEY" } } } } ``` The same `mcp-remote` setup works for any client that cannot send a header itself. ### Cursor In `~/.cursor/mcp.json` or the project's `.cursor/mcp.json`: ```json { "mcpServers": { "hebrewcore": { "url": "https://hc.itsbaba.com/mcp", "headers": { "Authorization": "Bearer hc_live_YOUR_KEY" } } } } ``` ### VS Code In `.vscode/mcp.json`. VS Code asks for the key once and stores it securely: ```json { "inputs": [ { "type": "promptString", "id": "hebrewcore-key", "description": "HebrewCore API key", "password": true } ], "servers": { "hebrewcore": { "type": "http", "url": "https://hc.itsbaba.com/mcp", "headers": { "Authorization": "Bearer ${input:hebrewcore-key}" } } } } ``` ### OpenAI API and Agents SDK As a remote MCP tool in the Responses API: ```text from openai import OpenAI client = OpenAI() response = client.responses.create( model="gpt-5.5", tools=[{ "type": "mcp", "server_label": "hebrewcore", "server_url": "https://hc.itsbaba.com/mcp", "headers": {"Authorization": "Bearer hc_live_YOUR_KEY"}, "require_approval": "never", }], input="Translate 'Your order of 3 items ships on 04/03/2026' into Hebrew, keeping the date and quantity exact.", ) print(response.output_text) ``` With the OpenAI Agents SDK (Python): ```text from agents import Agent, HostedMCPTool agent = Agent( name="Hebrew assistant", tools=[HostedMCPTool(tool_config={ "type": "mcp", "server_label": "hebrewcore", "server_url": "https://hc.itsbaba.com/mcp", "headers": {"Authorization": "Bearer hc_live_YOUR_KEY"}, "require_approval": "never", })], ) ``` > Keep the key on your side: in a config file on your machine, a secret store, or your server. Never put it in a prompt, a shared configuration or browser code. Clinical tools also need a key with Clinical access and refuse calls that come from a browser. ## Directionality The defining feature of HebrewCore is structured directionality. For any string, the API returns: | Field | Description | | --- | --- | | `dir` | Paragraph base direction, `"rtl"` or `"ltr"`. With `base:"auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. | | `mixed` | `true` when the text contains both strong RTL and strong LTR characters (invisible bidi marks and digits do not count). | | `lang` | Best-effort BCP-47 language from the dominant script (e.g. `he`, `en`). | | `script` | Dominant ISO-15924 script (`Hebr`, `Latn`, `Arab`, …). | | `runs[]` | Maximal same-direction segments in logical order. Each run has `text`, `dir`, `script`, `lang`, `start`, and `end` (UTF-16 offsets, `end` exclusive, so `text.slice(start,end)` reproduces the run). | Example: `"שלום world"` resolves to two runs you can render independently: - `שלום`: rtl · he · Hebr · 0–5 - `world`: ltr · en · Latn · 5–10 For display, use `display_runs` or `/v1/wrap`. They keep every left-to-right unit whole, so a price, a range such as "10–20%", a date, a model number or a comparison such as "<5" never splits or mirrors inside a Hebrew line. `/v1/analyze`, `/v1/detect`, `/v1/wrap`, and `/v1/strip-nikud` are deterministic, run with no language model, and do not consume your character quota. ## Protected Values Some text must never change in translation: prices and currency, quantities, dates, order and account numbers, product and brand names, codes, interface variables, and in regulated fields doses, units and lab values. HebrewCore finds these values, replaces each with a placeholder the model cannot alter, and restores the original afterwards. It then checks every sentence: each protected value and every number must come back unchanged, and negation, left/right and grammatical gender must match. A sentence that cannot be verified is returned in its source language, flagged, rather than translated wrongly. Each [domain](https://hc.itsbaba.com/docs#domains) adds its own values and checks. | Protected automatically | Examples | | --- | --- | | Numbers, amounts and signs | `$129.99`, `₪149.90`, `10–20%`, `<5`, `2 ×` | | Dates and times | `04/03/2026` (rewritten so it cannot be misread), `08:30` | | Identifiers and contact details | order and account numbers, emails, phone numbers, URLs | | Interface markup | `{name}`, `{{count}}`, `%s`, `…` | | Your terms | [Account terms](https://hc.itsbaba.com/docs#terms), plus `protected_terms` and `glossary` entries on the request: product names, brand names, drug names, legal terms | | Financial values, with `domain: "finance"` | IBANs, SWIFT/BIC, bank account and card numbers, Israeli ID numbers, invoice and policy numbers, rates and basis points | | Legal references, with `domain: "legal"` | clause and section references, defined terms, statute and case citations | | Clinical terms, with `domain: "clinical"` | drug names, doses, units, lab values, clinical codes and abbreviations | ## Domains `domain` on `/v1/translate` and `/v1/translate/batch` tells protected translation what kind of text it is reading, so it knows which values to lock and which meaning changes to reject. There are four domains. `general` is the default; any other value turns protection on by itself, so you do not need `protect: true`. | Domain | Use it for | Also protects | Extra checks | | --- | --- | --- | --- | | `general` *(default)* | Product, commerce, support, interface and everyday content. | The [standard set](https://hc.itsbaba.com/docs#protection): numbers, amounts, dates, identifiers, contact details, interface variables and your terms. | Every protected value and number comes back unchanged; negation, left/right and grammatical gender must match. | | `finance` | Statements, payment and transfer notices, invoices, lending, insurance. Formal financial register. | IBANs (any country, including Israel), SWIFT/BIC codes, Israeli bank account numbers such as `12-345-678901`, Israeli ID numbers (9 digits with a check digit), card numbers (masked or full; the model only ever sees a placeholder), invoice, reference, policy and transaction numbers, signed currency amounts, percentages, basis points, interest rates and dates. | Direction words must match: credit/debit, deposit/withdrawal, increase/decrease, gain/loss, buy/sell, owe/are owed. Negation and every number are checked. | | `legal` | Contracts, terms of service, privacy policies, notices and filings. Legal register. | Clause and section references: the label is translated and the number kept exactly (`Section 4.2` becomes `סעיף 4.2`; `Clause 7(b)`, `סעיף 12(א)` and `Article III` work the same way, and `§ 3` is kept whole). Defined terms (a Capitalized Term in quotes, or defined as `("the Company")`): translated once and used the same way in every later sentence, for example `(להלן: "החברה")`. Statute and case citations, kept as written (a Hebrew statute year such as `התשנ"ט-1999` becomes `5759-1999` in English and Russian). Party names you pass in `protected_terms`, dates and amounts. | Modality must match: shall/must against may, shall not/must not against may not, and will. Negation, numbers and references must be unchanged. | | `clinical` | Patient instructions, care-team messages, clinical notes. Clinical register, for a clinician or a patient. | Drug names, doses, units, lab values, clinical codes and abbreviations. | The general checks with every drug, dose and lab value verbatim. `audience` and `patient_gender` apply. For streaming, record search and verification, use the [Clinical API](https://hc.itsbaba.com/docs#medical). | A sentence that fails a check is retried once with a stronger model, told what was wrong. If it still fails, it comes back in the source language with `status: "fallback"` and an entry in `issues`, so a flipped "credit" or a "may" that became "shall" never reaches your users. ### Span Types Every protected value is listed in `protection.spans` with a `type`. Personal and account data (`name`, `account`, `id_number`, `card`) is listed without a `value`, so it never appears in your logs through the response. | Domain | Span types | | --- | --- | | Every domain | `term`, `glossary`, `number`, `ordinal`, `date`, `identifier`, `email`, `url`, `template` (interface variables), `keep`, `markup`, `code_inline`, `name` (redacted) | | `finance` | `account` (IBAN, SWIFT/BIC, bank account), `id_number`, `card`, `reference` (invoice, policy, transaction). Amounts, percentages and basis points are `number`. | | `legal` | `clause` (`value` is the number), `defined_term` (with its `render` in the target language), `citation` | | `clinical` | `drug`, `dose`, `abbreviation`, `code` | ### Example: A Transfer Notice ```http POST /v1/translate { "text": "We debited ₪12,450.00 from account 12-345-678901 on 03/04/2026. Your interest rate increases by 0.25% to 4.75%.", "source_lang": "en", "target_lang": "he", "domain": "finance", "date_order": "DMY" } { "translation": { "text": "חייבנו את חשבון 12-345-678901 בסך ₪12,450.00 ב־3 באפריל 2026. שיעור הריבית שלך עולה ב־0.25% ל־4.75%.", "dir": "rtl", "protection": { "status": "ok", "spans": [ { "type": "number", "value": "₪12,450.00" }, { "type": "account" }, { "type": "date", "value": "03/04/2026", "render": "3 באפריל 2026", "ambiguous_date": true }, { "type": "number", "value": "0.25%" }, { "type": "number", "value": "4.75%" } ], "issues": [], … }, … } } ``` ## Quality Tiers Translation and transliteration accept an optional `quality` parameter that trades latency for depth. Direction analysis, detection, and the language list are deterministic and instant. | quality | When to use | | --- | --- | | `fast` | High volume and short strings, lowest latency. | | `balanced` *(default)* | The default. Excellent quality for everyday use. | | `smartest` | Maximum nuance for long or sensitive content. | With [protected translation](https://hc.itsbaba.com/docs#protected), every tier runs the value and number checks; `balanced` and `smartest` add an independent review of each sentence for meaning changes. ## Rate Limits & Quotas | Limit | Default | Notes | | --- | --- | --- | | Request rate | 600 requests / minute per account, across all its keys, on every plan | Exact sliding one-minute window. Returns `429 rate_limited` with a `Retry-After` header in seconds. See `X-RateLimit-*` headers. | | Monthly characters | Set by your plan (100,000 on Free) | Counts billed characters: input characters times the weight of the endpoint and quality tier (see [Plans & Pricing](https://hc.itsbaba.com/docs#pricing)). Direction, detection, wrap, strip nikud, languages and account terms are not counted. Past the limit, counted requests return `429 quota_exceeded` until the next month or a plan change. | | Per-request size | 20,000 chars (5,000 for transliterate, 10,000 for nikud, 2,000 for a clinical query) | Analyze accepts up to 100 fields, 20,000 chars total. | ### Response Headers | Header | On | Meaning | | --- | --- | --- | | `X-Usage-Chars-Used` | `translate`, `translate/batch`, `transliterate`, `nikud` | Billed characters used this month by the account, including this request. | | `X-Usage-Chars-Limit` | `translate`, `translate/batch`, `transliterate`, `nikud` | The account's monthly character quota, in billed characters. | | `X-RateLimit-Limit` | Authenticated requests | Requests allowed per minute for the key. | | `X-RateLimit-Remaining` | Authenticated requests | Requests left in the current minute. | | `X-Content-Stored` | Every endpoint that takes text | Always `false`: HebrewCore never stores the text you send or the result. | | `Server-Timing` | Authenticated requests | Time spent on our side: `auth`, `ratelimit` and `total`, in milliseconds. | | `Cache-Control` | Clinical API | Always `no-store`. | Every metered response includes usage headers: ```http X-Usage-Chars-Used: 46 X-Usage-Chars-Limit: 100000 X-RateLimit-Limit: 600 X-RateLimit-Remaining: 599 X-Content-Stored: false ``` The response body reports both amounts: `usage.characters` is the length of the input, and `usage.billed_characters` is what the request counted toward the monthly quota. A 23-character protected translation at `balanced` returns: ```text "usage": { "characters": 23, "billed_characters": 46 } ``` Key revocations and plan changes take effect within 30 seconds. Authenticated responses also carry a `Server-Timing` header with the time spent on our side, so you can tell it apart from network time when you measure latency from your own region: ```http Server-Timing: auth;desc="memory";dur=0, ratelimit;dur=0, total;dur=842 ``` ## Plans & Pricing Every plan includes the full API. Plans differ only in how many characters you can use each month. Every plan is by inquiry: [request access](https://hc.itsbaba.com/pricing) and we set up your account and arrange payment with you directly. Nothing is charged online. | Plan | Price | Monthly characters | | --- | --- | --- | | Free | $0 | 100,000 | | Starter | $49 / month | 1,000,000 | | Growth | $249 / month | 6,000,000 | | Business | $999 / month | 30,000,000 | | Enterprise | Custom | Custom | ### Every Plan Includes - Translation between Hebrew, English and Russian - Protected translation - Domains: general, finance, legal and clinical - ICU plurals - Batch translation - Directionality analysis - Language detection - Render-ready wrap - Transliteration - Nikud - Account terms - Playground - Clinical API, on request - 600 requests per minute - 2,000 protected terms ### How Characters Are Counted Billed characters are input characters times a weight. The weight depends on the endpoint and, for translation, the quality tier and whether the request is protected. Protected means any protection field, a [domain](https://hc.itsbaba.com/docs#domains), [account terms](https://hc.itsbaba.com/docs#terms) that apply, or `message_format: "icu"`. | Weight | Applies to | | --- | --- | | Not counted | Direction, detection, wrap, strip nikud, languages, account terms | | 1× | Translation (fast or balanced), transliteration, protected translation at fast | | 2× | Protected translation at balanced | | 3× | Nikud, the Clinical API, and translation at smartest | | 5× | Protected translation at smartest | ### At the Limit When the monthly characters are used up, counted requests return `429` with `quota_exceeded` until the next month starts or the plan changes. The `X-Usage-Chars-Used` and `X-Usage-Chars-Limit` headers and `usage.billed_characters` in each response show where you are. To change plans, contact us with the form on the [pricing page](https://hc.itsbaba.com/pricing) or from Plans in the console. ## Errors All errors use one envelope with a stable `type`: ```json { "error": { "type": "rate_limited", "message": "…", "code": "rate_limited" } } ``` | Status | type | Meaning | | --- | --- | --- | | `400` | invalid_request | Malformed body or parameters. | | `401` | unauthorized | Missing, invalid, or revoked API key. | | `403` | forbidden | The key lacks a scope (`scope_required`), a Clinical call came from a browser (`server_only`), or TLS is older than 1.2 (`tls_version`). | | `404` | not_found | No such route, or no such account term. | | `429` | rate_limited / quota_exceeded | Burst limit or monthly character quota. | | `500` | internal | Unexpected error. Safe to retry. | | `502` | bad_gateway | Upstream model error. Nothing is charged. Safe to retry. | | `503` | service_unavailable | A model feature is temporarily unavailable. | `code` refines `type` where it helps, for example `unsupported_language` and `same_language` on protected translation, `invalid_message_format` for ICU input that does not parse, `terms_limit` on account terms, and `upstream_error` on `502`. Branch on `type` and `code`, never on `message`. ## Privacy > The text you send and the text returned are **never stored**. We keep usage counts only (characters and request totals per day). Responses carry `X-Content-Stored: false`. This is how the service works, not a formal compliance certification; contact us for specific requirements. Model-backed endpoints call the language-model provider directly over TLS with storage turned off, never through a model reseller or a logging gateway. API data is not used to train models. Contact us for the current subprocessor list and processing regions. ## POST /v1/translate `POST /v1/translate` Translate text and attach directionality metadata to both the source and the result. | Parameter | Type | Description | | --- | --- | --- | | `text` *required* | string | 1–20,000 characters. | | `target_lang` *required* | string | BCP-47 code, e.g. `he` or `en`. | | `source_lang` | string | BCP-47 code or `"auto"` (default). | | `transliterate` | boolean | Include a Latin transliteration of a Hebrew result. Default `false`. | | `quality` | enum | `fast` · `balanced` (default) · `smartest`. | | `gender` | enum | `male` · `female` · `general`, where the language marks it. | | `message_format` | enum | `icu`: the text is an ICU MessageFormat string, and plural branches are rewritten for the target language. See [ICU plurals](https://hc.itsbaba.com/docs#icu). | | `store` | boolean | Accepted for compatibility and has no effect. HebrewCore never stores request or response text. | ### Response ```json { "id": "txn_…", "source": { "text": "Welcome to your account", "lang": "en", "dir": "ltr", "mixed": false, "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", "lang": "he", "dir": "rtl", "mixed": false, "script": "Hebr", "runs": [ { "text": "ברוכים הבאים לחשבון שלך", "dir": "rtl", "script": "Hebr", "lang": "he", "start": 0, "end": 22 } ] }, "quality": "balanced", "usage": { "characters": 23 } } ``` ## Protected Translation Add any of the fields below to `/v1/translate` or `/v1/translate/batch` to translate with [protected values](https://hc.itsbaba.com/docs#protection). Every sentence is checked before it is returned; one that cannot be verified comes back in the source language with `status: "fallback"`, so an unverified translation never reaches your users. Available between Hebrew (`he`), English (`en`) and Russian (`ru`). | Parameter | Type | Description | | --- | --- | --- | | `protect` | boolean | Turn protection on. Implied by any field below, and by [account terms](https://hc.itsbaba.com/docs#terms) for Hebrew, English and Russian pairs. | | `domain` | enum | `general` (default) for product, commerce, support and interface text · `finance` · `legal` · `clinical`. Each adds its own protected values, register and checks; see [Domains](https://hc.itsbaba.com/docs#domains). Any value except `general` implies `protect`. | | `listener_gender` | enum | `male` · `female`. Who "you" is: `תרצי` / `תרצה`. Hebrew and Russian mark it; English does not. | | `speaker_gender` | enum | `male` · `female`. Who "I" is, for an assistant or brand voice: `מצאתי`, `я нашла` / `я нашёл`. | | `patient_gender` | enum | Clinical domain: a patient referred to in the third person. | | `protected_terms` | string[] | Terms kept exactly as written: product names, brand names, SKUs. Up to 500. Added to the account terms for this request. | | `redact_terms` | string[] | Kept exactly and never shown to the model: customer names and other personal data. Up to 200. | | `glossary` | object | Source term → required rendering in the target language. Up to 500. | | `date_order` | enum | How to read ambiguous numeric dates: `MDY` (US style) or `DMY` (Israel, Europe). Default: MDY for English sources, DMY for Hebrew and Russian. | | `date_style` | enum | `hebrew` (default) spells the month out in the target language ("4 במרץ 2026", "4 марта 2026 г."); `iso`; `keep` (unambiguous dates only). | | `audience` | enum | Clinical register: `clinician` (default) or `patient`. | | `bidi` | enum | `isolate` wraps protected values in Unicode isolates in Hebrew output. Default `none`; see [/v1/wrap](https://hc.itsbaba.com/docs#wrap). | ### Quality with Protection | Quality | What runs | | --- | --- | | `fast` | The deterministic checks on every sentence (protected values, numbers, signs, negation, left/right, gender), with a retry by a stronger model and fallback. Lowest latency: suited to live chat and voice. | | `balanced` | The same, plus an independent model review of every sentence for meaning changes (negation, certainty, timing, quantities in words, who is being described). | | `smartest` | As balanced, with the strongest model translating. | ### Example: A Shopping Assistant Replying in Hebrew ```bash curl https://hc.itsbaba.com/v1/translate \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "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" }' ``` ```json { "translation": { "text": "מצאתי את ההזמנה שלך מס׳ A-10234: 2 יחידות של Wireless Earbuds Pro במחיר $129.99. האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?", "dir": "rtl", "protection": { "status": "ok", "source_lang": "en", "spans": [ { "type": "term", "value": "A-10234" }, { "type": "number", "value": "2" }, { "type": "term", "value": "Wireless Earbuds Pro" }, { "type": "number", "value": "$129.99" }, { "type": "date", "value": "04/03/2026", "render": "3 באפריל 2026", "ambiguous_date": true } ], "issues": [], "segments": [ { "source": "I found your order #A-10234: 2 × Wireless Earbuds Pro for $129.99.", "text": "מצאתי את ההזמנה שלך מס׳ A-10234: 2 יחידות של Wireless Earbuds Pro במחיר $129.99.", "status": "ok" }, { "source": "Would you like me to schedule delivery for 04/03/2026?", "text": "האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?", "status": "ok" } ] }, … } } ``` ### Example: A Support Reply in Russian ```http POST /v1/translate { "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" } → "Возврат средств в размере €45.00 был оформлен 12 мая 2026 г. Я не нашла других открытых запросов." ``` ## Account Terms Account terms are a persistent, per-account list of names that must never change in translation: drug names, product names, brand names. Add them once, in the dashboard or with the endpoints below, and every protected translation on the account keeps them exactly as written: `/v1/translate`, `/v1/translate/batch` and the [Clinical API](https://hc.itsbaba.com/docs#medical), for every key. | Behavior | Detail | | --- | --- | | Kept exactly | Every term is kept exactly as written. When a term has a rendering for the target language in `translations` (for example `translations.he`), that exact rendering is used instead. | | Placeholder masking | Terms are replaced with placeholders before the model runs and restored afterwards, so the model never sees them and cannot alter them. This is stronger than an instruction in a prompt. | | Automatic protection | When the account has terms, protection switches on automatically for Hebrew, English and Russian pairs. You do not need `protect: true`. | | Per-request fields | `protected_terms` and `glossary` still work and add to the account list. When both name the same term, the request's entry wins. | | Limits | 2,000 terms per account. A term or rendering is up to 200 characters, a note up to 500. `translations` accepts `he`, `en` and `ru`. | | Propagation | Changes apply to new requests within 30 seconds. | ### The Term Object | Field | Type | Description | | --- | --- | --- | | `id` | string | Identifier, used to delete the term. | | `term` | string | The name, exactly as it must appear. | | `translations` | object | Optional required rendering per target language: `{ "he"?, "en"?, "ru"? }`. | | `note` | string \| null | Your own note, for example why the term is protected. | | `created_at` | string | ISO 8601 timestamp. | ### POST /v1/terms `POST /v1/terms` Add or update terms. The body is `{ "terms": [{ "term", "translations"?, "note"? }] }`. Terms are upserted by exact term text: sending an existing term replaces its `translations` and `note`. Returns the stored terms and their `count`. ```bash curl https://hc.itsbaba.com/v1/terms \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "terms": [ { "term": "Wireless Earbuds Pro" }, { "term": "Optalgin", "translations": { "he": "אופטלגין", "ru": "Оптальгин" }, "note": "brand name" } ] }' ``` ```json { "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" } ], "count": 2 } ``` ### GET /v1/terms `GET /v1/terms` List the account's terms, sorted by term, with the account `limit`. ```http GET /v1/terms { "terms": [ { "id": "3f2c…", "term": "Optalgin", "translations": { "he": "אופטלגין" }, "note": "brand name", "created_at": "…" }, … ], "limit": 2000 } ``` ### DELETE /v1/terms/{id} `DELETE /v1/terms/{id}` Delete one term. Returns `404 not_found` when the id does not belong to the account. ```http DELETE /v1/terms/3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f { "deleted": true } ``` ### Effect on a Translation With the two terms above on the account, a plain request is protected automatically: ```http POST /v1/translate { "text": "Take Optalgin with water. Wireless Earbuds Pro ships tomorrow.", "target_lang": "he" } → "יש ליטול אופטלגין עם מים. Wireless Earbuds Pro נשלח מחר." ``` ## POST /v1/translate/batch `POST /v1/translate/batch` Translate many strings to one target language in a single request, for example to localize a set of UI strings or content fields. Up to 50 items, each up to 5,000 characters. | Parameter | Type | Description | | --- | --- | --- | | `items` *required* | string[] | 1–50 strings to translate. | | `target_lang` *required* | string | Applies to every item. | | `source_lang`, `transliterate`, `quality`, `gender`, `message_format` | varies | Same as `/v1/translate`; applied to all items. With `message_format: "icu"`, each item is one ICU message. | | Protection fields | varies | Any [protected translation](https://hc.itsbaba.com/docs#protected) field; each item then carries its own `protection` block. A protected batch carries at most 20,000 characters in total. Interface variables such as `{count}` and `%s` are kept in place. | ```json { "results": [ /* TranslationBlock per item, in input order */ ], "usage": { "characters": 18 } } ``` ```http POST /v1/translate/batch { "items": ["{count} items in your cart", "Checkout", "Last updated %s ago"], "target_lang": "he", "protect": true, "glossary": { "Checkout": "לתשלום" } } → ["{count} פריטים בעגלת הקניות שלך", "לתשלום", "עודכן לאחרונה לפני %s"] ``` ## App Localization: ICU Plurals Interface strings with plurals cannot be translated word for word: English has two plural forms, Hebrew has a separate form for two, and Russian has four. Set `message_format: "icu"` on `/v1/translate` or `/v1/translate/batch` and send an ICU MessageFormat string. You get back a valid ICU MessageFormat string in the target language, ready for your i18n library (FormatJS, i18next ICU, ICU4J, Android and Apple string catalogs that accept ICU). | Rule | Detail | | --- | --- | | Arguments | `{name}`, `{count, number}` and `{date, date, short}` are kept exactly. | | Plural branches | `plural` and `selectordinal` branches are rewritten for the target language's CLDR plural categories. Exact matches such as `=0` and `=1` are kept when the source has them. | | `#` | Kept wherever the source used it. | | `select` | Branch keys (`female`, `male`, `other`) are kept; each branch is translated. | | Nesting | Nested messages are supported, for example a `select` inside a `plural` branch. | | Validation | The input is parsed first: invalid ICU returns `400 invalid_request` with code `invalid_message_format`. The output is parsed and validated before it is returned; if it cannot be made valid, the source string comes back with `protection.status: "fallback"`. | | Response | The usual translate response. `translation.text` is the ICU string. In a batch, every item is one message. | ### Plural Categories | Language | Categories | Example for `{count}` days | | --- | --- | --- | | English (`en`) | `one`, `other` | 1 day · 2 days · 5 days | | Hebrew (`he`) | `one`, `two`, `other` | 1 יום · 2 ימים · 5 ימים | | Russian (`ru`) | `one`, `few`, `many`, `other` | 1 день · 2 дня · 5 дней · 1,5 дня | ### English to Hebrew ```http POST /v1/translate { "text": "{count, plural, one {# day left in your trial} other {# days left in your trial}}", "source_lang": "en", "target_lang": "he", "message_format": "icu" } { "translation": { "text": "{count, plural, one {נותר # יום לתקופת הניסיון} two {נותרו # ימים לתקופת הניסיון} other {נותרו # ימים לתקופת הניסיון}}", "lang": "he", "dir": "rtl", … }, "usage": { "characters": 82 } } ``` ### English to Russian, with an Exact Match ```http POST /v1/translate { "text": "{count, plural, =0 {Your cart is empty} one {# item in your cart} other {# items in your cart}}", "target_lang": "ru", "message_format": "icu" } → "{count, plural, =0 {Ваша корзина пуста} one {# товар в корзине} few {# товара в корзине} many {# товаров в корзине} other {# товара в корзине}}" ``` ### Select Messages ```http POST /v1/translate { "text": "{gender, select, female {{name} invited you to her workspace} male {{name} invited you to his workspace} other {{name} invited you to their workspace}}", "target_lang": "he", "message_format": "icu", "listener_gender": "female" } → "{gender, select, female {{name} הזמינה אותך לסביבת העבודה שלה} male {{name} הזמין אותך לסביבת העבודה שלו} other {{name} הזמינו אותך לסביבת העבודה}}" ``` > Without `message_format: "icu"`, arguments such as `{count}` are still protected, but plural branches are translated as plain text and keep the source language's categories. Always set it for ICU strings. ## POST /v1/analyze `POST /v1/analyze` Directionality only, with no language model. Pass exactly one of `text` (a single string) or `fields` (a map of name → string, ideal for annotating a whole record at once). Optional `base` is `auto` (default), `ltr`, or `rtl`. Each analysis has two run lists. `runs` are exactly what the Unicode Bidirectional Algorithm resolves, including its known defects: in a Hebrew line, a range such as "10–20%" splits around the dash and "<5" can mirror. `display_runs` keep every left-to-right unit whole (a Latin term, a price, a number with its unit, a range, a date, a percentage, a comparison). Render `display_runs`, or use `/v1/wrap`. ### Single String ```bash curl https://hc.itsbaba.com/v1/analyze \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"text":"שלום world"}' ``` ### Field Map ```bash curl https://hc.itsbaba.com/v1/analyze \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "fields": { "title": "מסמך Q3 ready", "subtitle": "Read the summary" } }' ``` ```json { "fields": { "title": { "dir": "rtl", "mixed": true, "lang": "he", "script": "Hebr", "runs": [ {"text":"מסמך ","dir":"rtl",...}, {"text":"Q3 ready","dir":"ltr",...} ] }, "subtitle": { "dir": "ltr", "mixed": false, "lang": "en", "script": "Latn", "runs": [ … ] } } } ``` ## POST /v1/wrap `POST /v1/wrap` Render-ready bidirectional output for a 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 ever reversed or mirrored. Deterministic, no model. | Parameter | Type | Description | | --- | --- | --- | | `text` *required* | string | The display line, up to 20,000 characters. | | `format` | enum | `html` (default, for the web, React and webviews): a `` for the line and one per unit. `isolate`: Unicode isolates, for modern text engines (iOS, Android 7+, current browsers). `marks`: direction marks (LRM/RLM), which render correctly on every engine, including older Android and embedded displays. | | `base` | enum | Paragraph direction of the surface: `auto` (default, first strong letter), `rtl` or `ltr`. Pass `rtl` for a Hebrew line even when it starts with a Latin term; `isolate` and `marks` output then starts with a mark so a text view takes the right direction by itself. | ```http POST /v1/wrap { "text": "הנחה: 10–20% על Galaxy S25 עד 31/12", "format": "html", "base": "rtl" } { "dir": "rtl", "format": "html", "output": "הנחה: 10–20% על Galaxy S25 עד 31/12", "runs": [ … ] } ``` ## POST /v1/detect `POST /v1/detect` Detect the dominant language, script and base direction of a string, with a segment per language (no model). 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`. ```http POST /v1/detect { "text": "Можно оплатить через PayPal сегодня?" } { "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 } ] } ``` ## POST /v1/transliterate `POST /v1/transliterate` Transliterate between scripts. `direction: "he-to-latin"` (default) romanizes Hebrew; `direction: "latin-to-he"` converts Latin spelling into Hebrew letters (useful for name entry and search). `text` up to 5,000 characters. ```http POST /v1/transliterate { "text": "שלום" } { "text": "שלום", "transliteration": "shalom", "scheme": "general", "direction": "he-to-latin" } ``` ## POST /v1/nikud `POST /v1/nikud` Add full nikud (vowel points) to Hebrew text: for vocalized display, learning materials, and text-to-speech, where unvocalized Hebrew is ambiguous. `text` up to 10,000 characters. English terms and numbers are left untouched, and the 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. ```http POST /v1/nikud { "text": "שלום עולם" } { "text": "שלום עולם", "nikud": "שָׁלוֹם עוֹלָם", "verified": true } ``` ## POST /v1/strip-nikud `POST /v1/strip-nikud` Remove nikud, dagesh, and cantillation marks (keeping punctuation like the maqaf). Useful for normalization, search keys, and de-duplication. Deterministic, no model. ```http POST /v1/strip-nikud { "text": "שָׁלוֹם" } { "text": "שָׁלוֹם", "stripped": "שלום" } ``` ## GET /v1/languages `GET /v1/languages` List supported languages with display names and direction. ```json { "languages": [ { "code": "he", "name": "Hebrew", "native": "עברית", "dir": "rtl" }, … ] } ``` ## GET /v1/health `GET /v1/health` Liveness and database check. Public, no authentication required. ```json { "status": "ok", "db": "ok", "version": "1.0.0" } ``` ## Status & Uptime Live status, 90-day uptime per component and incident history are at [hc-status.itsbaba.com](https://hc-status.itsbaba.com). The page runs separately from the API, so it stays up during an outage. Checks run every minute (translation every five minutes) from outside the API. - [`GET https://hc-status.itsbaba.com/api/status`](https://hc-status.itsbaba.com/api/status): current status as JSON, for your own monitoring. `status` is `operational`, `degraded`, `partial_outage` or `major_outage`. - [`/feed.atom`](https://hc-status.itsbaba.com/feed.atom): incidents and their updates as an Atom feed (also [`/feed.json`](https://hc-status.itsbaba.com/feed.json)). - [`GET /v1/health`](https://hc.itsbaba.com/docs#health): a direct liveness and database check against the API itself. ```bash curl https://hc-status.itsbaba.com/api/status { "status": "operational", "updated_at": "…", "components": [ { "id": "api", "name": "API", "status": "operational", "latency_ms": 142, "uptime_90d": 99.998 }, … ], "active_incidents": [] } ``` ## Machine-Readable Discovery Tools and AI agents can find everything about the API from a few standard files. All are public and need no key. | Path | What it is | | --- | --- | | [`/.well-known/api-catalog`](https://hc.itsbaba.com/.well-known/api-catalog) | API catalog (RFC 9727, `application/linkset+json`) linking the OpenAPI document, docs, llms.txt, status and the MCP server. The home page also sends `Link: ; rel="api-catalog"`. | | [`/apis.json`](https://hc.itsbaba.com/apis.json) | APIs.json index with the OpenAPI, documentation, pricing, status, llms.txt and MCP links. | | [`/openapi.json`](https://hc.itsbaba.com/openapi.json) | The OpenAPI 3.1 document for every endpoint. | | [`/llms.txt`](https://hc.itsbaba.com/llms.txt) | An index of the docs as Markdown for language models, with [`/llms-full.txt`](https://hc.itsbaba.com/llms-full.txt) holding everything in one file. | | [`/sitemap.xml`](https://hc.itsbaba.com/sitemap.xml) | Every public page and Markdown file, referenced from [`/robots.txt`](https://hc.itsbaba.com/robots.txt). | ## Solutions The same API serves very different products. Each guide below lists the endpoints and fields to use, a realistic request and response, and the mistakes teams make most often. All examples use synthetic data. | Solution | Typical content | Start with | | --- | --- | --- | | [Commerce & Marketplaces](https://hc.itsbaba.com/docs#solution-commerce) | Listings, catalogs, promotions, checkout | `/v1/translate/batch`, account terms, `/v1/wrap` | | [Customer Support](https://hc.itsbaba.com/docs#solution-support) | Assistant replies, macros, ticket text | `/v1/detect`, `/v1/translate` at `quality: "fast"` | | [App Localization](https://hc.itsbaba.com/docs#solution-localization) | String files, ICU plurals, interface copy | `/v1/translate/batch` with `message_format: "icu"` | | [Finance & Banking](https://hc.itsbaba.com/docs#solution-finance) | Statements, transfer notices, policies | `domain: "finance"` | | [Legal & Contracts](https://hc.itsbaba.com/docs#solution-legal) | Contracts, terms, notices | `domain: "legal"` | | [Education & Publishing](https://hc.itsbaba.com/docs#solution-education) | Lessons, readers, audio, textbooks | `/v1/nikud`, `transliterate` | | [Healthcare](https://hc.itsbaba.com/docs#solution-healthcare) | Patient instructions, care-team messages | `domain: "clinical"`, the Clinical API | ## Commerce & Marketplaces Product titles, descriptions, promotions and checkout copy in Hebrew and Russian, with every price, size, model number and brand name exactly as your catalog has it. ### What to Use | Need | Use | | --- | --- | | Translate a catalog | `/v1/translate/batch` with `protect: true`, up to 50 items per call. | | Brand, product and program names | [Account terms](https://hc.itsbaba.com/docs#terms) once for the whole catalog; `protected_terms` for one-off names. | | Your house vocabulary | `glossary`, for example `"warranty": "אחריות"`. | | Price and range lines on screen | `/v1/wrap` or `display_runs`, so `₪149.90` and `3–5` never split or mirror. | | Search in Hebrew and Latin letters | `/v1/detect` on the query, `/v1/transliterate` for Latin-letter search keys. | ### Example ```http POST /v1/translate/batch { "items": [ "Wireless Earbuds Pro, 2 pack", "Free shipping on orders over $50", "Only {stock} left in stock", "Model WEP-2210-BLK, 1-year warranty" ], "target_lang": "he", "protect": true, "protected_terms": ["Wireless Earbuds Pro"], "glossary": { "warranty": "אחריות" } } { "results": [ { "text": "Wireless Earbuds Pro, מארז של 2", "lang": "he", "dir": "rtl", "protection": { "status": "ok", … } }, { "text": "משלוח חינם בהזמנות מעל $50", "lang": "he", "dir": "rtl", "protection": { "status": "ok", … } }, { "text": "נותרו רק {stock} במלאי", "lang": "he", "dir": "rtl", "protection": { "status": "ok", … } }, { "text": "דגם WEP-2210-BLK, אחריות לשנה", "lang": "he", "dir": "rtl", "protection": { "status": "ok", … } } ], "usage": { "characters": 131 } } ``` ### Pitfalls - **Unusual model names.** Codes with digits are protected automatically; a plain-word product name ("Nimbus", "Aurora") is not. Add it to account terms. - **Prices in a Hebrew line.** `dir="rtl"` alone can split a range or move a sign. Render `display_runs` or the `/v1/wrap` output. - **Batch size.** A protected batch carries at most 20,000 characters in total; split long descriptions across calls. ## Customer Support Support assistants, macros and agent replies in the customer's language, with the assistant's voice and the customer's gender right, and every amount, date and order number unchanged. ### What to Use | Need | Use | | --- | --- | | Know the customer's language | `/v1/detect` on the incoming message. Brands and product names inside it do not change the result. | | Translate the reply | `/v1/translate` with protection at `quality: "fast"` for live chat, `balanced` for email. | | Gendered Hebrew and Russian | `speaker_gender` for the assistant (`я нашла`, `מצאתי`) and `listener_gender` for the customer. | | Customer names and personal data | `redact_terms`: kept exactly and never shown to the model. | | Plan and feature names | [Account terms](https://hc.itsbaba.com/docs#terms). | ### Example ```http POST /v1/translate { "text": "Hi Olga, your refund of €45.00 for order #B-20931 was issued on 12/05/2026. I could not find any other open requests.", "source_lang": "en", "target_lang": "ru", "redact_terms": ["Olga"], "speaker_gender": "female", "listener_gender": "female", "date_order": "DMY", "quality": "fast" } { "translation": { "text": "Здравствуйте, Olga! Возврат средств в размере €45.00 по заказу #B-20931 был оформлен 12 мая 2026 г. Я не нашла других открытых запросов.", "lang": "ru", "dir": "ltr", "protection": { "status": "ok", "spans": [ { "type": "number", "value": "€45.00" }, { "type": "identifier", "value": "B-20931" }, { "type": "date", "value": "12/05/2026", "render": "12 мая 2026 г.", "ambiguous_date": true } ], … } } } ``` ### Pitfalls - **Unknown gender.** Leave `listener_gender` unset rather than guessing; Hebrew then uses neutral forms where it can. - **Ambiguous dates.** `12/05/2026` is May 12 or December 5. Set `date_order` to match where the date came from. - **Fallback sentences.** When a sentence returns `status: "fallback"`, show it in the source language or rephrase; never retranslate it without the checks. ## App Localization String files for iOS, Android and the web, with interface variables intact and plurals rewritten for Hebrew and Russian. Translate at build time and ship the results with your app. ### What to Use | Need | Use | | --- | --- | | Plurals and selects | `message_format: "icu"`, described in [ICU plurals](https://hc.itsbaba.com/docs#icu). | | Many strings at once | `/v1/translate/batch`, one message per item, up to 50 per call. | | Variables and markup | Kept automatically: `{name}`, `{{count}}`, `%s`, `%d`, and anything inside `…`. | | Consistent product vocabulary | `glossary` and [account terms](https://hc.itsbaba.com/docs#terms). | | Mixed-direction strings | `/v1/wrap` with `format: "isolate"` for iOS and Android, `html` for the web. | ### Example ```http POST /v1/translate/batch { "items": [ "{count, plural, one {# new message} other {# new messages}}", "{days, plural, one {Your trial ends in # day} other {Your trial ends in # days}}", "Welcome back, {name}!" ], "source_lang": "en", "target_lang": "he", "message_format": "icu", "glossary": { "trial": "תקופת ניסיון" } } { "results": [ { "text": "{count, plural, one {# הודעה חדשה} two {# הודעות חדשות} other {# הודעות חדשות}}", … }, { "text": "{days, plural, one {תקופת הניסיון מסתיימת בעוד # יום} two {תקופת הניסיון מסתיימת בעוד # ימים} other {תקופת הניסיון מסתיימת בעוד # ימים}}", … }, { "text": "ברוך שובך, {name}!", … } ], "usage": { "characters": 146 } } ``` ### Pitfalls - **Hebrew has a form for two.** A Hebrew string file without a `two` branch shows the wrong form for 2. Let `message_format: "icu"` add it. - **Keys are not text.** Send only the values, never the string keys, and map results back by position. - **Buttons and labels.** Without `listener_gender`, Hebrew labels use the neutral infinitive (להציג עוד), which is usually what an interface wants. ## Finance & Banking Statements, transfer and payment notices, loan and insurance documents, where an amount, an account number or the word "credit" must never change. ### What to Use | Need | Use | | --- | --- | | Financial protection and register | `domain: "finance"`, described in [Domains](https://hc.itsbaba.com/docs#domains). | | Statement lines | `/v1/translate/batch`, one line per item. | | Customer names | `redact_terms`. Card numbers are replaced by placeholders automatically. | | Israeli dates | `date_order: "DMY"` for dates written day first. | | Amount lines in Hebrew | `/v1/wrap`, so `-$84.20` keeps its sign on the left. | ### Example ```http POST /v1/translate/batch { "items": [ "Card payment, card ending 4821: -$84.20", "Interest credited: +$3.15 (APR 4.5%)", "Overdraft fee reversed on 03/04/2026", "Transfer to IBAN GB29 NWBK 6016 1331 9268 19" ], "source_lang": "en", "target_lang": "he", "domain": "finance" } { "results": [ { "text": "תשלום בכרטיס, כרטיס המסתיים ב־4821: -$84.20", "protection": { "status": "ok", … }, … }, { "text": "ריבית שזוכתה: +$3.15 (ריבית שנתית 4.5%)", "protection": { "status": "ok", … }, … }, { "text": "עמלת משיכת יתר בוטלה ב־4 במרץ 2026", "protection": { "status": "ok", … }, … }, { "text": "העברה ל־IBAN GB29 NWBK 6016 1331 9268 19", "protection": { "status": "ok", … }, … } ], "usage": { "characters": 153 } } ``` ### Pitfalls - **Direction words.** A translation that turns a credit into a debit, or "you owe" into "you are owed", is rejected and falls back. Treat fallback lines as untranslated. - **English dates by default.** English sources default to `MDY`. A statement from an Israeli bank needs `DMY`. - **Regulatory text.** Translation does not change which version is binding. Keep the original available. ## Legal & Contracts Contracts, terms of service, privacy policies and formal notices, where "shall" and "may" are not the same word and Section 4.2 must still point to Section 4.2. ### What to Use | Need | Use | | --- | --- | | Legal protection and register | `domain: "legal"`, described in [Domains](https://hc.itsbaba.com/docs#domains). | | Party names | `protected_terms`, or `redact_terms` for private individuals. | | Fixed renderings of defined terms | `glossary`, for example `"Effective Date": "המועד הקובע"`. | | Long documents | One clause per item in `/v1/translate/batch`, at `quality: "smartest"`. | ### Example ```http POST /v1/translate { "text": "The Supplier shall not assign this Agreement without the prior written consent of Northwind Ltd. (the \"Customer\"). The Customer may terminate this Agreement on 30 days' notice.", "source_lang": "en", "target_lang": "he", "domain": "legal", "protected_terms": ["Northwind Ltd."], "quality": "smartest" } { "translation": { "text": "הספק לא יסב הסכם זה ללא הסכמה מראש ובכתב של Northwind Ltd. (להלן: ״הלקוח״). הלקוח רשאי לסיים הסכם זה בהודעה מוקדמת של 30 יום.", "dir": "rtl", "protection": { "status": "ok", "spans": [ { "type": "term", "value": "Northwind Ltd." }, { "type": "defined_term", "value": "Customer", "render": "הלקוח" }, { "type": "number", "value": "30" } ], "issues": [], … } } } ``` ### Pitfalls - **Defined terms are translated.** "the Customer" becomes (להלן: ״הלקוח״) once and הלקוח after that. Pin a specific rendering with `glossary`; put a party's legal name in `protected_terms` to keep it as written. - **Modality.** If "shall not" comes back as "may not", or "may" as "shall", the sentence falls back. Review fallback clauses by hand. - **Size.** A single request carries up to 20,000 characters. Split a long contract by clause, which also keeps retries small. - **Binding text.** A translation is a reading aid. State which language governs, and keep the original with it. ## Education & Publishing Language-learning apps, children's books, readers and audio, where vowel points, transliteration and the learner's gender matter as much as the translation. ### What to Use | Need | Use | | --- | --- | | Vocalized text for readers and speech | `/v1/nikud`, checked so no letter changes. | | A reading in Latin letters | `transliterate: true` on `/v1/translate`, or `/v1/transliterate`. | | Addressing the learner | `listener_gender` on protected translation (`סיימת`, `ты закончила`). | | Search across vocalized text | `/v1/strip-nikud` to build search keys. | | Course interface strings | The [App Localization](https://hc.itsbaba.com/docs#solution-localization) setup. | ### Example ```http POST /v1/nikud { "text": "הילדים קוראים ספר בספרייה" } { "text": "הילדים קוראים ספר בספרייה", "nikud": "הַיְלָדִים קוֹרְאִים סֵפֶר בַּסִּפְרִיָּה", "verified": true } POST /v1/translate { "text": "The children are reading a book in the library.", "target_lang": "he", "transliterate": true } → "text": "הילדים קוראים ספר בספרייה.", "transliteration": "Hayeladim kor'im sefer basifriya." ``` ### Pitfalls - **Unverified nikud.** When `verified` is false, `nikud` is your text unchanged. Show or speak the plain text. - **Transliteration scheme.** The scheme is a general reading aid, not an academic standard. Keep that in mind for citations. - **Mixed search.** Index both the plain and the vocalized form, or strip nikud from queries and documents alike. ## Healthcare Patient portals, care-team tools and clinical assistants that work in English and speak to patients in Hebrew. Short messages use `domain: "clinical"` on `/v1/translate`; streamed answers, record search and verification use the [Clinical API](https://hc.itsbaba.com/docs#medical). ### What to Use | Need | Use | | --- | --- | | A short message or instruction | `/v1/translate` with `domain: "clinical"`, `audience` and `patient_gender`. | | An answer your model is still writing | Streaming: [WebSocket /v1/medical/stream](https://hc.itsbaba.com/docs#medical-stream) or [Server-Sent Events](https://hc.itsbaba.com/docs#medical-sse). | | A Hebrew question against English records | [/v1/medical/query](https://hc.itsbaba.com/docs#medical-query). | | Checking Hebrew written elsewhere | [/v1/medical/verify](https://hc.itsbaba.com/docs#medical-verify). | | The patient's medications and names | `protected_terms` from your record search; `redact_terms` for names. | ### Example ```http POST /v1/translate { "text": "Take Eliquis 5 mg twice a day. Do not take ibuprofen. Your next INR check is on 03/04/2026.", "target_lang": "he", "domain": "clinical", "audience": "patient", "listener_gender": "female", "protected_terms": ["Eliquis 5 mg"] } { "translation": { "text": "יש ליטול Eliquis 5 mg פעמיים ביום. אין ליטול איבופרופן. בדיקת ה־INR הבאה שלך תתקיים ב־4 במרץ 2026.", "dir": "rtl", "protection": { "status": "ok", "spans": [ { "type": "term", "value": "Eliquis 5 mg" }, { "type": "abbreviation", "value": "INR" }, { "type": "date", "value": "03/04/2026", "render": "4 במרץ 2026", "ambiguous_date": true } ], … } } } ``` ### Pitfalls - **Server only.** `/v1/medical` refuses browser requests, and needs a key with the `medical` scope. Use synthetic data in the playground. - **US record dates.** Clinical dates default to `MDY`; set `date_order: "DMY"` for Israeli records. - **Fallback sentences.** Show a `fallback` sentence in English and keep the English original available. ## Guide: Localizing an App or Site Send interface strings to `/v1/translate/batch` with `protect: true`. Variables such as `{count}`, `{{name}}` and `%s` stay in place, and a `glossary` fixes the words your product always uses ("Checkout" → "לתשלום"). Set `listener_gender` when you know the user's gender; without it, Hebrew labels and buttons use the neutral infinitive (להציג עוד). Translate once at build time and ship the results with your app. ## Guide: Mixed-Direction Display A Hebrew line with prices, model numbers, dates or ranges needs more than `dir="rtl"`: the Unicode algorithm alone splits "10–20%" around the dash and mirrors "<5". Pass each display string through `/v1/wrap` with `base: "rtl"` and pick the format for the surface: | Surface | Format | | --- | --- | | Web, React, webviews | `html` | | iOS, Android 7+, desktop apps | `isolate` | | Older Android, embedded and small displays, any renderer you cannot test | `marks` | `/v1/wrap` is deterministic and fast enough to call per line at render time, or you can wrap once when the string is created and store the result. ## Guide: Assistants and Chat For an assistant that answers in Hebrew or Russian, detect the user's language with `/v1/detect`, generate the answer in your usual language, and translate it with protected translation at `quality: "fast"`. Set `speaker_gender` for the assistant's voice and `listener_gender` for the user, and pass the names, products and amounts from your data as `protected_terms`. When a sentence comes back with `status: "fallback"`, show it in the source language or ask the user to rephrase; never retranslate it without the checks. ## Guide: Voice Output Unvocalized Hebrew is ambiguous for speech engines. Send the text you will speak to `/v1/nikud` and pass the vocalized result to your text-to-speech engine, while the screen keeps the plain text (or use `/v1/strip-nikud` to get it back). English terms and numbers pass through unchanged. If `verified` is false, speak the plain text. ## Guide: Regulated Content Finance, insurance, legal and health content share one rule: an amount, a date, a code or a negation must never change in translation. Protected translation enforces that for every request, and `redact_terms` keeps personal names out of the model entirely. Pick the [domain](https://hc.itsbaba.com/docs#domains) that matches the text: `finance` for statements and notices, `legal` for contracts and policies, and `clinical` for health content, or the [Clinical API](https://hc.itsbaba.com/docs#medical) for streaming, record search and verification. The [solution guides](https://hc.itsbaba.com/docs#solutions) walk through each. For processing agreements, subprocessors and regions, contact us. ## Clinical API The `/v1/medical` endpoints serve health products that work in English and speak to people in Hebrew: patient portals, care-team tools, clinical assistants and record viewers. Records, search and your own model stay in English. HebrewCore turns a Hebrew question into an English query, then turns the English answer into Hebrew as it streams, one verified sentence at a time. Real patient data goes only from your server, with an API key. The [playground](https://hc.itsbaba.com/docs#playground) runs in the browser, so use synthetic data only there. ```text Hebrew question ──► POST /v1/medical/query ──► English query ──► your record search + model │ English answer, streamed Hebrew answer ◄── verified sentences ◄── WebSocket /v1/medical/stream ◄──┘ ``` Every sentence goes through the same steps before it is returned: | Step | What happens | | --- | --- | | Protect | Drug names (US generics and brands, plus unknown drugs by their name stem), doses and concentrations, lab values, units, ICD-10 codes, clinical abbreviations, identifiers and every number are replaced with placeholders the model cannot change. Your `protected_terms`, `redact_terms` and [account terms](https://hc.itsbaba.com/docs#terms) come first. | | Translate | The model translates the words around the placeholders into Israeli medical Hebrew for a clinician or a patient. | | Check | Every placeholder must appear exactly once, every number in the English must appear in the Hebrew and no number may be invented, negations and left/right must survive, and the length must be plausible. | | Review | An independent model checks every sentence for meaning changes: certainty, timing, dosing wording, who is being described, omissions and additions. | | Retry or fall back | A rejected sentence is retried once with a stronger model, told what was wrong. If it still fails, the English sentence is returned with `status: "fallback"`. Unverified Hebrew is never returned. | | Restore | The original values are put back, wrapped in Unicode isolates so `5 mg` never renders as `mg 5`. Dates are rewritten unambiguously (`03/04/2026` → `4 במרץ 2026`). | ### Segment Status | Status | Meaning | | --- | --- | | `ok` | Translated and verified on the first attempt. | | `retried` | The first attempt was rejected; the retry passed every check. | | `fallback` | No translation passed. `text` is the English source; `issues` says why. Show it as English, or ask the user to rephrase. | | `passthrough` | Structure or values only (a blank line, a rule, a date on its own). No model was needed. | ## Access & Data Handling > The Clinical API is enabled per account under a data processing agreement (and a BAA for US covered entities). Keys need the `medical` scope; other keys get `403 scope_required`. - **Server to server only.** A request carrying a browser `Origin` header is refused with `403 server_only`. Never put a medical key in a browser or app. - **Nothing is stored.** Only character counts are kept for billing. Responses carry `Cache-Control: no-store` and `X-Content-Stored: false`. - **Names and identifiers never reach the model.** Values passed in `redact_terms`, and record numbers, phone numbers, SSNs and emails found in the text, are sent to the model as blank placeholders and put back afterwards. They are also left out of the `spans` list in responses. - **Dedicated model access.** Medical traffic goes directly to the model provider under contract, with storage turned off. It never passes through a model reseller or a logging gateway. ## POST /v1/medical/translate `POST /v1/medical/translate` Translate a complete English text. Sentences are translated in parallel and returned in order. | Parameter | Type | Description | | --- | --- | --- | | `text` *required* | string | 1–20,000 characters of English. Markdown lists, headings and tables keep their structure. | | `audience` | enum | `clinician` (default) keeps shorthand such as BID and PO. `patient` writes it as plain Hebrew. | | `reader_gender` | enum | `male` · `female`. How to address "you". Omit when unknown. | | `patient_gender` | enum | `male` · `female`. The patient in third-person references. Inferred from he/she when omitted. | | `protected_terms` | string[] | Kept verbatim, e.g. the medication and problem lists your record search returned. Up to 500. | | `redact_terms` | string[] | Kept verbatim and never shown to the model: patient and staff names. Up to 200. | | `glossary` | object | English term → required Hebrew rendering, e.g. `{"hypertension": "יתר לחץ דם"}`. Up to 500. | | `date_order` | enum | How to read ambiguous numeric dates: `MDY` (default, US records) or `DMY`. | | `date_style` | enum | `hebrew` (default, "4 במרץ 2026") · `iso` ("2026-03-04") · `keep` (unambiguous dates only; an ambiguous one is still rewritten). A two-digit year is kept as written. | | `bidi` | enum | `isolate` (default) wraps English values in Unicode isolates · `none`. | ```bash curl https://hc.itsbaba.com/v1/medical/translate \ -H "Authorization: Bearer hc_live_YOUR_MEDICAL_KEY" \ -H "Content-Type: application/json" \ -d '{ "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"] }' ``` ### Response ```json { "id": "med_…", "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 } } ``` ## WebSocket /v1/medical/stream `GET /v1/medical/stream` (WebSocket upgrade) For an answer your model is still generating. Send the English as it arrives; each Hebrew sentence comes back as soon as it is verified, typically about 2–3 seconds after the English sentence completes. Authenticate with the `Authorization` header on the upgrade request. | Message | Direction | Meaning | | --- | --- | --- | | `{"type":"start", …options}` | → | First message. Takes every option of `/v1/medical/translate` except `text`. | | `{"type":"delta","text":"…"}` | → | The next piece of English. Any size, in order. Up to 100,000 characters per session. | | `{"type":"end"}` | → | No more English. The rest is flushed. | | `{"type":"ready"}` | ← | Options accepted. | | `{"type":"segment", …}` | ← | One sentence, the same shape as a `segments[]` entry, strictly in order. | | `{"type":"done","stats","usage"}` | ← | Everything delivered. The socket then closes with code 1000. | | `{"type":"error","error":{type,message}}` | ← | The session stops and the socket closes. `quota_exceeded` closes with 1008. | ```js // Server-side only. Pipes your model's English answer through HebrewCore // and shows each verified Hebrew sentence as soon as it is ready. import OpenAI from "openai"; const ws = new WebSocket("wss://hc.itsbaba.com/v1/medical/stream", { headers: { Authorization: `Bearer ${process.env.HEBREWCORE_MEDICAL_KEY}` }, }); await new Promise((r) => ws.addEventListener("open", r)); ws.addEventListener("message", (e) => { const msg = JSON.parse(e.data); if (msg.type === "segment") sendToUser(msg.prefix + msg.text + msg.suffix, msg.status); if (msg.type === "error") handleError(msg.error); if (msg.type === "done") finish(msg.stats); }); ws.send(JSON.stringify({ type: "start", audience: "patient", reader_gender: "male", protected_terms: patient.medications, // from your record search redact_terms: [patient.fullName], })); const stream = await new OpenAI().chat.completions.create({ model, messages, stream: true }); for await (const chunk of stream) { const delta = chunk.choices[0]?.delta?.content; if (delta) ws.send(JSON.stringify({ type: "delta", text: delta })); } ws.send(JSON.stringify({ type: "end" })); ``` Characters are charged per sentence as it starts, so a session that hits the quota stops exactly there. A session idle for 60 seconds is closed. ## POST /v1/medical/translate/stream `POST /v1/medical/translate/stream` Same body as `/v1/medical/translate`, answered as Server-Sent Events so the first sentence can be shown before the last is done. Events: `segment`, then `done` or `error`. ## POST /v1/medical/query `POST /v1/medical/query` Turn a Hebrew question into an English query for your record search. 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`. `text` up to 2,000 characters. ```http POST /v1/medical/query { "text": "האם המטופלת עדיין לוקחת מטפורמין?", "known_terms": ["metformin", "lisinopril"] } { "query": "Is the patient still taking metformin?", "terms": [ { "hebrew": "מטפורמין", "english": "metformin", "source": "known_terms" } ], "usage": { "characters": 33 } } ``` ## POST /v1/medical/verify `POST /v1/medical/verify` Check Hebrew that was produced some other way, for example by your own model answering in Hebrew, against its English source. Every protected value must appear verbatim, dates must be unambiguous, no number may be added, and negation and laterality must survive. Set `verification: "strict"` to add the independent review; names in `redact_terms` and identifiers are replaced before the reviewer sees the text. ```http POST /v1/medical/verify { "source": "Metformin 500 mg BID since 03/04/2026.", "translation": "Metformin 50 mg BID מאז 03/04/2026." } { "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 } } ``` > Translation is an aid, not a clinical record. Keep the English original available to the user, and treat any sentence with `status: "fallback"` as untranslated. > Looking for the full machine-readable contract? The OpenAPI 3.1 spec is at [`/openapi.json`](https://hc.itsbaba.com/openapi.json), rendered interactively at [/reference](https://hc.itsbaba.com/reference). # API reference Generated from the OpenAPI 3.1.0 document at https://hc.itsbaba.com/openapi.json. Interactive version: https://hc.itsbaba.com/reference. Base URL: https://hc.itsbaba.com. **Authentication.** HebrewCore API key, sent as `Authorization: Bearer `: `hc_live_…` for production, `hc_test_…` for the sandbox. Create keys in the dashboard. **WebSocket.** `wss://hc.itsbaba.com/v1/medical/stream` streams clinical translation for English that is still being generated. It is not an OpenAPI operation; see the "WebSocket /v1/medical/stream" section of the documentation above. ## Translation Translation, protected translation, batches and transliteration. Model-backed: consumes the character quota. ### POST /v1/translate **Translate text.** Operation id: `translate`. 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. **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](https://hc.itsbaba.com/docs#terms). **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). **Quota.** Consumes the monthly character quota: the length of `text`. A request that fails upstream is not charged. **Limits.** `text` up to 20,000 characters. Not idempotent: the same request translated twice may differ in wording, never in protected values. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | Text to translate, 1 to 20,000 characters. Counts toward the monthly character quota. 1 to 20,000 characters. Example: `"Welcome to your account"`. | | `source_lang` | string | no | BCP 47 source language, or `auto` (default) to detect it. Example: `"auto"`. | | `target_lang` | string | yes | BCP 47 target language, e.g. `he`, `en`, `ru`. See GET /v1/languages. Example: `"he"`. | | `transliterate` | boolean | no | Include a Latin transliteration when the target is Hebrew. Default: `false`. Example: `false`. | | `quality` | string | no | `fast`: lowest latency, for high volume and short strings. `balanced`: the default. `smartest`: maximum nuance for long or sensitive text. One of: `fast`, `balanced`, `smartest`. Default: `"balanced"`. Example: `"balanced"`. | | `gender` | string | no | Grammatical gender for the reader where the target language marks it. For assistants, prefer `listener_gender` and `speaker_gender`. One of: `male`, `female`, `general`. Example: `"general"`. | | `store` | boolean | no | Accepted for compatibility and has no effect: HebrewCore never stores request or response text. Example: `false`. | | `message_format` | string | no | `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"`. One of: `icu`. Example: `"icu"`. | | `protect` | boolean | no | Keep prices, quantities, numbers, dates, codes, identifiers, product names, interface variables ({name}, %s) and … 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` | string | no | `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`. One of: `general`, `clinical`, `finance`, `legal`. Example: `"finance"`. | | `audience` | string | no | Clinical domain register. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes it as plain words. One of: `clinician`, `patient`. Example: `"patient"`. | | `protected_terms` | string[] | no | 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. Up to 500 items. Each item up to 200 characters. Example: `["Wireless Earbuds Pro","A-10234"]`. | | `redact_terms` | string[] | no | Kept exactly and never shown to the model: customer names and other personal data. Up to 200. Up to 200 items. Each item up to 200 characters. Example: `["Dana Levi"]`. | | `glossary` | object | no | 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` | string | no | Gender of the reader ("you"): תרצי / תרצה. Hebrew and Russian mark it; English does not. Without it, Hebrew interface text uses neutral forms. One of: `male`, `female`. Example: `"female"`. | | `speaker_gender` | string | no | Gender of the speaker ("I"), for an assistant or brand voice: מצאתי, я нашла / я нашёл. One of: `male`, `female`. Example: `"female"`. | | `patient_gender` | string | no | Clinical domain: gender of a patient referred to in the third person. One of: `male`, `female`. Example: `"male"`. | | `date_order` | string | no | How to read ambiguous numeric dates such as 04/03/2026. Default MDY for English sources, DMY for Hebrew and Russian. One of: `MDY`, `DMY`. Example: `"MDY"`. | | `date_style` | string | no | `hebrew` (default) spells the month out in the target language ("4 במרץ 2026", "4 марта 2026 г."); `iso`; `keep` (unambiguous dates only). One of: `hebrew`, `iso`, `keep`. Example: `"hebrew"`. | | `bidi` | string | no | `isolate` wraps protected values in Unicode isolates in Hebrew output. Default none; see /v1/wrap. One of: `isolate`, `none`. Example: `"none"`. | Example (Shopping assistant reply, protected): ```json { "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" } ``` Example (Support reply to Russian, protected): ```json { "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" } ``` Example (Hebrew customer message to English): ```json { "text": "ההזמנה שלי מס׳ A-10234 עוד לא הגיעה, אפשר לבדוק?", "target_lang": "en", "protect": true } ``` Example (Clinical text for a patient): ```json { "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" ] } ``` Example (Bank transfer confirmation, finance domain): ```json { "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" } ``` Example (Contract clause, legal domain): ```json { "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" } ``` Example (ICU plural message): ```json { "text": "{count, plural, one {# item} other {# items}} in your cart", "source_lang": "en", "target_lang": "he", "message_format": "icu" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/translate \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Welcome to your account", "target_lang": "he", "transliterate": true }' ``` #### Response 200 Translation result | Header | Description | | --- | --- | | `X-Usage-Chars-Used` | Characters used this month by the account, including this request. | | `X-Usage-Chars-Limit` | Monthly character quota of the account. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `id` | string | Request identifier. Include it when you contact support. Example: `"txn_a1b2c3d4e5f6"`. | | `source` | object | The source text with its directionality metadata. | | `source.dir` | string | Paragraph base direction. With `base: "auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `source.mixed` | boolean | 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`. | | `source.lang` | string | Dominant BCP 47 language, from the dominant script. Example: `"he"`. | | `source.script` | string | Dominant ISO 15924 script. Example: `"Hebr"`. | | `source.runs` | object[] | Runs exactly as the Unicode Bidirectional Algorithm resolves them. | | `source.runs[].text` | string | The run text. Equals `input.slice(start, end)`. Example: `"שלום "`. | | `source.runs[].dir` | string | Resolved direction of the run. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `source.runs[].script` | string | ISO 15924 script of the run: `Hebr`, `Latn`, `Cyrl`, `Arab`, or `Zyyy` for digits and punctuation only. Example: `"Hebr"`. | | `source.runs[].lang` | string | Best-effort BCP 47 language of the run, from its script. `und` when undetermined (numbers, symbols). Example: `"he"`. | | `source.runs[].start` | integer | UTF-16 offset of the first character, inclusive. Example: `0`. | | `source.runs[].end` | integer | UTF-16 offset after the last character, exclusive. Example: `5`. | | `source.display_runs` | object[] | 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. Same fields as `source.runs[]`. | | `source.text` | string | The source text as sent. Example: `"Welcome to your account"`. | | `translation` | object | The translation with its directionality metadata. | | `translation.dir` | string | Paragraph base direction. With `base: "auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `translation.mixed` | boolean | 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`. | | `translation.lang` | string | Dominant BCP 47 language, from the dominant script. Example: `"he"`. | | `translation.script` | string | Dominant ISO 15924 script. Example: `"Hebr"`. | | `translation.runs` | object[] | Runs exactly as the Unicode Bidirectional Algorithm resolves them. Same fields as `source.runs[]`. | | `translation.display_runs` | object[] | 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. Same fields as `source.runs[]`. | | `translation.text` | string | The translation, or the source text for sentences that fell back. Example: `"ברוכים הבאים לחשבון שלך"`. | | `translation.transliteration` | string \| null | Latin transliteration of a Hebrew result when `transliterate` was true, otherwise null. Example: `"Bruchim haba'im lakheshbon shelkha"`. | | `translation.protection` | object | Present when the request used protected translation. | | `translation.protection.status` | string | 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. One of: `ok`, `retried`, `fallback`, `passthrough`. Example: `"ok"`. | | `translation.protection.source_lang` | string | Source language used for protection (detected when `source_lang` is `auto`). Example: `"en"`. | | `translation.protection.spans` | object[] | Every protected value, in source order. | | `translation.protection.spans[].type` | string | 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"`. | | `translation.protection.spans[].value` | string | The protected source value. Omitted for redacted values. Example: `"04/03/2026"`. | | `translation.protection.spans[].render` | string | How the value was written in the translation, when it was rewritten (dates). Example: `"3 באפריל 2026"`. | | `translation.protection.spans[].ambiguous_date` | boolean | True when a numeric date could be read two ways and `date_order` decided it. Example: `true`. | | `translation.protection.issues` | object[] | Problems found by the checks. Empty when every sentence passed. | | `translation.protection.issues[].code` | string | 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"`. | | `translation.protection.issues[].severity` | string | One of: `error`, `warning`. Example: `"error"`. | | `translation.protection.issues[].detail` | string | Example: `"\"A-10234\" (term) is missing or altered."`. | | `translation.protection.segments` | object[] | Per-sentence result, in order. | | `translation.protection.segments[].source` | string | Example: `"Would you like me to schedule delivery for 04/03/2026?"`. | | `translation.protection.segments[].text` | string | Example: `"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?"`. | | `translation.protection.segments[].status` | string | One of: `ok`, `retried`, `fallback`, `passthrough`. Example: `"ok"`. | | `quality` | string | Quality tier used. Example: `"balanced"`. | | `usage` | object | What this request consumed. | | `usage.characters` | integer | Characters charged to the monthly quota for this request. Example: `23`. | ```json { "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 } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request` / `unsupported_language`: "Protected translation supports Hebrew (he), English (en) and Russian (ru)."; `invalid_request` / `same_language`: "source_lang and target_lang must differ." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | | 502 | The model provider failed or returned an empty result. Nothing was charged. Safe to retry. | `bad_gateway` / `upstream_error`: "Translation provider error." | | 503 | A model feature is temporarily unavailable. | `service_unavailable` / `not_configured`: "Translation is not configured on this server." | ### POST /v1/transliterate **Transliterate between Hebrew and Latin script.** Operation id: `transliterate`. 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. **Quota.** Consumes the monthly character quota: the length of `text`. **Limits.** `text` up to 5,000 characters. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | Text to transliterate, up to 5,000 characters. 1 to 5,000 characters. Example: `"שלום"`. | | `direction` | string | no | `he-to-latin` (default) romanizes Hebrew. `latin-to-he` writes Latin spelling in Hebrew letters, for name entry and search. One of: `he-to-latin`, `latin-to-he`. Default: `"he-to-latin"`. Example: `"he-to-latin"`. | Example (Latin spelling to Hebrew letters): ```json { "text": "Rivka Cohen", "direction": "latin-to-he" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/transliterate \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "שלום" }' ``` #### Response 200 Transliteration | Header | Description | | --- | --- | | `X-Usage-Chars-Used` | Characters used this month by the account, including this request. | | `X-Usage-Chars-Limit` | Monthly character quota of the account. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `text` | string | The input. Example: `"שלום"`. | | `transliteration` | string | The transliterated text. Example: `"shalom"`. | | `scheme` | string | Romanization scheme used. Example: `"general"`. | | `direction` | string | Direction used. Example: `"he-to-latin"`. | ```json { "text": "שלום", "transliteration": "shalom", "scheme": "general", "direction": "he-to-latin" } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request` / `unsupported_language`: "Protected translation supports Hebrew (he), English (en) and Russian (ru)."; `invalid_request` / `same_language`: "source_lang and target_lang must differ." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | | 502 | The model provider failed or returned an empty result. Nothing was charged. Safe to retry. | `bad_gateway` / `upstream_error`: "Translation provider error." | | 503 | A model feature is temporarily unavailable. | `service_unavailable` / `not_configured`: "Translation is not configured on this server." | ### POST /v1/translate/batch **Translate a batch of strings.** Operation id: `translateBatch`. 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. With 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. **Quota.** Consumes the monthly character quota: the total length of all items. **Limits.** 1 to 50 items, each up to 5,000 characters. A protected batch carries at most 20,000 characters in total. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | string[] | yes | 1 to 50 strings, each up to 5,000 characters. A protected batch carries at most 20,000 characters in total. 1 to 50 items. Each item up to 5,000 characters. Example: `["{count} items in your cart","Checkout","Last updated %s ago"]`. | | `target_lang` | string | yes | BCP 47 target language, applied to every item. Example: `"he"`. | | `source_lang` | string | no | BCP 47 source language, or `auto` (default). Example: `"auto"`. | | `transliterate` | boolean | no | Include a Latin transliteration when the target is Hebrew. Default: `false`. Example: `false`. | | `quality` | string | no | Quality tier, applied to every item. One of: `fast`, `balanced`, `smartest`. Default: `"balanced"`. Example: `"balanced"`. | | `gender` | string | no | Grammatical gender for the reader where the target language marks it. One of: `male`, `female`, `general`. Example: `"general"`. | | `message_format` | string | no | `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"`. One of: `icu`. Example: `"icu"`. | | `protect` | boolean | no | Keep prices, quantities, numbers, dates, codes, identifiers, product names, interface variables ({name}, %s) and … 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` | string | no | `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`. One of: `general`, `clinical`, `finance`, `legal`. Example: `"finance"`. | | `audience` | string | no | Clinical domain register. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes it as plain words. One of: `clinician`, `patient`. Example: `"patient"`. | | `protected_terms` | string[] | no | 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. Up to 500 items. Each item up to 200 characters. Example: `["Wireless Earbuds Pro","A-10234"]`. | | `redact_terms` | string[] | no | Kept exactly and never shown to the model: customer names and other personal data. Up to 200. Up to 200 items. Each item up to 200 characters. Example: `["Dana Levi"]`. | | `glossary` | object | no | 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` | string | no | Gender of the reader ("you"): תרצי / תרצה. Hebrew and Russian mark it; English does not. Without it, Hebrew interface text uses neutral forms. One of: `male`, `female`. Example: `"female"`. | | `speaker_gender` | string | no | Gender of the speaker ("I"), for an assistant or brand voice: מצאתי, я нашла / я нашёл. One of: `male`, `female`. Example: `"female"`. | | `patient_gender` | string | no | Clinical domain: gender of a patient referred to in the third person. One of: `male`, `female`. Example: `"male"`. | | `date_order` | string | no | How to read ambiguous numeric dates such as 04/03/2026. Default MDY for English sources, DMY for Hebrew and Russian. One of: `MDY`, `DMY`. Example: `"MDY"`. | | `date_style` | string | no | `hebrew` (default) spells the month out in the target language ("4 במרץ 2026", "4 марта 2026 г."); `iso`; `keep` (unambiguous dates only). One of: `hebrew`, `iso`, `keep`. Example: `"hebrew"`. | | `bidi` | string | no | `isolate` wraps protected values in Unicode isolates in Hebrew output. Default none; see /v1/wrap. One of: `isolate`, `none`. Example: `"none"`. | Example (Short labels to Russian): ```json { "items": [ "Save", "Cancel", "Delete account" ], "target_lang": "ru", "quality": "fast" } ``` Example (ICU messages to Russian): ```json { "items": [ "{count, plural, one {# file} other {# files}} uploaded", "{name} invited you" ], "target_lang": "ru", "message_format": "icu" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/translate/batch \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ "{count} items in your cart", "Checkout", "Last updated %s ago" ], "target_lang": "he", "protect": true, "glossary": { "Checkout": "לתשלום" } }' ``` #### Response 200 Batch results (input order) | Header | Description | | --- | --- | | `X-Usage-Chars-Used` | Characters used this month by the account, including this request. | | `X-Usage-Chars-Limit` | Monthly character quota of the account. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `results` | object[] | One translation per item, in input order. | | `results[].dir` | string | Paragraph base direction. With `base: "auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `results[].mixed` | boolean | 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`. | | `results[].lang` | string | Dominant BCP 47 language, from the dominant script. Example: `"he"`. | | `results[].script` | string | Dominant ISO 15924 script. Example: `"Hebr"`. | | `results[].runs` | object[] | Runs exactly as the Unicode Bidirectional Algorithm resolves them. | | `results[].runs[].text` | string | The run text. Equals `input.slice(start, end)`. Example: `"שלום "`. | | `results[].runs[].dir` | string | Resolved direction of the run. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `results[].runs[].script` | string | ISO 15924 script of the run: `Hebr`, `Latn`, `Cyrl`, `Arab`, or `Zyyy` for digits and punctuation only. Example: `"Hebr"`. | | `results[].runs[].lang` | string | Best-effort BCP 47 language of the run, from its script. `und` when undetermined (numbers, symbols). Example: `"he"`. | | `results[].runs[].start` | integer | UTF-16 offset of the first character, inclusive. Example: `0`. | | `results[].runs[].end` | integer | UTF-16 offset after the last character, exclusive. Example: `5`. | | `results[].display_runs` | object[] | 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. Same fields as `results[].runs[]`. | | `results[].text` | string | The translation, or the source text for sentences that fell back. Example: `"ברוכים הבאים לחשבון שלך"`. | | `results[].transliteration` | string \| null | Latin transliteration of a Hebrew result when `transliterate` was true, otherwise null. Example: `"Bruchim haba'im lakheshbon shelkha"`. | | `results[].protection` | object | Present when the request used protected translation. | | `results[].protection.status` | string | 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. One of: `ok`, `retried`, `fallback`, `passthrough`. Example: `"ok"`. | | `results[].protection.source_lang` | string | Source language used for protection (detected when `source_lang` is `auto`). Example: `"en"`. | | `results[].protection.spans` | object[] | Every protected value, in source order. | | `results[].protection.spans[].type` | string | 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"`. | | `results[].protection.spans[].value` | string | The protected source value. Omitted for redacted values. Example: `"04/03/2026"`. | | `results[].protection.spans[].render` | string | How the value was written in the translation, when it was rewritten (dates). Example: `"3 באפריל 2026"`. | | `results[].protection.spans[].ambiguous_date` | boolean | True when a numeric date could be read two ways and `date_order` decided it. Example: `true`. | | `results[].protection.issues` | object[] | Problems found by the checks. Empty when every sentence passed. | | `results[].protection.issues[].code` | string | 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"`. | | `results[].protection.issues[].severity` | string | One of: `error`, `warning`. Example: `"error"`. | | `results[].protection.issues[].detail` | string | Example: `"\"A-10234\" (term) is missing or altered."`. | | `results[].protection.segments` | object[] | Per-sentence result, in order. | | `results[].protection.segments[].source` | string | Example: `"Would you like me to schedule delivery for 04/03/2026?"`. | | `results[].protection.segments[].text` | string | Example: `"האם תרצי שאקבע את המשלוח ל־3 באפריל 2026?"`. | | `results[].protection.segments[].status` | string | One of: `ok`, `retried`, `fallback`, `passthrough`. Example: `"ok"`. | | `usage` | object | What this request consumed. | | `usage.characters` | integer | Characters charged to the monthly quota for this request. Example: `23`. | ```json { "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 } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request` / `unsupported_language`: "Protected translation supports Hebrew (he), English (en) and Russian (ru)."; `invalid_request` / `same_language`: "source_lang and target_lang must differ." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | | 502 | The model provider failed or returned an empty result. Nothing was charged. Safe to retry. | `bad_gateway` / `upstream_error`: "Translation provider error." | | 503 | A model feature is temporarily unavailable. | `service_unavailable` / `not_configured`: "Translation is not configured on this server." | ## Account Terms 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. ### GET /v1/terms **List the account's protected terms.** Operation id: `listTerms`. 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. **Quota.** Does not consume the character quota. Authentication: `Authorization: Bearer `. #### Example request ```bash curl https://hc.itsbaba.com/v1/terms \ -H "Authorization: Bearer hc_live_YOUR_KEY" ``` #### Response 200 Terms | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `terms` | object[] | | | `terms[].id` | string | Example: `"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f"`. | | `terms[].term` | string | Kept exactly as written in every protected translation. Example: `"Acamol"`. | | `terms[].translations` | object | Optional required rendering per target language. When set for the target, it replaces the term; otherwise the term is kept verbatim. Example: `{"he":"אקמול"}`. | | `terms[].translations.he` | string | | | `terms[].translations.en` | string | | | `terms[].translations.ru` | string | | | `terms[].note` | string \| null | Your own note, up to 500 characters. Example: `"paracetamol 500 mg brand"`. | | `terms[].created_at` | string | ISO 8601 timestamp. Example: `"2026-01-15T09:30:00.000Z"`. | | `limit` | integer | Example: `2000`. | ```json { "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 } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached. | `invalid_request`: "Each term needs a non-empty "term"."; `invalid_request`: "translations: unsupported language "fr". Use he, en or ru."; `invalid_request` / `terms_limit`: "An account may hold at most 2000 terms." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ### POST /v1/terms **Add or update protected terms (upsert by exact term).** Operation id: `upsertTerms`. 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. `translations` accepts `he`, `en` and `ru`. Leave it out to keep the term exactly as written in every language. **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. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `terms` | object[] | yes | 1 to 2,000 items. | | `terms[].term` | string | yes | 1 to 200 characters. Example: `"Optalgin"`. | | `terms[].translations` | object | no | Example: `{"he":"אופטלגין","ru":"Оптальгин"}`. | | `terms[].translations.he` | string | no | 1 to 200 characters. | | `terms[].translations.en` | string | no | 1 to 200 characters. | | `terms[].translations.ru` | string | no | 1 to 200 characters. | | `terms[].note` | string \| null | no | Up to 500 characters. | Example (Drug names with fixed renderings): ```json { "terms": [ { "term": "Optalgin", "translations": { "he": "אופטלגין", "ru": "Оптальгин" }, "note": "brand name" }, { "term": "Eliquis", "translations": { "he": "אליקוויס" } } ] } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/terms \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "terms": [ { "term": "Wireless Earbuds Pro" }, { "term": "Galaxy S25", "note": "product line" } ] }' ``` #### Response 200 Stored terms | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `terms` | object[] | | | `terms[].id` | string | Example: `"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f"`. | | `terms[].term` | string | Kept exactly as written in every protected translation. Example: `"Acamol"`. | | `terms[].translations` | object | Optional required rendering per target language. When set for the target, it replaces the term; otherwise the term is kept verbatim. Example: `{"he":"אקמול"}`. | | `terms[].translations.he` | string | | | `terms[].translations.en` | string | | | `terms[].translations.ru` | string | | | `terms[].note` | string \| null | Your own note, up to 500 characters. Example: `"paracetamol 500 mg brand"`. | | `terms[].created_at` | string | ISO 8601 timestamp. Example: `"2026-01-15T09:30:00.000Z"`. | | `count` | integer | | ```json { "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 } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached. | `invalid_request`: "Each term needs a non-empty "term"."; `invalid_request`: "translations: unsupported language "fr". Use he, en or ru."; `invalid_request` / `terms_limit`: "An account may hold at most 2000 terms." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ### DELETE /v1/terms/{id} **Delete one protected term.** Operation id: `deleteTerm`. Remove one term by id. New requests stop using it within 30 seconds. Authentication: `Authorization: Bearer `. #### Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Example: `"3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f"`. | #### Example request ```bash curl -X DELETE https://hc.itsbaba.com/v1/terms/3f2c1a9e-8b7d-4c6e-9f10-2a3b4c5d6e7f \ -H "Authorization: Bearer hc_live_YOUR_KEY" ``` #### Response 200 Deleted | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `deleted` | boolean | | ```json { "deleted": true } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid body, a term that is empty or too long, an unsupported language in `translations`, or the account limit reached. | `invalid_request`: "Each term needs a non-empty "term"."; `invalid_request`: "translations: unsupported language "fr". Use he, en or ru."; `invalid_request` / `terms_limit`: "An account may hold at most 2000 terms." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 404 | No term with this id on the account. | `not_found`: "No such term." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ## Directionality Deterministic RTL/LTR analysis, render-ready display output and language detection. No model, no character quota. ### POST /v1/analyze **Analyze directionality.** Operation id: `analyze`. 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. **Quota.** Deterministic, no model. Does not consume the character quota; counts toward the rate limit only. **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. Authentication: `Authorization: Bearer `. #### Request body 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. | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | no | A single string, up to 20,000 characters. Send this or `fields`. 1 to 20,000 characters. Example: `"שלום world"`. | | `fields` | object | no | 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` | string | no | Paragraph direction to resolve against. `auto` (default) uses the first strong letter. One of: `auto`, `ltr`, `rtl`. Default: `"auto"`. Example: `"auto"`. | Example (A whole record at once): ```json { "fields": { "title": "מסמך Q3 ready", "subtitle": "Read the summary" } } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/analyze \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "שלום world" }' ``` #### Response 200 Directionality analysis | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `analysis` | object | | | `analysis.dir` | string | Paragraph base direction. With `base: "auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `analysis.mixed` | boolean | 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`. | | `analysis.lang` | string | Dominant BCP 47 language, from the dominant script. Example: `"he"`. | | `analysis.script` | string | Dominant ISO 15924 script. Example: `"Hebr"`. | | `analysis.runs` | object[] | Runs exactly as the Unicode Bidirectional Algorithm resolves them. | | `analysis.runs[].text` | string | The run text. Equals `input.slice(start, end)`. Example: `"שלום "`. | | `analysis.runs[].dir` | string | Resolved direction of the run. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `analysis.runs[].script` | string | ISO 15924 script of the run: `Hebr`, `Latn`, `Cyrl`, `Arab`, or `Zyyy` for digits and punctuation only. Example: `"Hebr"`. | | `analysis.runs[].lang` | string | Best-effort BCP 47 language of the run, from its script. `und` when undetermined (numbers, symbols). Example: `"he"`. | | `analysis.runs[].start` | integer | UTF-16 offset of the first character, inclusive. Example: `0`. | | `analysis.runs[].end` | integer | UTF-16 offset after the last character, exclusive. Example: `5`. | | `analysis.display_runs` | object[] | 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. Same fields as `analysis.runs[]`. | | `fields` | object | Present when the request sent `fields`: one analysis per field name. | | `fields..dir` | string | Paragraph base direction. With `base: "auto"` this follows the Unicode first-strong rule, matching CSS `dir="auto"`. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `fields..mixed` | boolean | 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`. | | `fields..lang` | string | Dominant BCP 47 language, from the dominant script. Example: `"he"`. | | `fields..script` | string | Dominant ISO 15924 script. Example: `"Hebr"`. | | `fields..runs` | object[] | Runs exactly as the Unicode Bidirectional Algorithm resolves them. Same fields as `analysis.runs[]`. | | `fields..display_runs` | object[] | 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. Same fields as `analysis.runs[]`. | ```json { "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 } ] } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request`: "Provide either "text" or "fields"." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ### POST /v1/detect **Detect language.** Operation id: `detect`. 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`. **Quota.** Deterministic, no model. Does not consume the character quota. **Limits.** `text` up to 20,000 characters. Idempotent. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | Text to classify, up to 20,000 characters. Built for short, code-switched input. 1 to 20,000 characters. Example: `"Можно оплатить через PayPal сегодня?"`. | Example (Hebrew with an English term): ```json { "text": "איך מחברים את ה-API לחשבון?" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/detect \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Можно оплатить через PayPal сегодня?" }' ``` #### Response 200 Detection | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `lang` | string | Dominant language (BCP 47). Latin script is tagged `en`. Example: `"ru"`. | | `script` | string | Dominant ISO 15924 script. Example: `"Cyrl"`. | | `dir` | string | Base direction of the dominant language. One of: `ltr`, `rtl`. Example: `"ltr"`. | | `confidence` | number | Share of letters in the dominant language, 0 to 1. Example: `0.941`. | | `segments` | object[] | Same-script stretches in order, e.g. ru · en ("CBC") · ru. Latin script is tagged en. | | `segments[].text` | string | Example: `"PayPal "`. | | `segments[].start` | integer | Example: `21`. | | `segments[].end` | integer | Example: `28`. | | `segments[].script` | string | Example: `"Latn"`. | | `segments[].lang` | string | Example: `"en"`. | | `languages` | object[] | Every language found, largest share first. | | `languages[].lang` | string | Example: `"ru"`. | | `languages[].share` | number | Share of letters, 0 to 1. Example: `0.941`. | ```json { "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 } ] } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request`: "Provide either "text" or "fields"." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ### POST /v1/wrap **Wrap a line for display.** Operation id: `wrap`. 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. Pick `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. **Quota.** Deterministic, no model. Does not consume the character quota. Fast enough to call per line at render time. **Limits.** `text` up to 20,000 characters. Idempotent. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | The display line, up to 20,000 characters. 1 to 20,000 characters. Example: `"הנחה: 10–20% על Galaxy S25 עד 31/12"`. | | `format` | string | no | `html` for the web; `isolate` (Unicode isolates) for modern text engines; `marks` (LRM/RLM) for every renderer, including older Android. One of: `html`, `isolate`, `marks`. Default: `"html"`. Example: `"html"`. | | `base` | string | no | Paragraph direction of the display surface. Pass `rtl` for a Hebrew line even when it starts with a Latin term. One of: `auto`, `ltr`, `rtl`. Default: `"auto"`. Example: `"rtl"`. | Example (Order status for an older Android screen): ```json { "text": "ההזמנה A-10234 יוצאת ב־08:30", "format": "marks", "base": "rtl" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/wrap \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "הנחה: 10–20% על Galaxy S25 עד 31/12", "format": "html", "base": "rtl" }' ``` #### Response 200 Wrapped output | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `dir` | string | Paragraph direction used. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `format` | string | Format used. Example: `"html"`. | | `output` | string | Render-ready text: HTML with `dir` spans, or the text with Unicode isolates or direction marks inserted. | | `runs` | object[] | The display runs the output was built from. | | `runs[].text` | string | The run text. Equals `input.slice(start, end)`. Example: `"שלום "`. | | `runs[].dir` | string | Resolved direction of the run. One of: `ltr`, `rtl`. Example: `"rtl"`. | | `runs[].script` | string | ISO 15924 script of the run: `Hebr`, `Latn`, `Cyrl`, `Arab`, or `Zyyy` for digits and punctuation only. Example: `"Hebr"`. | | `runs[].lang` | string | Best-effort BCP 47 language of the run, from its script. `und` when undetermined (numbers, symbols). Example: `"he"`. | | `runs[].start` | integer | UTF-16 offset of the first character, inclusive. Example: `0`. | | `runs[].end` | integer | UTF-16 offset after the last character, exclusive. Example: `5`. | ```json { "dir": "rtl", "format": "html", "output": "הנחה: 10–20% על Galaxy S25 עד 31/12", "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 } ] } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request`: "Provide either "text" or "fields"." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ## Hebrew Nikud (vowel points) for display and speech, and removing them for search and normalization. ### POST /v1/nikud **Add nikud (vowel points).** Operation id: `addNikud`. 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. The 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. **Quota.** Consumes the monthly character quota: the length of `text`. **Limits.** `text` up to 10,000 characters. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | Hebrew text to vocalize, up to 10,000 characters. English terms and numbers pass through. 1 to 10,000 characters. Example: `"שלום עולם"`. | Example (Hebrew with an English term and a number): ```json { "text": "ההזמנה שלך ל-Galaxy S25 תגיע בעוד 3 ימים" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/nikud \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "שלום עולם" }' ``` #### Response 200 Vocalized text | Header | Description | | --- | --- | | `X-Usage-Chars-Used` | Characters used this month by the account, including this request. | | `X-Usage-Chars-Limit` | Monthly character quota of the account. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `text` | string | The input. Example: `"שלום עולם"`. | | `nikud` | string | The vocalized text, or the input unchanged when `verified` is false. Example: `"שָׁלוֹם עוֹלָם"`. | | `verified` | boolean | 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`. | ```json { "text": "שלום עולם", "nikud": "שָׁלוֹם עוֹלָם", "verified": true } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request` / `unsupported_language`: "Protected translation supports Hebrew (he), English (en) and Russian (ru)."; `invalid_request` / `same_language`: "source_lang and target_lang must differ." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | | 502 | The model provider failed or returned an empty result. Nothing was charged. Safe to retry. | `bad_gateway` / `upstream_error`: "Translation provider error." | | 503 | A model feature is temporarily unavailable. | `service_unavailable` / `not_configured`: "Translation is not configured on this server." | ### POST /v1/strip-nikud **Remove nikud.** Operation id: `stripNikud`. 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. **Quota.** Deterministic, no model. Does not consume the character quota. **Limits.** `text` up to 20,000 characters. Idempotent. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | Hebrew text with nikud or cantillation, up to 20,000 characters. 1 to 20,000 characters. Example: `"שָׁלוֹם"`. | #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/strip-nikud \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "שָׁלוֹם" }' ``` #### Response 200 Stripped text | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `text` | string | The input. Example: `"שָׁלוֹם"`. | | `stripped` | string | The text without nikud, dagesh or cantillation. Punctuation such as the maqaf is kept. Example: `"שלום"`. | ```json { "text": "שָׁלוֹם", "stripped": "שלום" } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required"; `invalid_request`: "Provide either "text" or "fields"." | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The connection used TLS older than 1.2. | `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ## Clinical API 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. ### POST /v1/medical/translate **Translate clinical English into verified Hebrew.** Operation id: `medicalTranslate`. 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. Every 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. **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`. **Quota.** Consumes the monthly character quota: the length of `text`. Refunded when the provider fails for every sentence. **Limits.** `text` up to 20,000 characters. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `audience` | string | no | Who reads the Hebrew. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes dosing shorthand (BID, PRN) as plain words. One of: `clinician`, `patient`. Default: `"clinician"`. Example: `"patient"`. | | `reader_gender` | string | no | Gender of the reader, the person the text calls "you". Omit when unknown. One of: `male`, `female`. Example: `"female"`. | | `patient_gender` | string | no | Gender of the patient in third-person references. Inferred from he/she when omitted. One of: `male`, `female`. Example: `"male"`. | | `protected_terms` | string[] | no | 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. Up to 500 items. Each item up to 200 characters. Example: `["Eliquis 5 mg BID","atrial fibrillation"]`. | | `redact_terms` | string[] | no | Kept verbatim and never shown to the model (patient and staff names). Up to 200. Up to 200 items. Each item up to 200 characters. Example: `["Dana Levi"]`. | | `glossary` | object | no | English term → required Hebrew rendering. Up to 500 entries. Example: `{"hypertension":"יתר לחץ דם"}`. | | `date_order` | string | no | How to read ambiguous numeric dates in the source. US records are MDY. One of: `MDY`, `DMY`. Default: `"MDY"`. Example: `"MDY"`. | | `date_style` | string | no | `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. One of: `hebrew`, `iso`, `keep`. Default: `"hebrew"`. Example: `"hebrew"`. | | `bidi` | string | no | `isolate` wraps English values in Unicode isolates so "5 mg" never renders as "mg 5". `none` returns plain text. One of: `isolate`, `none`. Default: `"isolate"`. Example: `"isolate"`. | | `text` | string | yes | English text, 1 to 20,000 characters. Markdown lists, headings and tables keep their structure. Counts toward the monthly character quota. 1 to 20,000 characters. | Example (Note for a clinician, with a redacted name and a glossary): ```json { "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": "יתר לחץ דם" } } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/medical/translate \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "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" ] }' ``` #### Response 200 Translation | Header | Description | | --- | --- | | `Cache-Control` | Always `no-store` on the Clinical API. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `id` | string | Request identifier. Example: `"med_a1b2c3d4e5f6"`. | | `text` | string | The whole Hebrew document: every segment joined with its prefix and suffix. Example: `"את נוטלת Eliquis 5 mg פעמיים ביום. המינון שלך שונה ב־4 במרץ 2026."`. | | `segments` | object[] | One entry per sentence, in order. | | `segments[].index` | integer | Position of the sentence, from 0. Example: `0`. | | `segments[].prefix` | string | Markdown structure emitted before the text (list marker, heading). Example: `"- "`. | | `segments[].suffix` | string | Whitespace or structure after the text. Join `prefix + text + suffix` for every segment to rebuild the document. Example: `"\n"`. | | `segments[].source` | string | The English sentence. Example: `"You are taking Eliquis 5 mg twice a day."`. | | `segments[].text` | string | Verified Hebrew, or the English source when status is `fallback`. Example: `"את נוטלת Eliquis 5 mg פעמיים ביום."`. | | `segments[].status` | string | `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. One of: `ok`, `retried`, `fallback`, `passthrough`. Example: `"ok"`. | | `segments[].issues` | object[] | Why a sentence was retried or fell back. Empty for `ok`. | | `segments[].issues[].code` | string | 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"`. | | `segments[].issues[].severity` | string | `error` blocks the sentence; `warning` is informational. One of: `error`, `warning`. Example: `"error"`. | | `segments[].issues[].detail` | string | Human-readable explanation. Example: `"The source says \"no known allergies\"; the translation drops the negation."`. | | `segments[].spans` | object[] | Protected values in this sentence. Redacted names and identifiers are left out. | | `segments[].spans[].type` | string | What was protected: `drug`, `dose`, `abbreviation`, `code`, `number`, `date`, `term`, `glossary`, `identifier`, `name` and others. Example: `"dose"`. | | `segments[].spans[].value` | string | The protected source value. Omitted for names and identifiers. Example: `"5 mg"`. | | `segments[].spans[].render` | string | How the value was written in the Hebrew, when it was rewritten (dates). Example: `"4 במרץ 2026"`. | | `segments[].spans[].ambiguous_date` | boolean | True when a numeric date could be read two ways and `date_order` decided it. Example: `true`. | | `stats` | object | | | `stats.segments` | integer | Total sentences. Example: `2`. | | `stats.ok` | integer | Example: `2`. | | `stats.retried` | integer | Example: `0`. | | `stats.fallback` | integer | Sentences returned in English. Treat them as untranslated. Example: `0`. | | `stats.passthrough` | integer | Example: `0`. | | `usage` | object | | | `usage.characters` | integer | Characters charged. Example: `77`. | ```json { "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 } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required" | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2. | `forbidden` / `scope_required`: "This API key is not enabled for medical translation. Contact HebrewCore to enable it."; `forbidden` / `server_only`: "Medical endpoints must be called from your server, never from a browser."; `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 502 | The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry. | `bad_gateway` / `upstream_error`: "The model provider is unavailable. No Hebrew was produced."; `bad_gateway` / `unverified`: "The query could not be translated without losing a protected value." | | 503 | Medical translation is not configured on this server. | `service_unavailable` / `not_configured`: "Medical translation is not configured on this server." | ### POST /v1/medical/translate/stream **Translate clinical English, streamed as Server-Sent Events.** Operation id: `medicalTranslateStream`. 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. Events: `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](https://hc.itsbaba.com/docs#medical-stream)). **Quota.** Charged up front for the length of `text`; refunded when the provider fails for every sentence. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `audience` | string | no | Who reads the Hebrew. `clinician` (default) keeps shorthand such as BID and PO; `patient` writes dosing shorthand (BID, PRN) as plain words. One of: `clinician`, `patient`. Default: `"clinician"`. Example: `"patient"`. | | `reader_gender` | string | no | Gender of the reader, the person the text calls "you". Omit when unknown. One of: `male`, `female`. Example: `"female"`. | | `patient_gender` | string | no | Gender of the patient in third-person references. Inferred from he/she when omitted. One of: `male`, `female`. Example: `"male"`. | | `protected_terms` | string[] | no | 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. Up to 500 items. Each item up to 200 characters. Example: `["Eliquis 5 mg BID","atrial fibrillation"]`. | | `redact_terms` | string[] | no | Kept verbatim and never shown to the model (patient and staff names). Up to 200. Up to 200 items. Each item up to 200 characters. Example: `["Dana Levi"]`. | | `glossary` | object | no | English term → required Hebrew rendering. Up to 500 entries. Example: `{"hypertension":"יתר לחץ דם"}`. | | `date_order` | string | no | How to read ambiguous numeric dates in the source. US records are MDY. One of: `MDY`, `DMY`. Default: `"MDY"`. Example: `"MDY"`. | | `date_style` | string | no | `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. One of: `hebrew`, `iso`, `keep`. Default: `"hebrew"`. Example: `"hebrew"`. | | `bidi` | string | no | `isolate` wraps English values in Unicode isolates so "5 mg" never renders as "mg 5". `none` returns plain text. One of: `isolate`, `none`. Default: `"isolate"`. Example: `"isolate"`. | | `text` | string | yes | English text, 1 to 20,000 characters. Markdown lists, headings and tables keep their structure. Counts toward the monthly character quota. 1 to 20,000 characters. | Example (Note for a clinician, with a redacted name and a glossary): ```json { "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": "יתר לחץ דם" } } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/medical/translate/stream \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "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" ] }' ``` #### Response 200 A stream of `segment` events, then `done` or `error`. | Header | Description | | --- | --- | | `Cache-Control` | Always `no-store` on the Clinical API. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | Content type `text/event-stream`. ```text event: segment data: {"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"}]} event: segment data: {"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}]} event: done data: {"stats":{"segments":2,"ok":2,"retried":0,"fallback":0,"passthrough":0},"usage":{"characters":77}} ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required" | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2. | `forbidden` / `scope_required`: "This API key is not enabled for medical translation. Contact HebrewCore to enable it."; `forbidden` / `server_only`: "Medical endpoints must be called from your server, never from a browser."; `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 502 | The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry. | `bad_gateway` / `upstream_error`: "The model provider is unavailable. No Hebrew was produced."; `bad_gateway` / `unverified`: "The query could not be translated without losing a protected value." | | 503 | Medical translation is not configured on this server. | `service_unavailable` / `not_configured`: "Medical translation is not configured on this server." | ### GET /v1/medical/stream **Clinical translation over a WebSocket, for English that is still being generated.** Operation id: `medicalStreamSocket`. 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. **You send** JSON text frames (each under 64 KB): - `{"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). - `{"type":"delta","text":"..."}` for each piece of English, as it arrives. - `{"type":"end"}` when the English is complete. **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. **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. Authentication: `Authorization: Bearer `. #### Example request ```bash curl https://hc.itsbaba.com/v1/medical/stream \ -H "Authorization: Bearer hc_live_YOUR_KEY" ``` #### Response 101 Switching Protocols: the WebSocket is open. #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Not a WebSocket upgrade request (`upgrade_required`). | | | 401 | Missing, invalid or revoked API key. | | | 403 | The key lacks Clinical access, or the request came from a browser. | | | 429 | Rate limit, or too many open sessions (`too_many_sessions`). | | ### POST /v1/medical/query **Turn a Hebrew question into an English record query.** Operation id: `medicalQuery`. 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. **Quota.** Consumes the monthly character quota: the length of `text`. Refunded when the query cannot be verified (`502 unverified`) or the provider fails. **Limits.** `text` up to 2,000 characters. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `text` | string | yes | The Hebrew question, up to 2,000 characters. 1 to 2,000 characters. Example: `"האם המטופלת עדיין לוקחת מטפורמין?"`. | | `known_terms` | string[] | no | English terms from the patient's record, used to map Hebrew spellings back. Up to 500. Account terms are added automatically. Up to 500 items. Each item up to 200 characters. Example: `["metformin","lisinopril"]`. | | `glossary` | object | no | English term → Hebrew rendering, used to map the Hebrew back to English. Example: `{"metformin":"מטפורמין"}`. | Example (Lab question with a date): ```json { "text": "מה היה ה-HbA1c בבדיקה מ-12/05/2026?" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/medical/query \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "האם המטופלת עדיין לוקחת מטפורמין?", "known_terms": [ "metformin", "lisinopril" ] }' ``` #### Response 200 English query | Header | Description | | --- | --- | | `Cache-Control` | Always `no-store` on the Clinical API. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `query` | string | English query for your record search. Example: `"Is the patient still taking metformin?"`. | | `terms` | object[] | Hebrew spellings that were mapped back to English terms. | | `terms[].hebrew` | string | Example: `"מטפורמין"`. | | `terms[].english` | string | Example: `"metformin"`. | | `terms[].source` | string | Where the mapping came from. One of: `known_terms`, `lexicon`, `glossary`. Example: `"known_terms"`. | | `usage` | object | | | `usage.characters` | integer | Example: `33`. | ```json { "query": "Is the patient still taking metformin?", "terms": [ { "hebrew": "מטפורמין", "english": "metformin", "source": "known_terms" } ], "usage": { "characters": 33 } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required" | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2. | `forbidden` / `scope_required`: "This API key is not enabled for medical translation. Contact HebrewCore to enable it."; `forbidden` / `server_only`: "Medical endpoints must be called from your server, never from a browser."; `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 502 | The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry. | `bad_gateway` / `upstream_error`: "The model provider is unavailable. No Hebrew was produced."; `bad_gateway` / `unverified`: "The query could not be translated without losing a protected value." | | 503 | Medical translation is not configured on this server. | `service_unavailable` / `not_configured`: "Medical translation is not configured on this server." | ### POST /v1/medical/verify **Verify a Hebrew translation against its English source.** Operation id: `medicalVerify`. 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. `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. **Quota.** Consumes the monthly character quota: the length of `source` plus `translation`. **Limits.** `source` up to 20,000 characters, `translation` up to 40,000. Authentication: `Authorization: Bearer `. #### Request body | Field | Type | Required | Description | | --- | --- | --- | --- | | `source` | string | yes | The English source, up to 20,000 characters. 1 to 20,000 characters. Example: `"Metformin 500 mg BID since 03/04/2026."`. | | `translation` | string | yes | The Hebrew to check, up to 40,000 characters. 1 to 40,000 characters. Example: `"Metformin 50 mg BID מאז 03/04/2026."`. | | `protected_terms` | string[] | no | Terms that must appear verbatim. Up to 500. Up to 500 items. Each item up to 200 characters. Example: `["Metformin"]`. | | `redact_terms` | string[] | no | Names replaced before the reviewer sees the text. Up to 200. Up to 200 items. Each item up to 200 characters. Example: `["Dana Levi"]`. | | `glossary` | object | no | English term → required Hebrew rendering. Example: `{"hypertension":"יתר לחץ דם"}`. | | `date_order` | string | no | How to read ambiguous numeric dates in the source. One of: `MDY`, `DMY`. Default: `"MDY"`. Example: `"MDY"`. | | `verification` | string | no | `standard` (default) runs the deterministic checks. `strict` adds an independent model review for meaning changes. One of: `strict`, `standard`. Default: `"standard"`. Example: `"standard"`. | Example (Strict review of a patient message): ```json { "source": "No known drug allergies. Stop ibuprofen 3 days before surgery.", "translation": "אין אלרגיות ידועות לתרופות. יש להפסיק ibuprofen 3 ימים לפני הניתוח.", "protected_terms": [ "ibuprofen" ], "verification": "strict" } ``` #### Example request ```bash curl -X POST https://hc.itsbaba.com/v1/medical/verify \ -H "Authorization: Bearer hc_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "source": "Metformin 500 mg BID since 03/04/2026.", "translation": "Metformin 50 mg BID מאז 03/04/2026." }' ``` #### Response 200 Verdict | Header | Description | | --- | --- | | `Cache-Control` | Always `no-store` on the Clinical API. | | `X-Content-Stored` | Whether the request text or the result was stored. `false` in the default no-retention mode. | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `pass` | boolean | True when no issue has severity `error`. Example: `false`. | | `issues` | object[] | Every problem found. | | `issues[].code` | string | 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"`. | | `issues[].severity` | string | `error` blocks the sentence; `warning` is informational. One of: `error`, `warning`. Example: `"error"`. | | `issues[].detail` | string | Human-readable explanation. Example: `"The source says \"no known allergies\"; the translation drops the negation."`. | | `usage` | object | | | `usage.characters` | integer | Characters charged: source plus translation. Example: `72`. | ```json { "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 } } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 400 | Invalid request: the body failed validation or a value is out of range. | `invalid_request`: "Required" | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 403 | The key lacks the `medical` scope, the request came from a browser, or TLS is older than 1.2. | `forbidden` / `scope_required`: "This API key is not enabled for medical translation. Contact HebrewCore to enable it."; `forbidden` / `server_only`: "Medical endpoints must be called from your server, never from a browser."; `forbidden` / `tls_version`: "TLS 1.2 or newer is required." | | 429 | 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. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry."; `quota_exceeded`: "Monthly character quota of 100,000 reached." | | 502 | The model provider failed for every sentence, so no Hebrew was produced. The characters are refunded. Safe to retry. | `bad_gateway` / `upstream_error`: "The model provider is unavailable. No Hebrew was produced."; `bad_gateway` / `unverified`: "The query could not be translated without losing a protected value." | | 503 | Medical translation is not configured on this server. | `service_unavailable` / `not_configured`: "Medical translation is not configured on this server." | ## Reference Supported languages and the public health check. ### GET /v1/languages **List supported languages.** Operation id: `listLanguages`. 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. Authentication: `Authorization: Bearer `. #### Example request ```bash curl https://hc.itsbaba.com/v1/languages \ -H "Authorization: Bearer hc_live_YOUR_KEY" ``` #### Response 200 Languages | Header | Description | | --- | --- | | `X-RateLimit-Limit` | Requests allowed per minute for this key: 60 on Standard, 600 on Scale. | | `X-RateLimit-Remaining` | Requests left in the current minute. | | `Server-Timing` | 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. | | Field | Type | Description | | --- | --- | --- | | `languages` | object[] | Every supported language. | | `languages[].code` | string | BCP 47 code to pass as `source_lang` or `target_lang`. Example: `"he"`. | | `languages[].name` | string | English name. Example: `"Hebrew"`. | | `languages[].native` | string | Name in the language itself. Example: `"עברית"`. | | `languages[].dir` | string | Writing direction. One of: `ltr`, `rtl`. Example: `"rtl"`. | ```json { "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" } ] } ``` #### Errors | Status | When | type / code: example message | | --- | --- | --- | | 401 | Missing, malformed, invalid or revoked API key. | `unauthorized`: "Missing or malformed API key. Use header: Authorization: Bearer hc_live_…"; `unauthorized`: "Invalid or revoked API key." | | 429 | Too many requests this minute. Retry after a short wait. | `rate_limited`: "Rate limit of 600/min exceeded. Slow down and retry." | | 500 | Unexpected server error. Safe to retry. | `internal`: "Internal error." | ### GET /v1/health **Health check.** Operation id: `health`. Liveness and database check. Public: no API key needed, no rate limit, no quota. Use it for uptime monitoring. Authentication: none (public). #### Example request ```bash curl https://hc.itsbaba.com/v1/health ``` #### Response 200 Health | Field | Type | Description | | --- | --- | --- | | `status` | string | `ok` when the API is serving. Example: `"ok"`. | | `db` | string | `ok`, or `error` when the database check failed. Example: `"ok"`. | | `version` | string | API version. Example: `"1.0.0"`. | ```json { "status": "ok", "db": "ok", "version": "1.0.0" } ```