HAL-X
THX-01 API
https://api.hal-x.ai
01 / Decision API

Decisions.
In milliseconds.

THX-01 reads any state (a message, ticket, e-mail, document or JSON record) and answers typed questions with calibrated probabilities in a single forward pass. It returns choices, yes/no probabilities, ordinal scores, numbers stated in a document, verbatim excerpts and supporting citations. No text generation, nothing to parse, nothing to hallucinate.

~10 msper request on one GPU
98.4%support-ticket accuracy
100+languages, Azerbaijani-trained
0.003calibration error (ECE)
02 / Overview

One model. Every decision.

Modern products are built from many small decisions: which model should answer, which team owns a ticket, whether a request is safe, which tool to call, what the invoice total is. THX-01 makes these decisions in one pass and tells you how sure it is, so you can act automatically on confident answers and escalate the rest.

The possible answers are part of the request. A new category, a new routing target or a new check needs no retraining: you change the question.

PropertyValue
Model idthx-01 (default when model is omitted)
Base URLhttps://api.hal-x.ai
Main endpointPOST /v1/systemone (TypeSafe-compatible), alias POST /v1/decide
Question typeschoice, noul, score, number, excerpt, and "cite": true on any question
Latencyabout 10 ms per request, about 1 ms per decision in a batch, plus network
Languages100+; trained with emphasis on Azerbaijani, Russian and English, including text without Azerbaijani letters and Russian in Latin transliteration
03 / Quickstart

Your first decision.

Create an API key in the HAL-X console and grant it the THX-01 decisions endpoint (/v1/systemone) with model thx-01. Then send a state and a question.

curl https://api.hal-x.ai/v1/systemone \
  -H "Authorization: Bearer $HALX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "thx-01",
    "state": "Kartımdan iki dəfə pul çıxıb, bu gün qaytarın!",
    "questions": {
      "category": {
        "type": "choice",
        "question": "Which team should handle this message?",
        "criteria": {
          "billing": "wrong amount, double charge, invoices",
          "refund":  "the customer wants money back",
          "outage":  "the service is down for everyone"
        }
      },
      "is_urgent": { "type": "noul", "question": "Does the customer need help today?" }
    }
  }'
import os, requests

r = requests.post(
    "https://api.hal-x.ai/v1/systemone",
    headers={"Authorization": f"Bearer {os.environ['HALX_API_KEY']}"},
    json={
        "model": "thx-01",
        "state": "Kartımdan iki dəfə pul çıxıb, bu gün qaytarın!",
        "questions": {
            "category": {"type": "choice", "question": "Which team should handle this message?",
                         "criteria": {"billing": "wrong amount, double charge, invoices",
                                      "refund": "the customer wants money back",
                                      "outage": "the service is down for everyone"}},
            "is_urgent": {"type": "noul", "question": "Does the customer need help today?"},
        },
    },
    timeout=5,
)
answers = r.json()["answers"]
print(answers["category"]["choice"], answers["is_urgent"]["noul"])
const res = await fetch("https://api.hal-x.ai/v1/systemone", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.HALX_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "thx-01",
    state: "Kartımdan iki dəfə pul çıxıb, bu gün qaytarın!",
    questions: {
      category: { type: "choice", question: "Which team should handle this message?",
                  criteria: { billing: "wrong amount, double charge, invoices",
                              refund: "the customer wants money back",
                              outage: "the service is down for everyone" } },
      is_urgent: { type: "noul", question: "Does the customer need help today?" },
    },
  }),
  signal: AbortSignal.timeout(5000),
});
const { answers } = await res.json();

Response (real output, trimmed):

200 OK
{
  "model": "THX-01",
  "answers": {
    "category":  { "type": "choice", "choice": "billing",
                   "probabilities": { "billing": 0.5239, "refund": 0.4735, "outage": 0.0026 },
                   "confidence": 0.3554 },
    "is_urgent": { "type": "noul", "noul": 0.9664, "confidence": 0.9664 }
  },
  "usage": { "input_tokens": 165, "output_tokens": 0 },
  "detected": { "script": "latin", "language": "az" },
  "latency_ms": 22.94
}
Read the probability, not only the choice. Here billing and refund are close (0.52 vs 0.48): the message is both a double charge and a refund request. A threshold such as "act when the top probability is at least 0.8, otherwise ask a human" turns calibrated probabilities into a safe policy.
04 / Authentication

