Privacy
What we hold. Which is very little.
This is a plain-language summary of what the service does with data, written by the person who operates it, checked against the code that runs. It is not legal advice, and it is not a contract. Where this page and the code disagree, the code is the bug and we will fix it.
Data controller: Brelsford Software LLC, the company behind HLA-Verify. Questions, corrections and deletion requests: hello@hlaverify.com.
Do not send patient identifiers
Send allele names and typing strings. Do not send patient records, names, dates of birth, medical record numbers or any other identifier. The service does not need them to answer, does not look for them, and does not want them.
The /v1/verify endpoint and the verify_text tool accept up to 200,000 characters of free text because typing reports and model output arrive as prose. That limit is a size cap, not an invitation to paste a chart. Strip the identifiers before you call, and send the part with the alleles in it.
Said honestly: HLA types are themselves genetic data, and a rare type in a small population can be quasi-identifying even with no name attached. Nothing you send is stored (see below), but if your policy says such data may not leave your perimeter, self-host rather than call the hosted API. The in-browser demo makes no network call at all.
What happens to a request
- Request bodies are processed in memory and discarded when the response is written. There is no content log, no queue, no copy kept for debugging, and no training use: the product has no model to train.
- Metering records counts, never content. Each call writes one row: the key label, the endpoint, the release the verdict was computed against, the HTTP status, whether the call was keyed or anonymous, the tier, how many units were computed and how long it took — and a count, per kind, of inputs the service could not fully check: how many were NMDP multiple allele codes, serologic antigens, names that would have resolved after trivial cleanup, names at a locus outside IPD-IMGT/HLA, a match framework or tool that does not exist, and so on. The row names the kind, never the input: at most it carries a gene symbol, a framework label or a tool name taken from a closed list. No allele, no text, no email address is in that row. Those counts are how we decide what to build next.
- Burst limiting uses your IP address in memory only. Anonymous calls are held to 60 a minute per IP. The address is the limiter's key for the length of that request; it is not written to a record we keep.
- The daily quota counts without storing your address. Every tier has a quota of API calls per UTC day, 100 for anonymous callers. The counter for an anonymous caller is named by a SHA-256 digest of the UTC date and the IP address, never by the address itself, so the name changes at midnight and the previous day's counter can never be addressed again. All it holds is a date and a number. There is no row anywhere that says an IP address made a call. A keyed caller is counted the same way against a digest of the key, so two keys never share a counter.
- Counters delete themselves. A day's anonymous counter is swept away a day and a half after the day it counted ends, and it holds nothing but the date and the count while it exists.
- Your quota is on the response, not in a report. Every billable response carries the tier, the daily limit, what is left and when it resets, so you can see the ceiling without us keeping a usage history you have to ask for.
- Nothing is sent onward. A verification request makes no outbound call on your behalf, to an analytics vendor or to anyone else.
Cloudflare runs the network the API sits on and is a processor for it. Like any host, it sees the connection, including the IP address it arrives from, and applies its own network logging and abuse protection. We do not add a content log on top of that, and the request body is not part of what it retains for us.
The beta list
The forms on the site are the only places the service asks you for anything about yourself. Here is the whole record each one writes. Support reports have their own section.
The beta list, from the form on /beta
| Field | Where it comes from |
|---|---|
email | What you typed. Required, because it is the thing we mail. |
org | What you typed, if anything. Optional. |
use_case | What you typed, if anything. Optional. It decides whether a hand-issued beta key makes sense. |
source | Which form sent it, so signups from the site can be told from signups made by hand. |
ts | The time the record was written. |
country | The two-letter country Cloudflare reports for the connection. Not the IP address: the IP is deliberately not part of the record. |
- It is used for one thing. Telling you when anything about early access changes, and sending a key if you asked for one. No newsletter, no sequence, no drip.
- It is not sold or shared. Not to advertisers, not to partners, not to anyone.
- Signing up is optional. Anonymous access is open at 100 calls a day per IP, no key and no signup at all.
- Deletion on request. Reply to any mail from us, or write to hello@hlaverify.com, and the record is deleted. You do not have to explain why, and the answer will say when it was done.
Free keys, from the form on /research
Getting a free key writes two records: the key record (see API keys), which holds the email address the key was issued to, and the request record below. The email address is stored with the key and used for service notices only: a release change, a change to the free tier, or a problem with your key. It is not a newsletter and it is never sold or shared. A free key is issued at once, by the API itself, with no review and no outside processor. Only a request for the Lab tier is reviewed, and that review uses two outside processors, named below.
| Field | Where it comes from |
|---|---|
email | What you typed. Required: it is stored with the key and used for service notices only. For a Lab-tier request it is also where the answer goes, and the organisation is verified against it. |
institution | What you typed, if anything. Optional for a free key; required for a Lab-tier request, because verifying the organisation is most of that decision. |
use_case | What you typed, if anything. Optional for a free key; required for a Lab-tier request, and the other half of that decision. |
expected_volume | What you typed, if anything. Optional. It sizes the key. |
source | Which form sent it, so applications from the site can be told from ones made by hand. |
ts | The time the record was written. |
status, key_ref | issued for a free key, with the key's first eight characters so a lost or misused key can be found; never the whole key. A Lab-tier request is written as pending and changes when it is decided. |
country | The two-letter country Cloudflare reports for the connection. Not the IP address: the IP is deliberately not part of the record. |
- It is used for service notices only. For a Lab-tier request, also for deciding it and emailing you the Lab key if the answer is yes. It does not put you on the beta list and it starts no sequence.
- Abuse limits, without keeping your IP. At most three new keys a day come from one connection. That is counted under a salted digest of the date and the IP address, which changes at midnight; the IP address itself is never stored.
- How a Lab-tier request is decided. An automated job reads the request. An address at an academic domain (
.edu,.ac.ukand the like) is approved from the domain alone. A request from a personal webmail address (Gmail, Outlook, Yahoo and the like) is held for a person to decide by hand. Any other request is checked by Claude, an AI model from Anthropic, using public web search and fetch to confirm the organisation exists and matches the email domain. The owner is notified of every decision and reviews each one. - Anthropic is a processor for that check. For a request that is neither academic nor webmail, Anthropic's Claude receives the institution name, the email domain, the use case and the expected volume. It does not receive the full email address. Academic and webmail requests are not sent to Anthropic.
- Google sends the key. An approved key is emailed to you from our Gmail account, so Google processes that message, your address and the key in it, as it does for any email we send.
- It is not sold or shared beyond that. Same as the beta list: not to advertisers, not to partners, not to anyone other than the processors named here.
- Deletion on request. Write to hello@hlaverify.com and the record is deleted, decided or not. Deleting the email address from a key record switches that key off, because the address is how a key is traced.
Support reports
A report from /support, POST /v1/report or the MCP tool is the one place the service keeps what you typed, because a person has to read it to fix the answer. It is stored apart from API keys and account records.
| Field | Where it comes from |
|---|---|
kind, endpoint | What you chose and typed. |
input, received, expected, details | What you typed: the request you sent, what came back, what you expected, anything else. Do not include patient identifiers of any kind, names included. Obvious ones (record-number and date-of-birth labels, Social Security numbers, US-format dates) are refused before anything is stored; a name cannot be detected automatically, so leave names out. |
email | What you typed, if anything. Optional. Used only to reply about this report. |
request_id, source | Optional; which call or form it came from. |
release, ts, country | The release that was live, the time, and the two-letter country Cloudflare reports. Not the IP address. A daily count of reports per connection is kept under a salted digest of the date and the address, never the address itself, and expires after two days. |
status, note, fixed_in | Written by us as the report is handled. These, and nothing else, are what /support?id= shows: never your input or your email. |
- Who reads it. Every report is rerun against the reference data by our tooling, and a person confirms any error before it is published. It is copied into a private issue tracker for that work. A confirmed bug becomes a public engine issue with only the HLA names involved, never your text or your address.
- Deletion on request. Write to hello@hlaverify.com with the report id and the record is deleted.
API keys, payment and sign-in
- A key record holds a label, a tier, a status and the email the key was issued to. That is what lets us mail you about a release change and stop a key that was leaked. It holds no request history.
- Payment, if it is ever taken, is handled by Stripe. Keys are free and nothing is charged. If self-serve checkout opens, card details go to Stripe and never reach our servers. What comes back to us is the email address and name Stripe reports for the purchase, plus the subscription or payment reference needed to keep the key in step with the subscription.
- OAuth sign-in for the MCP endpoint carries a key, not an account. There are no user accounts. The consent screen asks for an existing API key; the code and tokens issued from it carry that key encrypted, and the MCP endpoint decrypts it and applies exactly that key's tier and limit. The client never sees the key, we store no profile, and revoking the key stops every token made from it on the next request. The only things written down are single-use markers so a code cannot be replayed, and a revocation record so a stolen refresh token can be cut off.
The website
- Cloudflare Web Analytics, and nothing else. It is a measurement script served from
static.cloudflareinsights.comthat reports the page URL, the referring URL, page-load timings, and the browser, device type and country derived from the request. It sets no cookie, assigns no persistent visitor id, and follows nobody across other sites. There is no advertising pixel and no other analytics vendor on this site. - No cookies beyond the ones a flow needs. The site sets no tracking cookie. The only cookie the service sets at all is a short-lived one during OAuth sign-in, which exists to stop a forged consent submission and is gone when the flow ends.
- The demo stays in your browser. /demo runs the engine client-side. What you type there is not sent anywhere, including to us.
- Forms. There are two, both described above: the beta signup on /beta and the free-key form on /research. Nothing else on the site collects anything you type.
How long things are kept
| What | How long |
|---|---|
| Request bodies and responses | Not stored. The lifetime of the request. |
| Metering rows (counts, no content) | Kept while the account is active, for rate limits, invoices and capacity planning. |
| Daily quota counter (a date and a count) | An anonymous counter is named by a digest of the date and the IP and is deleted a day and a half after its day ends. A key's counter is one record that rolls over each day. |
| Beta list record | Until early access has ended and you have been told, or until you ask for it to be deleted, whichever comes first. |
| Support report | Until it is resolved and a year has passed, so a repeat of the same problem can be traced, or until you ask for it to be deleted. |
| Free-key record | While the key exists, so a key can be traced back to the address it was issued to, or until you ask for it to be deleted. |
| New-key counter (a date and a count, under a digest of the date and the IP) | Deleted a day and a half after its day ends. |
| API key record | While the key exists, plus the period the payment processor requires for billing records. |
| OAuth markers and cookie | Minutes to days. They expire on their own. |
Asking us to do something about it
One address handles all of it: hello@hlaverify.com. It reaches the person who built the service.
- See what we hold about you. Ask, and you get the record, which for most people is one beta-list row or one research-access application.
- Have it deleted or corrected. Ask, and it is done, normally the same day.
- Ask where it sits. The service runs on Cloudflare's network. What it stores sits in Cloudflare KV (key records, the beta list and free-key requests, and support reports in a separate store), Analytics Engine (metering counts) and Durable Objects (the daily quota counters described above); free-key requests that are neither academic nor webmail are checked by Anthropic's Claude, approved keys are emailed through Google's Gmail, and payments, if they open, run through Stripe. If your review needs specifics beyond this page, ask and you get specifics.
If this page changes in a way that matters, the change is described here rather than slipped in. Last reviewed against the running code in September 2026.