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

# 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 theme={null}
     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 theme={null}
     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 theme={null}
     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 theme={null}
     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 theme={null}
     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 theme={null}
     #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 theme={null}
     $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 theme={null}
     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 theme={null}
     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 theme={null}
     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 theme={null}
   {
       "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)