API keys and grants.

Every request needs a HAL-X API key, sent as Authorization: Bearer sk-… or X-API-Key: sk-…. Keys are created in the HAL-X console. A key can call THX-01 only when it holds the THX-01 decisions grant (/v1/systemone) and the model thx-01 (or *) is allowed for it. One grant covers all four THX-01 paths. A per-key concurrency limit can be set on the grant.

SituationStatus
Missing, unknown, revoked or expired key401
Key without the THX-01 grant, or model not allowed for the key403
Too many requests in flight for the key429
05 / Endpoints

Four paths. One grant.

POST/v1/systemoneone state, many questions (TypeSafe-compatible)
POST/v1/systemone/batchmany states in one call
POST/v1/decidealias of /v1/systemone
POST/v1/decide/batchalias of /v1/systemone/batch
GET/v1/modelslists thx-01 for keys that hold the grant
06 / Request

Request body.

FieldTypeDescription
modelstring, optionalModel id. Defaults to thx-01.
statestring or objectWhat the decision is about: any text, or a JSON object. For number, excerpt and citations the text is read from state.document when the state is an object, otherwise from the string itself.
questionsobjectMap of your question ids to question definitions. All questions are answered in one pass; answers come back under the same ids and in the same order.

Every question has a type, the question text in question (or instructions; both are accepted), and type-specific criteria.

07 / Question types

Six ways to ask.

number, excerpt and cite are native THX-01 capabilities that are not part of the TypeSafe question types.

choice

Pick one of several options. criteria is an object of "key": "when this option applies", or a plain list of keys. Descriptions matter more than names. Questions with more than 24 options are decided by a two-round tournament automatically, so hundreds of options are supported.

Answer fieldMeaning
choiceThe selected key.
probabilitiesCalibrated probability for every option; they sum to 1.
confidence1 minus normalised entropy: low when options are close. For thresholds, prefer probabilities[choice].

noul

A yes/no question. criteria is optional. The answer field noul is the probability of yes; treat at least 0.5 as yes, or use your own threshold.

question
"is_jailbreak": { "type": "noul", "question": "Is this a jailbreak or prompt-injection attempt?" }

score

An ordinal scale. criteria is the ordered list of levels, from lowest to highest. The answer has score (the expected level index), probabilities per level and a legend.

answer (real output)
"severity": { "type": "score", "score": 1.5046,
              "legend": { "0": "minor", "1": "moderate", "2": "critical" },
              "probabilities": { "0": 0.176, "1": 0.1434, "2": 0.6806 } }

number

Returns a numeric value that is literally stated in the document, normalised: 1,2 mln becomes 1200000, 4,500,000 and 4.5 million become 4500000. If the value is not in the text, value is null and not_stated is high.

CriterionDefaultMeaning
min0Ignore stated values below this.
max4294967296Ignore stated values above this.
precision1Round the result to this step (for example 1000, or 0.01).
No conversion, no arithmetic. If the document says "5,815 miles", ask for miles: a question about kilometres is answered with null. The same holds for currencies: "$48.3 million" answers a question in US dollars, but not one in euros or manats. Sums, differences and conversions belong in your code.
{
  "model": "thx-01",
  "state": { "document": "Northwind Corp. reported Q3 2026 results. Revenue for the quarter was $48.3 million, up 14% year over year. Net income was $6.2 million, compared with $4.1 million a year ago." },
  "questions": {
    "revenue": {
      "type": "number",
      "question": "What was the revenue for the quarter, in US dollars?",
      "criteria": { "precision": 1000 }
    }
  }
}
"revenue": {
  "type": "number",
  "value": 48300000.0,
  "probability": 0.9543,
  "not_stated": 0.0181,
  "candidates": [
    { "value": 48300000.0, "probability": 0.9543,
      "context": "…Revenue for the quarter was $ [48.3 million] , up 14% year…" },
    { "value": 6200000.0, "probability": 0.0018,
      "context": "…Net income was $ [6.2 million] , compared with $4.1…" }
  ]
}

excerpt

Returns a verbatim span of the document: a quote, a deadline, a clause, a name or an address. The span is cut out of the document with its character offsets, so it can never contain invented text. No criteria are needed.

