Authenticating with the API

You're building a genetic app. How do you get a user's data? With OAuth 2.0,

  1. Ask the user's permission for their data. If they accept, you get an authorization code.
  2. Exchange the code for an authorization token.
  3. Using the token, call our API endpoints for data.

1. Ask the user's permission, get an authorization code.

In your app, send the user to https://api.23andme.com/authorize/ with these parameters:

redirect_uri The redirect uri from your dashboard, e.g. https://exampleapp.com/receive_code/.
response_type code
client_id The client id from your dashboard.
scope A space-delimited list of scopes you're asking the user to allow you to access. See scopes for a list of them.
state An optional value of your choosing, to maintain state between the request and the callback.
select_profile=True Optional. 23andMe user accounts may have multiple associated profiles. If you'd like your app to deal with only a single profile's resources, set this parameter to true, and the grant screen will require the user to select a single profile for which to authorize your app. Otherwise, your token will be scoped for all profiles for the user's account.

We recommend you use a branded button so users recognize the login, but you may also use a GET link, or even a form that POSTs to /authorize/ (helpful for scopes with thousands of rsids that won't fit in a URL string).

<a href="https://api.23andme.com/authorize/?redirect_uri=https://exampleapp.com/receive_code/&response_type=code&client_id=8c5bc3cd41932f405c80612248b7ae43&scope=basic rs123">Connect with 23andMe</a>

When the user clicks the button, they sign in with 23andMe and see a screen asking them to give you access to their data. If they accept, their browser will redirect to your redirect_uri with parameter code=zzz. That's your authorization code, and it only lasts for 10 minutes.

2. Exchange the auth code for a token.

Send a POST /token/ request with these parameters (client_id and client_secret are on your dashboard):

    curl https://api.23andme.com/token/
         -d client_id=xxx \
         -d client_secret=yyy \
         -d grant_type=authorization_code \
         -d code=zzz \
         -d "redirect_uri=https://localhost:5000/receive_code/"
         -d "scope=basic%20rs3094315"

If successful, you'll get a 200 JSON response like this:

    {"access_token":"89822b93d2",
     "token_type":"bearer",
     "expires_in": 86400,
     "refresh_token":"33c53cd7bb",
     "scope":"rs3094315 basic"}

Otherwise, you'll get a non-200 error response. Here's a full list of errors.

    {"error_description":"No such code: 1928789",
     "error":"invalid_request"}

3. Call the API endpoints.

Now that you've got a token, call the endpoints you want data from. See the API reference for endpoints and explanations.


Refresh tokens

Access tokens expire after 1 day. If you need to access a user's data past that, you can request another token using the last refresh_token that you were issued. Using the refresh token means you don't have to send the user through the "Accept" screen all over again. Requesting a new token set will invalidate your old refresh_token. Be sure to specify the full scope when requesting a new access token.

    curl https://api.23andme.com/token/ \
         -d client_id=xxx \
         -d client_secret=yyy \
         -d grant_type=refresh_token \
         -d refresh_token=33c53cd7bb \
         -d "redirect_uri=https://localhost:5000/receive_code/" \
         -d "scope=basic%20rs3094315"

You will get the same JSON responses as when you got the original token.

Scopes

With OAuth 2.0, you include a space-delimited list of scopes in your requests to access certain user data. The user must consent to each scope. For example, if you wanted profile markers rs123 and rs456, your scope would be basic names email rs123 rs456; you would need basic, names and email to get the user's profile and associated id, and rs123 and rs456 to get those profile markers for the profile.

The privacy of our users and the protection of their data are among 23andMe's highest priorities. With that in mind, be sure to request only the scopes that your app needs. For example, if you know which SNPs you'll be using, please request the scopes for only those SNPs and not the entire genome.

If you are using the deprecated API endpoints, check here for a list of supported scopes.

scope what it grants access to, and what the user sees when you ask for it
basic Read a profile's service type (ancestry or health and ancestry)
names Read the full name on your account and profile
email Read your account's email address
report:all Read all of a profile's reports
report:genetic_weight Read a profile's Genetic Weight report
report:wellness.alcohol_flush Read a profile's Alcohol Flush Reaction report
report:wellness.caffeine_consumption Read a profile's Caffeine Consumption report
report:wellness.deep_sleep Read a profile's Deep Sleep report
report:wellness.lactose Read a profile's Lactose Intolerance report
report:wellness.muscle_composition Read a profile's Muscle Composition report
report:wellness.saturated_fat_and_weight Read a profile's Saturated Fat and Weight report
report:wellness.sleep_movement Read a profile's Sleep Movement report
rsXX or iXX The genotype at rsXX or iXX for all profiles in the account. You can string these together to get access to multiple genes. This list of SNPs (31MB) shows which SNPs our customers are genotyped for; all of these SNPs are valid scopes.
accession:<accession_id> Read a profile's genotype across accession accession_id, unless you have not opted to know it
genomes Read a profile's entire genome, including all SNP locations except those the profile has not opted into. You should only grant access to services you trust.
phenotypes:read:all Read all of a profile phenotypes. You should only grant access to services you trust.