HLA-Verify API

Base URL https://api.hlaverify.com (also https://hlaverify.com/v1/…). Pinned to IPD-IMGT/HLA 3.65.0 — 46,652 named alleles. Every response carries the release and the attribution line. No LLM anywhere; nothing you send is stored.

Authentication and limits

Without a key the API is open for evaluation at 60 requests per minute per IP. Labs, LIMS vendors and agent platforms get a key (header X-API-Key: … or Authorization: Bearer …) with no per-minute cap, per-key usage reporting, and a release-change notice before each quarterly IPD-IMGT/HLA update. Keys: hello@hlaverify.com.

Endpoints

POST/v1/verify — check every allele-shaped token in free text

Send a typing report, an EHR fragment, or a model's answer. Every token that looks like an allele is classified: valid, group (G/P), deleted (with successor), fabricated_group, or hallucinated. clean is true only when nothing is fabricated, deleted, or a made-up group.

curl -s https://api.hlaverify.com/v1/verify -H 'content-type: application/json' \
  -d '{"text": "Patient typing: A*0101, B*15:504:01, DRB1*14:06. Assistant suggested DQB1*05:03:26:99 (DQB1*05:03:01G)."}'
{"release":"3.65.0","clean":false,
 "counts":{"valid":2,"deleted":1,"group":1,"fabricated_group":0,"hallucinated":1},
 "tokens":[{"token":"A*0101","status":"deleted","successor":"A*01:01:01:01","current_2field":"A*01:01",
            "g_group":"AMBIGUOUS","flags":["deprecated_name"],"note":"was assigned once, no longer current — see successor"},
           {"token":"DQB1*05:03:26:99","status":"hallucinated","note":"no such name in any release back to 1.05.0 — fabricated"}, …],
 "attribution":"Computed from IPD-IMGT/HLA (Barker DJ et al., Nucleic Acids Res 2025), …"}

POST/v1/normalize — bring reported typings to the current release

Any era: colon-less 1990s strings (A*0101, Cw*0702), deleted names, lower-resolution prefixes. Returns the current name, the comparable 2-field name (keeping an expression suffix only when every full-resolution allele shares it), the G group (NONE / AMBIGUOUS), and flags such as deprecated_name, null_allele, nonexistent_allele.

curl -s https://api.hlaverify.com/v1/normalize -H 'content-type: application/json' \
  -d '{"typings": ["A*0101", "A*01:34N", "DRB1*1406", "A*24:09N", "B*9999"]}'

GET/v1/allele/{name} — the facts for one name

assigned (G/P group, first release, confirmed status, WMDA serology, null flag), valid_prefix (member count and sample), or deleted (successor). 404 for anything not in the release.

curl -s 'https://api.hlaverify.com/v1/allele/A*24:09N'

POST/v1/match — donor–recipient match verdict

Two reported alleles per locus, any nomenclature era. Frameworks 6/6, 8/8, 10/10, 12/12, antigen. Counts per chromosome, not per locus; GvH and HvG mismatches reported separately; a locus whose typing is too coarse to call is potential and excluded from the denominator with resolution_insufficient — a confident count over unresolvable typing is itself the error. Null alleles hiding inside serologic matches (the A*24:09N trap) raise null_allele_mismatch. Rules R1–R6 are published in rules.py for lab audit.

curl -s https://api.hlaverify.com/v1/match -H 'content-type: application/json' -d '{
  "framework": "8/8",
  "recipient": {"A": ["A*02:01", "A*24:02"], "B": ["B*07:02", "B*44:02"], "C": ["C*07:02", "C*05:01"], "DRB1": ["DRB1*15:01", "DRB1*04:01"]},
  "donor":     {"A": ["A*02:01", "A*24:09N"], "B": ["B*07:02", "B*44:02"], "C": ["C*07:02", "C*05:01"], "DRB1": ["DRB1*15:01", "DRB1*04:01"]}}'
{"release":"3.65.0","framework":"8/8","count":"7/8",
 "verdicts":{"A":"mismatch","B":"match","C":"match","DRB1":"match"},
 "hvg_mismatches":1,"gvh_mismatches":1,"flags":["null_allele"], "attribution":"…"}

GET/healthz

{"ok":true,"release":"3.65.0","alleles":46652,"uptime_s":…}

Integrating into a pipeline

WhereCallGate on
Typing report ingest (LIMS, HistoTrac/TIMS exports, PDF-to-text)/v1/normalize per reported allelenonexistent_allele → reject; deprecated_name → rewrite to current_name and log
Any LLM or agent output that mentions HLA/v1/verify on the textclean == false → block or annotate before display
Search / match reports/v1/match per pairCompare with the lab's count; any potential or null_allele* flag routes to human review
Registry / data-warehouse QC/v1/normalize in batches of ≤5,000Diff reported vs current_name per release

Python (no HTTP): pip install "verifiable-science-envs @ git+https://github.com/jasonbrelsford/verifiable-science-envs", then from sci_envs.families.nomenclature.normalize import normalize and from sci_envs.families.matching.rules import score — the same engine that computed these tables. Agents: MCP server python -m sci_envs.mcp_server with tools verify_text, normalize_allele, match_score; see llms.txt.

Release pinning

This deployment is pinned to 3.65.0; the tables were exported 2026-09-10T19:34:01Z from the release's own files (Allelelist, Deleted_alleles, Allelelist_history, hla_nom_g/p, rel_dna_ser). IPD-IMGT/HLA publishes quarterly; keyed customers receive a diff of changed verdicts before the pin moves, and an older release can be kept for a customer on request.

Errors

Errors are JSON {"detail": "…"}: 400 malformed JSON, 401 bad key, 404 unknown name or route, 415 wrong content type, 422 invalid input, 429 anonymous rate limit, 500 (nothing stored).

Terms

HLA-Verify is a research-and-evaluation tool and not a medical device; output supports and does not replace clinical judgement. Service code: PolyForm Noncommercial 1.0.0 — commercial use requires a licence from Brelsford Software LLC (hello@hlaverify.com). Reference data: IPD-IMGT/HLA (Barker DJ et al., Nucleic Acids Research 2025), CC-BY-ND, fetched from the official source and never redistributed in bulk. Requests are processed in memory and discarded; metering records counts per key, never content.