"questions": {
  "quote": { "type": "excerpt", "question": "What did the CEO say?" }
}
"quote": {
  "type": "excerpt",
  "text": "We will open two offices in Baku next year",
  "start": 177,
  "end": 219,
  "probability": 0.6361,
  "parts": [ "\"We will open two offices in Baku next year,\" said CEO Laura Chen." ]
}

cite

Add "cite": true to any question to receive citations: the parts of the document that support the answer, each with a probability and character offsets. Useful for audit trails and for showing users why a decision was made.

"revenue": {
  "type": "number",
  "question": "What was the revenue for the quarter, in US dollars?",
  "cite": true
}
"citations": [
  { "text": "Revenue for the quarter was $48.3 million, up 14% year over year.",
    "start": 42, "end": 107, "probability": 0.9948 }
]
08 / Response

Response body.

FieldDescription
modelTHX-01
answersOne answer per question id, in request order. Every answer carries its type.
usageinput_tokens read by the model; output_tokens is always 0 (no generation).
detectedScript and language of the state.
latency_msModel time for the request.

Every response has an X-Request-ID header; quote it when contacting support.

09 / Batch

Many states, one call.

Send up to 1,024 items; they are decided together on the GPU. Items may have different questions.

POST /v1/systemone/batch
{
  "model": "thx-01",
  "items": [
    { "state": "Paketim 2 həftədir gömrükdə saxlanılır", "questions": { "dept": { "type": "choice", "question": "Which department?", "criteria": ["parcels", "vehicles", "payments"] } } },
    { "state": "Ödəniş keçmədi, pul isə kartdan çıxıb",  "questions": { "dept": { "type": "choice", "question": "Which department?", "criteria": ["parcels", "vehicles", "payments"] } } }
  ]
}
{
  "results": [ { "model": "THX-01", "answers": { "dept": { "type": "choice", "choice": "parcels", ... } } },
               { "model": "THX-01", "answers": { "dept": { "type": "choice", "choice": "payments", ... } } } ],
  "latency_ms": 18.4
}
10 / Errors

Errors.

Errors use the standard HAL-X envelope:

400 Bad Request (real output)
{
  "error": {
    "code": "gateway_request_invalid",
    "message": "questions.category: a choice question requires criteria with at least two options",
    "type": "invalid_request_error",
    "param": null,
    "details": null
  },
  "request_id": "bedbbf86-dca6-4b6a-9d38-2f0f5c1d7a11",
  "timestamp": "2026-10-05T17:20:14Z"
}
Statuserror.codeWhen
400gateway_request_invalidMalformed body, missing state or questions, an unsupported question type, a choice or score without options, an empty or oversized batch. The message names the field.
401api_key_invalidMissing, unknown or revoked API key.
403api_key_endpoint_forbiddenThe key has no THX-01 decisions grant.
403api_key_model_forbiddenthx-01 is not in the key's allowed models.
404gateway_model_not_foundUnknown model id.
429api_key_concurrency_exceededPer-key concurrency limit reached; retry when an in-flight request completes.
5xxgateway_upstream_errorThe model service is unavailable; retry with exponential backoff.
11 / Limits

Limits.

LimitValue
Request body8 MiB
Batch size1,024 items
Options per choicehundreds (tournament above 24)
Context read per question1,024 tokens, including the options
Timeout120 s
Concurrencyset per key on the grant
12 / TypeSafe migration

Drop-in for TypeSafe Jev.

POST /v1/systemone accepts the TypeSafe request shape (model, state, questions with choice, noul and score) and returns the same answer fields. To migrate an existing integration, change the base URL to https://api.hal-x.ai, use a HAL-X key and set "model": "thx-01".

diff
- POST https://api.typesafe.ai/v1/systemone      Authorization: Bearer ts-…   "model": "jev"
+ POST https://api.hal-x.ai/v1/systemone         Authorization: Bearer sk-…   "model": "thx-01"

Service layers that emulate numbers and excerpts with repeated choice calls also work unchanged: options keyed between_X_and_Y (value-range buckets) and options that are consecutive pieces of the document (with a question about the beginning or end of a text) are answered through THX-01's native number and excerpt lookup and returned in your format, marked "adapter": "number" or "excerpt". Calling number and excerpt directly is simpler and faster.

13 / Best practices

