The Short Answer
There is no 23andMe API you can sign up for in 2026. What still works is the raw data file the customer downloads, and every tool that reads 23andMe data today, from PLINK to bcftools to the Python package snps, starts from that file.
TL;DR:
- Don't build on
api.23andme.com: it no longer serves the genetic endpoints.- Ask the user for their raw data download (a
.zipwith agenome…txtinside).- Parse four columns: marker, chromosome, position, genotype. Positions are GRCh37, so remap before joining against GRCh38 data.
- Treat
--as "no call", and expect single-letter genotypes on X, Y and MT and marker IDs that start withi.
23andMe told developers in August 2018 that it was turning off third-party access to genetic data. Today the host redirects to the company's main site and the old documentation paths return 404, which you can check yourself:
# 302: the host redirects away
curl -sI https://api.23andme.com/ | head -1
# 404: the old API reference is gone
curl -s -o /dev/null -w "%{http_code}\n" \
https://api.23andme.com/docs/v1_reference/
What Happened to the 23andMe API
23andMe opened its API to developers in September 2012. It was an OAuth 2.0 API: an app asked the customer for permission, then read their data on their behalf. The v1 reference, by then already marked deprecated, listed endpoints such as /1/genotypes, /1/genomes, /1/haplogroups and /1/ancestry. The /genomes endpoint returned the customer's whole genotype as one packed string of roughly 2 MB. A later v3 reorganised this around /3/marker, /3/variant and /3/report.
On 23 August 2018 23andMe told developers it would disable that access within two weeks. From then on, third-party apps could no longer pull a customer's raw genotypes; research partnerships kept their own arrangements. An archived copy of the developer portal from January 2023 says access is granted only through a developer arrangement and points to a business-development address.
Two events since then make it unlikely to come back in its old form:
- The 2023 breach. Attackers used reused passwords to get into about 14,000 accounts and, through the DNA Relatives feature, reached data on about 6.9 million people. The UK Information Commissioner's Office later fined the company £2.31 million.
- The bankruptcy and sale. 23andMe filed for Chapter 11 in March 2025, and in July 2025 the company was sold to TTAM Research Institute, a nonprofit led by co-founder Anne Wojcicki. We found no public developer programme under the new owner.
The open-data side shrank too. openSNP, where people published their own 23andMe files for researchers, shut down on 30 April 2025 and deleted its data, citing the bankruptcy among its reasons.
So if a tutorial, a GitHub repo or an LLM tells you to register an app at api.23andme.com, it is describing something that hasn't existed for years.
The Replacement: the Raw Data File
The customer downloads their own data and hands it to your software. 23andMe's help page describes the route: in the account, Browse Raw Genotyping Data, then Download, with a date-of-birth confirmation. Preparing the file "usually takes about one week but can sometimes take up to thirty days". What arrives is a .zip holding a text file whose name starts with genome.
This changes your product more than your code. With the API, consent was an OAuth screen and the data arrived in seconds. With the file, the user has to request it, wait up to a month, and then upload it to you. Build the wait into the onboarding (the steps are in our guide to 23andMe raw data), and tell the user exactly which file to send you, because people often upload the .zip, a screenshot or a PDF report instead.
It also changes your responsibility. The file is the user's whole genotype, and once they upload it you are the one holding it. Keep only what your feature needs, and delete the upload once you've parsed it.
What's in the File
Each data line has four fields: a marker name, a chromosome, a position and a genotype. Lines starting with # are a comment header to skip. Here is a synthetic example we made with the same shape (the parser below splits on any whitespace, so it doesn't depend on the exact separator):
# This data file generated by 23andMe at: Sun Oct 11 12:00:00 2026
#
# rsid chromosome position genotype
rs4244285 10 96541616 AG
rs1801133 1 11856378 AG
rs429358 19 45411941 TT
rs7412 19 45412079 --
i5000100 X 2700157 A
i5000200 Y 2655180 G
i5000300 MT 16519 C
The i… rows are made up for illustration; the rs rows use real GRCh37 positions. Four details in that file break naive parsers, all of them documented by 23andMe itself:
- Positions are GRCh37 on the plus strand. 23andMe's reference genome page says so. Most current databases and pipelines use GRCh38, where the same variant sits at a different coordinate. rs4244285 is at
10:96541616in GRCh37 and10:94781859in GRCh38. If you join on chromosome and position without remapping, you'll match the wrong variant without any error. - Not every marker has an rsID. Markers without a clear rsID get an internal ID that starts with
i. A filter likestartswith("rs")silently throws them away. --means no call. 23andMe uses it when it couldn't determine the genotype, and also for some insertion and deletion markers. It is not a genotype, and it isn't the reference allele either.- Some genotypes have one letter. Mitochondrial calls, and most X and Y calls in men, are reported with a single allele. Code that assumes every genotype has two characters will either crash or invent a second allele.
Which markers a file contains depends on the chip the customer was genotyped on. 23andMe's own chip documentation lists four generations, from about 560,000 variants on v2 to the current v5, built on Illumina's Global Screening Array with about 654,000 preselected variants plus about 50,000 custom ones. Two customers' files won't contain the same set of markers, so check that a marker is present before you report on it.
Parsing It in Plain Python
This reader has no dependencies and refuses to guess. It keeps the i IDs, stores no-calls as an empty string, keeps haploid calls as they are, and fails loudly on anything that isn't four columns or a known chromosome, which is how you find out a user uploaded the wrong file:
from dataclasses import dataclass
from pathlib import Path
VALID_CHROMS = {str(n) for n in range(1, 23)} | {"X", "Y", "MT"}
@dataclass(frozen=True)
class Call:
marker: str # rsID, or a 23andMe internal ID starting with "i"
chrom: str
pos: int # GRCh37 coordinate
genotype: str # "AG", "T" (haploid) or "" (no-call)
def read_23andme(path: str | Path) -> list[Call]:
calls = []
with open(path, encoding="utf-8") as fh:
for n, line in enumerate(fh, 1):
if line.startswith("#") or not line.strip():
continue
fields = line.split()
if len(fields) != 4:
raise ValueError(f"line {n}: expected 4 columns, got {len(fields)}")
marker, chrom, pos, gt = fields
if chrom not in VALID_CHROMS:
raise ValueError(f"line {n}: unknown chromosome {chrom!r}")
calls.append(Call(marker, chrom, int(pos), "" if gt == "--" else gt))
if not calls:
raise ValueError("no genotype rows: is this really a 23andMe file?")
return calls
On the synthetic file above it returns seven calls. Four are rsIDs, one of them a no-call (rs7412); the other three are the i rows, which are also the three single-letter calls. On the CYP2C19 row it gives Call(marker='rs4244285', chrom='10', pos=96541616, genotype='AG').
If you take uploads, add two more checks before trusting the result: unzip the .zip yourself rather than asking the user to, and look for 23andMe's own first comment line, since an AncestryDNA or MyHeritage file can also have four or five columns.
Remapping to GRCh38 With snps
For anything beyond reading the file, the open-source snps package (version 2.12.1, actively maintained) already handles the format. It recognises 23andMe files, detects the build, and remaps coordinates using Ensembl's assembly mappings:
from snps import SNPs
s = SNPs("genome_synthetic.txt")
print(s.source, s.build, s.count) # 23andMe 37 7
s.remap(38) # downloads Ensembl mapping data
print(s.snps.loc["rs4244285"].to_dict())
# {'chrom': '10', 'pos': 94781859, 'genotype': 'AG'}
We ran this on 11 October 2026, and the GRCh38 position it returns matches Ensembl's record for rs4244285. The no-call on rs7412 comes back as NaN, so filter it out before you count genotypes. remap needs network access the first time it runs. If your machine sits behind a proxy that rewrites TLS certificates, point SSL_CERT_FILE at a certificate bundle such as certifi's.
snps can also write a VCF, and so can bcftools, whose manual uses a 23andMe file as the example for convert --tsv2vcf. Both need a GRCh37 reference to fill in reference alleles, and neither turns the file into an interpretation. A VCF of 650,000 genotypes still says nothing about what a single one of them means.
What the File Doesn't Give You
The old API returned some interpretation alongside the genotypes, such as haplogroups and ancestry composition. The raw file contains only the genotypes, so everything else is now your job.
The file says AG, but whether A is the allele that matters, and on which strand the literature reports it, has to come from ClinVar, dbSNP or a curated source. The call itself is reliable for common variants and much less so for rare ones: a 2021 study in the BMJ compared SNP chip calls with sequencing in about 50,000 UK Biobank participants: for variants rarer than 0.001%, only 16% of the heterozygous calls from the chips were confirmed by sequencing. A rare, alarming call from a consumer chip needs a clinical test before anyone acts on it. And a marker that isn't on the chip is not a negative result.
If your code is an AI agent, this is also where it is most likely to go wrong: asked what rs4244285 AG means, a model will answer from memory. Giving it a lookup tool with cited sources is safer than trusting recall.
Where DeepDNA Fits
DeepDNA, which is not affiliated with 23andMe, runs free knowledge endpoints with no key. They cover 12 genes today, mostly pharmacogenes plus a few of the most-searched nutrition and risk genes. Each record cites its sources:
curl -s https://deepdna.ai/api/v1/variants/rs4244285
That returns the CYP2C19 *2 record: what the A allele does, a reading block with the reference and variant alleles on the plus strand of GRCh37 (the orientation of the file you just parsed), a short note on population frequency, and links to the CPIC and PharmVar pages it was written from. The same lookups are exposed as a remote MCP server at https://deepdna.ai/mcp, so an agent can call them as tools. The request carries an rsID or a gene name, never a genotype or a file.
Parsing files is a different matter. POST /dna/parse, an endpoint designed to take a raw file from 23andMe, AncestryDNA or MyHeritage and return normalised variants, is in private beta and not deployed: it doesn't answer today, with or without a key. Until it does, the reader above and snps are the honest answer. The API docs list what is live, and for a worked example that goes from a raw file to CPIC phenotypes, see CYP2C19 and SLCO1B1 from a raw DNA file in Python.
Frequently Asked Questions
Does 23andMe have an API?
Not one you can use. 23andMe turned off third-party access to genetic data in 2018, by 2023 access required a direct business arrangement, and in 2026 api.23andme.com redirects away from the old developer site. The supported way to get a customer's genotypes is the raw data file they download themselves.
When did the 23andMe API shut down?
23andMe told developers on 23 August 2018 that it would disable access within two weeks. The documentation paths that served the API reference now return 404.
What format is the 23andMe raw data file?
A text file with # comment lines, then four whitespace-separated columns per marker: rsID or internal i ID, chromosome, position and genotype. Positions are GRCh37 on the plus strand, -- means no call, and mitochondrial calls, plus most X and Y calls in men, have a single letter.
Is 23andMe raw data GRCh37 or GRCh38?
23andMe documents the raw data as GRCh37 on the plus strand. Its online Browse Raw Data view now also shows GRCh38 genotypes, so check the build of any file you receive. The snps package detects it for you and can remap to GRCh38.
Can I convert a 23andMe file to VCF?
Yes. Both snps and bcftools convert --tsv2vcf can do it, given a GRCh37 reference. A VCF makes the file readable by more tools but doesn't add any interpretation.
This article is for educational purposes only and does not constitute medical advice. Consumer genotyping arrays can miss or miscall variants, especially rare ones; any finding that could affect health decisions should be confirmed by a validated clinical test and discussed with a qualified clinician.
This article was created with AI assistance and reviewed by the DeepDNA editorial team.
DNA and bloodwork, as an API
DeepDNA is now an API for AI agents and health apps. The knowledge endpoints are live and free, no key. Parsing DNA files and lab reports, and crossing the two, is in private beta. Building something with genetic or lab data? Tell us what.
Read the API docs