# Create Consents
source: https://developer.mastercard.com/consent-management/documentation/tutorials/card-consents-tutorial/create-consents/index.md

The source code for the tutorial is available under [Reference App](https://developer.mastercard.com/consent-management/documentation/reference-app/index.md). Run the tutorial as follows:
* Java
* Python

```java
mvn spring-boot:run
```

```bash
FLASK_APP=main python3 -m flask run
```

When the tutorial app starts, it serves a webpage at `localhost:8081`. Navigate to "Card Consent Management APIs" you will see the form with an option to prefill fields to run specific test case. Select the first test case to go through successful flow.

<br />

When the Create Consent button is pressed it calls the tutorial `/create-consents` endpoint:
* Java
* Python

```java
// ConsentController.java

/**
   * Call Consent Management API to create the consents.
   *
   * @param cardDetails
   * @param model
   * @return String
   */
  @PostMapping("/create-consents")
  public String postConsents(CardDetails cardDetails, Model model) {

    ConsentsCreate request = new ConsentsCreate();
    request.setCardDetails(cardDetails);
    ConsentCreate consent = new ConsentCreate();
    consent.setName("notification");
    request.setConsents(Collections.singletonList(consent));

    try {

      Consents response = apiService.getApiClient().createConsents(request);
      log.info("Card reference: " + response.getCardReference());

      this.cardRef = response.getCardReference();
      String authType = response.getAuth().getType();

      StartAuthReq authReq = new StartAuthReq();
      authReq.setAuth(new Auth());

      if ("THREEDS" .equals(authType)) {
        // For 3DS we need to do fingerprinting in browser before we can start authentication
        Map<String, Object> params = response.getAuth().getParams();
        model.addAttribute("params", params);
        return "fingerprint";
      }

    } catch (ApiException e) {
      model.addAttribute(ERROR_MSG, e.getResponseBody());
    } catch (Exception e) {
      model.addAttribute(ERROR_MSG, e.getMessage());
    }

    return ERROR_TEMPLATE;
  }
```

```python
@app.route("/create-consents", methods=['GET', 'POST'])
def create_consents():
    """ handle create consent form """

    if request.method == 'POST':

        session["test_card_details"] = {
            "cardholderName": request.form["cardholderName"],
            "pan": request.form["pan"],
            "expiryMonth": request.form["expiryMonth"],
            "expiryYear": request.form["expiryYear"],
            "cvc": request.form["cvc"],
        }

        try:
            resp = api_create_consent(session["test_card_details"])

            session["card_ref"] = resp["cardReference"]
            session["auth_type"] = resp["auth"]["type"]
            session["auth_status"] = resp["auth"]["status"]

            if session["auth_type"] == 'THREEDS':
                # For 3DS we need to do fingerprinting in browser before we can start authentication
                params = resp["auth"]["params"]

                return render_template('fingerprint.html', **params)

            if session["auth_status"] == 'AUTHENTICATED':  # success ASI, 3ds not supported
                return redirect(url_for('consents_info'))

        except:
            error_msg = resp
            return render_template('error.html', error_msg=error_msg)

    is_prod = configs.get("isProd").data in ["true", "True", "1"]
    return render_template('create-consent.html', is_prod=is_prod)

```

We have a test_card_details object and we set the card details provided from the form.

The `POST /create-consents` calls `createConsents` function from ApiService to send a `POST /consents` to the
Consent Management API to create the consents.

When this API is called, the consent is created, and the Consent Management system
determines if authentication is required.

The response contains the cardReference, which may be new if the card is being seen for
the first time. Otherwise, it may be an existing cardReference if consents have already been granted on this card.
The new consents will have status="REQAUTH" if authentication is required.

If authentication is required, the response contains any parameters required to do
the authentication. For example:

```json
{ 
    "auth": {
        "status": "READY_TO_START",
        "type": "THREEDS",
        "params": { }
    }
}
```

Based on the auth.type return, an HTML page will be displayed to gather browser fingerprint data needed by 3DS. The Consent Management `/start-authentication` API
with that data.

The next steps for authentication are described in the following section.