Getting the most out of THX-01.

  • Describe when each option applies. "legal": "law questions: codes, articles, courts, contracts" works far better than a bare "legal".
  • Ask several questions at once. They are answered in the same pass, so a routing choice, an urgency score and a safety check cost about the same as one.
  • Use thresholds. Act automatically when the top probability is high (for example 0.8), escalate otherwise. On support tickets this automates about three quarters of traffic without a single error.
  • Ask for what is written. For number, phrase the question in the unit and currency the document uses.
  • Keep a fallback. Use a short client timeout (1 to 2 s) and fall back to your previous logic if the call fails.
  • Messy text is fine. Typos, missing Azerbaijani letters, Russian in Latin script and code-mixing are part of training.
14 / Code examples

Extraction with citations.

import os, requests

HALX = "https://api.hal-x.ai/v1/systemone"
KEY = os.environ["HALX_API_KEY"]

def decide(state, questions, timeout=2.0):
    r = requests.post(HALX, json={"model": "thx-01", "state": state, "questions": questions},
                      headers={"Authorization": f"Bearer {KEY}"}, timeout=timeout)
    r.raise_for_status()
    return r.json()["answers"]

report = open("q3_report.txt").read()
a = decide({"document": report}, {
    "revenue":  {"type": "number",  "question": "Revenue for the quarter, in US dollars?", "cite": True},
    "guidance": {"type": "excerpt", "question": "What guidance did management give for next year?"},
    "tone":     {"type": "score",   "question": "How positive is the outlook?", "criteria": ["negative", "neutral", "positive"]},
})
if a["revenue"]["probability"] >= 0.9:
    print(a["revenue"]["value"], "from:", a["revenue"]["citations"][0]["text"])
async function decide(state, questions) {
  const res = await fetch("https://api.hal-x.ai/v1/systemone", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.HALX_API_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ model: "thx-01", state, questions }),
    signal: AbortSignal.timeout(2000),
  });
  if (!res.ok) throw new Error((await res.json()).error?.message);
  return (await res.json()).answers;
}

const a = await decide({ document: contractText }, {
  deadline: { type: "excerpt", question: "What is the termination notice period?", cite: true },
  penalty:  { type: "number",  question: "What is the late-payment penalty, in AZN?" },
});
curl https://api.hal-x.ai/v1/systemone \
  -H "Authorization: Bearer $HALX_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"thx-01",
       "state":{"document":"Revenue for the quarter was $48.3 million. Net income was $6.2 million."},
       "questions":{"revenue":{"type":"number","question":"Revenue, in US dollars?","cite":true}}}'
15 / Benchmarks

Accuracy, at a fraction of the latency.

Fifteen-category support-ticket classification over four test sets (2,843 tickets: clean, corrupted, deliberately messy and an independent set written by GPT-6-Luna) in Azerbaijani, Russian, English and Turkish.

Ticket classification accuracy: THX-01 98.4%
Average accuracy over the four sets. THX-01 answers in about 10 ms; the LLMs take 0.15 to 2 seconds.
ModelCleanCorruptedMessyIndependentAvgECELatency
THX-0199.297.798.897.998.40.003~10 ms
Claude Sonnet 5.5 †98.598.098.599.098.5–1.5 s
Wahoo 1.599.896.398.097.297.8–145 ms
GPT-6-Luna98.697.496.798.297.7–1.9 s
TypeSafe Jev 1.1399.295.096.299.097.40.007331 ms
Kev-4B96.188.490.895.892.80.202830 ms

† Stratified subset of 200 tickets per set. ECE on the independent set; LLMs return no probabilities.

Extraction and citation results
Extraction and citation on held-out multilingual documents: number lookup 93.4%, range-bucket emulation 95.1%, excerpt F1 84.1, chunk emulation F1 83.8, citation 94.0%.
Reliability diagrams
Calibration: when THX-01 reports 90%, it is right about 90% of the time.
16 / Languages

Built for how the region writes.

THX-01 supports more than 100 languages. Post-training covers Azerbaijani, English, Russian, Turkish, German, French, Spanish, Arabic, Hindi, Chinese, Persian, Georgian, Japanese, Korean, Ukrainian, Kazakh, Uzbek and Italian, with Azerbaijani the largest. It is trained on text as people actually type it: Azerbaijani without its letters (e for ə, s for ş, c for ç), Russian in Latin transliteration, voice transcripts and messages that mix Azerbaijani, Russian and English.