> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Describes how to use the MFA API to challenge users who lose access to their device or account using recovery codes.

# Challenge with Recovery Codes

When [recovery codes are enabled](/docs/secure/multi-factor-authentication/configure-recovery-codes-for-mfa) for your tenant, Auth0 automatically generates them when a user enrolls with <Tooltip tip="Multi-factor authentication (MFA): User authentication process that uses a factor in addition to username and password such as a code via SMS." cta="View Glossary" href="/docs/glossary?term=multi-factor+authentication">multi-factor authentication</Tooltip> (MFA). The user should save the recovery code. This code can later be used if the user loses access to the device or account used for MFA.

When recovery codes are disabled the MFA API will not return a recovery code when you associate a user's first MFA factor and users cannot authenticate with a recovery code.

You can enable users to authenticate with a recovery code using the MFA API.

1. Prompt the user for their recovery code. That value should be entered in the application for the user to authenticate.

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     Auth0 does not generate recovery codes for DUO and for the legacy `google-authenticator` factor.
   </Callout>

2. Authenticate with recovery code. Call the OAuth Token endpoint with the recovery code to authenticate and generate a new recovery code. You need to specify the following parameters:

   <table class="table">
     <thead>
       <tr>
         <th>Parameter</th>
         <th>Value</th>
       </tr>
     </thead>

     <tbody>
       <tr>
         <td><code>grant\_type</code></td>
         <td><code>[http://auth0.com/oauth/grant-type/mfa-recovery-code](http://auth0.com/oauth/grant-type/mfa-recovery-code)</code></td>
       </tr>

       <tr>
         <td><code>recovery\_code</code></td>
         <td>The recovery code provided by the user.</td>
       </tr>
     </tbody>
   </table>

   <CodeGroup>
     ```bash cURL lines
     curl --request POST \
     --url 'https://{yourDomain}/oauth/token' \
     --header 'content-type: application/x-www-form-urlencoded' \
     --data grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code \
     --data 'client_id={yourClientId}' \
     --data 'client_secret={yourClientSecret}' \
     --data 'mfa_token={mfaToken}' \
     --data 'recovery_code={recoveryCode}'
     ```

     ```csharp C# lines
     var client = new RestClient("https://{yourDomain}/oauth/token");
     var request = new RestRequest(Method.POST);
     request.AddHeader("content-type", "application/x-www-form-urlencoded");
     request.AddParameter("application/x-www-form-urlencoded", "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D", ParameterType.RequestBody);
     IRestResponse response = client.Execute(request);
     ```

     ```go Go lines expandable
     package main

     import (
        "fmt"
        "strings"
        "net/http"
        "io/ioutil"
     )

     func main() {

        url := "https://{yourDomain}/oauth/token"

        payload := strings.NewReader("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D")

        req, _ := http.NewRequest("POST", url, payload)

        req.Header.Add("content-type", "application/x-www-form-urlencoded")

        res, _ := http.DefaultClient.Do(req)

        defer res.Body.Close()
        body, _ := ioutil.ReadAll(res.Body)

        fmt.Println(res)
        fmt.Println(string(body))

     }
     ```

     ```java Java lines
     HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/token")
     .header("content-type", "application/x-www-form-urlencoded")
     .body("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D")
     .asString();
     ```

     ```javascript Node.JS lines
     var axios = require("axios").default;

     var options = {
     method: 'POST',
     url: 'https://{yourDomain}/oauth/token',
     headers: {'content-type': 'application/x-www-form-urlencoded'},
     data: new URLSearchParams({
        grant_type: 'http://auth0.com/oauth/grant-type/mfa-recovery-code',
        client_id: '{yourClientId}',
        client_secret: '{yourClientSecret}',
        mfa_token: '{mfaToken}',
        recovery_code: '{recoveryCode}'
     })
     };

     axios.request(options).then(function (response) {
     console.log(response.data);
     }).catch(function (error) {
     console.error(error);
     });
     ```

     ```obj-c Obj-C lines expandable
     #import <Foundation/Foundation.h>

     NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded" };

     NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code" dataUsingEncoding:NSUTF8StringEncoding]];
     [postData appendData:[@"&client_id={yourClientId}" dataUsingEncoding:NSUTF8StringEncoding]];
     [postData appendData:[@"&client_secret={yourClientSecret}" dataUsingEncoding:NSUTF8StringEncoding]];
     [postData appendData:[@"&mfa_token={mfaToken}" dataUsingEncoding:NSUTF8StringEncoding]];
     [postData appendData:[@"&recovery_code={recoveryCode}" dataUsingEncoding:NSUTF8StringEncoding]];

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/oauth/token"]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                        timeoutInterval:10.0];
     [request setHTTPMethod:@"POST"];
     [request setAllHTTPHeaderFields:headers];
     [request setHTTPBody:postData];

     NSURLSession *session = [NSURLSession sharedSession];
     NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                     if (error) {
                                                        NSLog(@"%@", error);
                                                     } else {
                                                        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                        NSLog(@"%@", httpResponse);
                                                     }
                                               }];
     [dataTask resume];
     ```

     ```php PHP lines expandable
     $curl = curl_init();

     curl_setopt_array($curl, [
     CURLOPT_URL => "https://{yourDomain}/oauth/token",
     CURLOPT_RETURNTRANSFER => true,
     CURLOPT_ENCODING => "",
     CURLOPT_MAXREDIRS => 10,
     CURLOPT_TIMEOUT => 30,
     CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
     CURLOPT_CUSTOMREQUEST => "POST",
     CURLOPT_POSTFIELDS => "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D",
     CURLOPT_HTTPHEADER => [
        "content-type: application/x-www-form-urlencoded"
     ],
     ]);

     $response = curl_exec($curl);
     $err = curl_error($curl);

     curl_close($curl);

     if ($err) {
     echo "cURL Error #:" . $err;
     } else {
     echo $response;
     }
     ```

     ```python Python lines
     import http.client

     conn = http.client.HTTPSConnection("")

     payload = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D"

     headers = { 'content-type': "application/x-www-form-urlencoded" }

     conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

     res = conn.getresponse()
     data = res.read()

     print(data.decode("utf-8"))
     ```

     ```ruby Ruby lines
     require 'uri'
     require 'net/http'
     require 'openssl'

     url = URI("https://{yourDomain}/oauth/token")

     http = Net::HTTP.new(url.host, url.port)
     http.use_ssl = true
     http.verify_mode = OpenSSL::SSL::VERIFY_NONE

     request = Net::HTTP::Post.new(url)
     request["content-type"] = 'application/x-www-form-urlencoded'
     request.body = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D"

     response = http.request(request)
     puts response.read_body
     ```

     ```swift Swift lines expandable
     import Foundation

     let headers = ["content-type": "application/x-www-form-urlencoded"]

     let postData = NSMutableData(data: "grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code".data(using: String.Encoding.utf8)!)
     postData.append("&client_id={yourClientId}".data(using: String.Encoding.utf8)!)
     postData.append("&client_secret={yourClientSecret}".data(using: String.Encoding.utf8)!)
     postData.append("&mfa_token={mfaToken}".data(using: String.Encoding.utf8)!)
     postData.append("&recovery_code={recoveryCode}".data(using: String.Encoding.utf8)!)

     let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/oauth/token")! as URL,
                                            cachePolicy: .useProtocolCachePolicy,
                                         timeoutInterval: 10.0)
     request.httpMethod = "POST"
     request.allHTTPHeaderFields = headers
     request.httpBody = postData as Data

     let session = URLSession.shared
     let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
     if (error != nil) {
        print(error)
     } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse)
     }
     })

     dataTask.resume()
     ```
   </CodeGroup>

3. Prompt user to capture recovery code. If the call is successful, you'll get the authentication tokens and a new recovery code:

   ```json lines
   {
       "access_token": "O3...H4",
       "id_token": "eyJh...w",
       "scope": "openid profile",
       "expires_in": 86400,
       "recovery_code": "K6LGLV3RSH3VERMKET8L7QKU",
       "token_type": "Bearer"
   }
   ```

4. Notify the user that a new recovery code was generated and ask them to capture it.

## Learn more

* [Enroll and Challenge SMS and Voice Authenticators](/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-challenge-sms-voice-authenticators)
* [Enroll and Challenge Push Authenticators](/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-push-authenticators)
* [Enroll and Challenge OTP Authenticators](/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators)
* [Enroll and Challenge Email Authenticators](/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-email-authenticators)
* [Auth0 MFA API](/docs/secure/multi-factor-authentication/multi-factor-authentication-developer-resources/mfa-api)
* [Manage Authentication Factors with Authentication API](/docs/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api)
