/*
 * The Plaid API
 * The Plaid REST API. Please see https://plaid.com/docs/api for more details.
 *
 * The version of the OpenAPI document: 2020-09-14_1.680.0
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */


package com.plaid.client.model;

import java.util.Objects;
import java.util.Arrays;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.plaid.client.model.ConsumerReportPermissiblePurpose;
import com.plaid.client.model.CountryCode;
import com.plaid.client.model.LinkTokenAccountFilters;
import com.plaid.client.model.LinkTokenCashflowReport;
import com.plaid.client.model.LinkTokenCreateCardSwitch;
import com.plaid.client.model.LinkTokenCreateHostedLink;
import com.plaid.client.model.LinkTokenCreateIdentity;
import com.plaid.client.model.LinkTokenCreateInstitutionData;
import com.plaid.client.model.LinkTokenCreateRequestAppearanceMode;
import com.plaid.client.model.LinkTokenCreateRequestAuth;
import com.plaid.client.model.LinkTokenCreateRequestBaseReport;
import com.plaid.client.model.LinkTokenCreateRequestCraOptions;
import com.plaid.client.model.LinkTokenCreateRequestCreditPartnerInsights;
import com.plaid.client.model.LinkTokenCreateRequestEmployment;
import com.plaid.client.model.LinkTokenCreateRequestIdentityVerification;
import com.plaid.client.model.LinkTokenCreateRequestIncomeVerification;
import com.plaid.client.model.LinkTokenCreateRequestPaymentConfiguration;
import com.plaid.client.model.LinkTokenCreateRequestPaymentInitiation;
import com.plaid.client.model.LinkTokenCreateRequestStatements;
import com.plaid.client.model.LinkTokenCreateRequestTransfer;
import com.plaid.client.model.LinkTokenCreateRequestUpdate;
import com.plaid.client.model.LinkTokenCreateRequestUser;
import com.plaid.client.model.LinkTokenEUConfig;
import com.plaid.client.model.LinkTokenInvestments;
import com.plaid.client.model.LinkTokenInvestmentsAuth;
import com.plaid.client.model.LinkTokenTransactions;
import com.plaid.client.model.Products;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * LinkTokenCreateRequest defines the request schema for &#x60;/link/token/create&#x60;
 */
@ApiModel(description = "LinkTokenCreateRequest defines the request schema for `/link/token/create`")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2025-12-11T18:58:39.328614Z[Etc/UTC]")
public class LinkTokenCreateRequest {
  public static final String SERIALIZED_NAME_CLIENT_ID = "client_id";
  @SerializedName(SERIALIZED_NAME_CLIENT_ID)
  private String clientId;

  public static final String SERIALIZED_NAME_SECRET = "secret";
  @SerializedName(SERIALIZED_NAME_SECRET)
  private String secret;

  public static final String SERIALIZED_NAME_CLIENT_NAME = "client_name";
  @SerializedName(SERIALIZED_NAME_CLIENT_NAME)
  private String clientName;

  public static final String SERIALIZED_NAME_LANGUAGE = "language";
  @SerializedName(SERIALIZED_NAME_LANGUAGE)
  private String language;

  public static final String SERIALIZED_NAME_COUNTRY_CODES = "country_codes";
  @SerializedName(SERIALIZED_NAME_COUNTRY_CODES)
  private List<CountryCode> countryCodes = new ArrayList<>();

  public static final String SERIALIZED_NAME_USER = "user";
  @SerializedName(SERIALIZED_NAME_USER)
  private LinkTokenCreateRequestUser user;

  public static final String SERIALIZED_NAME_USER_ID = "user_id";
  @SerializedName(SERIALIZED_NAME_USER_ID)
  private String userId;

  public static final String SERIALIZED_NAME_PRODUCTS = "products";
  @SerializedName(SERIALIZED_NAME_PRODUCTS)
  private List<Products> products = null;

  public static final String SERIALIZED_NAME_REQUIRED_IF_SUPPORTED_PRODUCTS = "required_if_supported_products";
  @SerializedName(SERIALIZED_NAME_REQUIRED_IF_SUPPORTED_PRODUCTS)
  private List<Products> requiredIfSupportedProducts = null;

  public static final String SERIALIZED_NAME_OPTIONAL_PRODUCTS = "optional_products";
  @SerializedName(SERIALIZED_NAME_OPTIONAL_PRODUCTS)
  private List<Products> optionalProducts = null;

  public static final String SERIALIZED_NAME_ADDITIONAL_CONSENTED_PRODUCTS = "additional_consented_products";
  @SerializedName(SERIALIZED_NAME_ADDITIONAL_CONSENTED_PRODUCTS)
  private List<Products> additionalConsentedProducts = null;

  public static final String SERIALIZED_NAME_WEBHOOK = "webhook";
  @SerializedName(SERIALIZED_NAME_WEBHOOK)
  private String webhook;

  public static final String SERIALIZED_NAME_ACCESS_TOKEN = "access_token";
  @SerializedName(SERIALIZED_NAME_ACCESS_TOKEN)
  private String accessToken;

  public static final String SERIALIZED_NAME_ACCESS_TOKENS = "access_tokens";
  @SerializedName(SERIALIZED_NAME_ACCESS_TOKENS)
  private List<String> accessTokens = null;

  public static final String SERIALIZED_NAME_LINK_CUSTOMIZATION_NAME = "link_customization_name";
  @SerializedName(SERIALIZED_NAME_LINK_CUSTOMIZATION_NAME)
  private String linkCustomizationName;

  public static final String SERIALIZED_NAME_APPEARANCE_MODE = "appearance_mode";
  @SerializedName(SERIALIZED_NAME_APPEARANCE_MODE)
  private LinkTokenCreateRequestAppearanceMode appearanceMode;

  public static final String SERIALIZED_NAME_REDIRECT_URI = "redirect_uri";
  @SerializedName(SERIALIZED_NAME_REDIRECT_URI)
  private String redirectUri;

  public static final String SERIALIZED_NAME_ANDROID_PACKAGE_NAME = "android_package_name";
  @SerializedName(SERIALIZED_NAME_ANDROID_PACKAGE_NAME)
  private String androidPackageName;

  public static final String SERIALIZED_NAME_INSTITUTION_DATA = "institution_data";
  @SerializedName(SERIALIZED_NAME_INSTITUTION_DATA)
  private LinkTokenCreateInstitutionData institutionData;

  public static final String SERIALIZED_NAME_CARD_SWITCH = "card_switch";
  @SerializedName(SERIALIZED_NAME_CARD_SWITCH)
  private LinkTokenCreateCardSwitch cardSwitch;

  public static final String SERIALIZED_NAME_ACCOUNT_FILTERS = "account_filters";
  @SerializedName(SERIALIZED_NAME_ACCOUNT_FILTERS)
  private LinkTokenAccountFilters accountFilters;

  public static final String SERIALIZED_NAME_EU_CONFIG = "eu_config";
  @SerializedName(SERIALIZED_NAME_EU_CONFIG)
  private LinkTokenEUConfig euConfig;

  public static final String SERIALIZED_NAME_INSTITUTION_ID = "institution_id";
  @SerializedName(SERIALIZED_NAME_INSTITUTION_ID)
  private String institutionId;

  public static final String SERIALIZED_NAME_PAYMENT_CONFIGURATION = "payment_configuration";
  @SerializedName(SERIALIZED_NAME_PAYMENT_CONFIGURATION)
  private LinkTokenCreateRequestPaymentConfiguration paymentConfiguration;

  public static final String SERIALIZED_NAME_PAYMENT_INITIATION = "payment_initiation";
  @SerializedName(SERIALIZED_NAME_PAYMENT_INITIATION)
  private LinkTokenCreateRequestPaymentInitiation paymentInitiation;

  public static final String SERIALIZED_NAME_EMPLOYMENT = "employment";
  @SerializedName(SERIALIZED_NAME_EMPLOYMENT)
  private LinkTokenCreateRequestEmployment employment;

  public static final String SERIALIZED_NAME_INCOME_VERIFICATION = "income_verification";
  @SerializedName(SERIALIZED_NAME_INCOME_VERIFICATION)
  private LinkTokenCreateRequestIncomeVerification incomeVerification;

  public static final String SERIALIZED_NAME_BASE_REPORT = "base_report";
  @SerializedName(SERIALIZED_NAME_BASE_REPORT)
  private LinkTokenCreateRequestBaseReport baseReport;

  public static final String SERIALIZED_NAME_CREDIT_PARTNER_INSIGHTS = "credit_partner_insights";
  @SerializedName(SERIALIZED_NAME_CREDIT_PARTNER_INSIGHTS)
  private LinkTokenCreateRequestCreditPartnerInsights creditPartnerInsights;

  public static final String SERIALIZED_NAME_CRA_OPTIONS = "cra_options";
  @SerializedName(SERIALIZED_NAME_CRA_OPTIONS)
  private LinkTokenCreateRequestCraOptions craOptions;

  public static final String SERIALIZED_NAME_CONSUMER_REPORT_PERMISSIBLE_PURPOSE = "consumer_report_permissible_purpose";
  @SerializedName(SERIALIZED_NAME_CONSUMER_REPORT_PERMISSIBLE_PURPOSE)
  private ConsumerReportPermissiblePurpose consumerReportPermissiblePurpose;

  public static final String SERIALIZED_NAME_AUTH = "auth";
  @SerializedName(SERIALIZED_NAME_AUTH)
  private LinkTokenCreateRequestAuth auth;

  public static final String SERIALIZED_NAME_TRANSFER = "transfer";
  @SerializedName(SERIALIZED_NAME_TRANSFER)
  private LinkTokenCreateRequestTransfer transfer;

  public static final String SERIALIZED_NAME_UPDATE = "update";
  @SerializedName(SERIALIZED_NAME_UPDATE)
  private LinkTokenCreateRequestUpdate update;

  public static final String SERIALIZED_NAME_IDENTITY_VERIFICATION = "identity_verification";
  @SerializedName(SERIALIZED_NAME_IDENTITY_VERIFICATION)
  private LinkTokenCreateRequestIdentityVerification identityVerification;

  public static final String SERIALIZED_NAME_STATEMENTS = "statements";
  @SerializedName(SERIALIZED_NAME_STATEMENTS)
  private LinkTokenCreateRequestStatements statements;

  public static final String SERIALIZED_NAME_THIRD_PARTY_USER_TOKEN = "third_party_user_token";
  @SerializedName(SERIALIZED_NAME_THIRD_PARTY_USER_TOKEN)
  private String thirdPartyUserToken;

  public static final String SERIALIZED_NAME_INVESTMENTS = "investments";
  @SerializedName(SERIALIZED_NAME_INVESTMENTS)
  private LinkTokenInvestments investments;

  public static final String SERIALIZED_NAME_INVESTMENTS_AUTH = "investments_auth";
  @SerializedName(SERIALIZED_NAME_INVESTMENTS_AUTH)
  private LinkTokenInvestmentsAuth investmentsAuth;

  public static final String SERIALIZED_NAME_HOSTED_LINK = "hosted_link";
  @SerializedName(SERIALIZED_NAME_HOSTED_LINK)
  private LinkTokenCreateHostedLink hostedLink;

  public static final String SERIALIZED_NAME_TRANSACTIONS = "transactions";
  @SerializedName(SERIALIZED_NAME_TRANSACTIONS)
  private LinkTokenTransactions transactions;

  public static final String SERIALIZED_NAME_CASHFLOW_REPORT = "cashflow_report";
  @SerializedName(SERIALIZED_NAME_CASHFLOW_REPORT)
  private LinkTokenCashflowReport cashflowReport;

  public static final String SERIALIZED_NAME_CRA_ENABLED = "cra_enabled";
  @SerializedName(SERIALIZED_NAME_CRA_ENABLED)
  private Boolean craEnabled;

  public static final String SERIALIZED_NAME_IDENTITY = "identity";
  @SerializedName(SERIALIZED_NAME_IDENTITY)
  private LinkTokenCreateIdentity identity;

  public static final String SERIALIZED_NAME_FINANCEKIT_SUPPORTED = "financekit_supported";
  @SerializedName(SERIALIZED_NAME_FINANCEKIT_SUPPORTED)
  private Boolean financekitSupported;

  public static final String SERIALIZED_NAME_ENABLE_MULTI_ITEM_LINK = "enable_multi_item_link";
  @SerializedName(SERIALIZED_NAME_ENABLE_MULTI_ITEM_LINK)
  private Boolean enableMultiItemLink;

  public static final String SERIALIZED_NAME_USER_TOKEN = "user_token";
  @SerializedName(SERIALIZED_NAME_USER_TOKEN)
  private String userToken;


  public LinkTokenCreateRequest clientId(String clientId) {
    
    this.clientId = clientId;
    return this;
  }

   /**
   * Your Plaid API &#x60;client_id&#x60;. The &#x60;client_id&#x60; is required and may be provided either in the &#x60;PLAID-CLIENT-ID&#x60; header or as part of a request body.
   * @return clientId
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "Your Plaid API `client_id`. The `client_id` is required and may be provided either in the `PLAID-CLIENT-ID` header or as part of a request body.")

  public String getClientId() {
    return clientId;
  }


  public void setClientId(String clientId) {
    this.clientId = clientId;
  }


  public LinkTokenCreateRequest secret(String secret) {
    
    this.secret = secret;
    return this;
  }

   /**
   * Your Plaid API &#x60;secret&#x60;. The &#x60;secret&#x60; is required and may be provided either in the &#x60;PLAID-SECRET&#x60; header or as part of a request body.
   * @return secret
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "Your Plaid API `secret`. The `secret` is required and may be provided either in the `PLAID-SECRET` header or as part of a request body.")

  public String getSecret() {
    return secret;
  }


  public void setSecret(String secret) {
    this.secret = secret;
  }


  public LinkTokenCreateRequest clientName(String clientName) {
    
    this.clientName = clientName;
    return this;
  }

   /**
   * The name of your application, as it should be displayed in Link. Maximum length of 30 characters. If a value longer than 30 characters is provided, Link will display \&quot;This Application\&quot; instead.
   * @return clientName
  **/
  @ApiModelProperty(required = true, value = "The name of your application, as it should be displayed in Link. Maximum length of 30 characters. If a value longer than 30 characters is provided, Link will display \"This Application\" instead.")

  public String getClientName() {
    return clientName;
  }


  public void setClientName(String clientName) {
    this.clientName = clientName;
  }


  public LinkTokenCreateRequest language(String language) {
    
    this.language = language;
    return this;
  }

   /**
   * The language that Link should be displayed in. When initializing with Identity Verification, this field is not used; for more details, see [Identity Verification supported languages](https://plaid.com/docs/identity-verification/#supported-languages).  Supported languages are: - Danish (&#x60;&#39;da&#39;&#x60;) - Dutch (&#x60;&#39;nl&#39;&#x60;) - English (&#x60;&#39;en&#39;&#x60;) - Estonian (&#x60;&#39;et&#39;&#x60;) - French (&#x60;&#39;fr&#39;&#x60;) - German (&#x60;&#39;de&#39;&#x60;) - Hindi (&#x60;&#39;hi&#39;&#x60;) - Italian (&#x60;&#39;it&#39;&#x60;) - Latvian (&#x60;&#39;lv&#39;&#x60;) - Lithuanian (&#x60;&#39;lt&#39;&#x60;) - Norwegian (&#x60;&#39;no&#39;&#x60;) - Polish (&#x60;&#39;pl&#39;&#x60;) - Portuguese (&#x60;&#39;pt&#39;&#x60;) - Romanian (&#x60;&#39;ro&#39;&#x60;) - Spanish (&#x60;&#39;es&#39;&#x60;) - Swedish (&#x60;&#39;sv&#39;&#x60;) - Vietnamese (&#x60;&#39;vi&#39;&#x60;)  When using a Link customization, the language configured here must match the setting in the customization, or the customization will not be applied.
   * @return language
  **/
  @ApiModelProperty(required = true, value = "The language that Link should be displayed in. When initializing with Identity Verification, this field is not used; for more details, see [Identity Verification supported languages](https://plaid.com/docs/identity-verification/#supported-languages).  Supported languages are: - Danish (`'da'`) - Dutch (`'nl'`) - English (`'en'`) - Estonian (`'et'`) - French (`'fr'`) - German (`'de'`) - Hindi (`'hi'`) - Italian (`'it'`) - Latvian (`'lv'`) - Lithuanian (`'lt'`) - Norwegian (`'no'`) - Polish (`'pl'`) - Portuguese (`'pt'`) - Romanian (`'ro'`) - Spanish (`'es'`) - Swedish (`'sv'`) - Vietnamese (`'vi'`)  When using a Link customization, the language configured here must match the setting in the customization, or the customization will not be applied.")

  public String getLanguage() {
    return language;
  }


  public void setLanguage(String language) {
    this.language = language;
  }


  public LinkTokenCreateRequest countryCodes(List<CountryCode> countryCodes) {
    
    this.countryCodes = countryCodes;
    return this;
  }

  public LinkTokenCreateRequest addCountryCodesItem(CountryCode countryCodesItem) {
    this.countryCodes.add(countryCodesItem);
    return this;
  }

   /**
   * Specify an array of Plaid-supported country codes using the ISO-3166-1 alpha-2 country code standard. Institutions from all listed countries will be shown. For a complete mapping of supported products by country, see https://plaid.com/global/. By default, access is granted to US and CA. For Production or Limited Production access to other countries, [contact Sales](https://plaid.com/contact/) or your account manager.    If using Identity Verification, &#x60;country_codes&#x60; should be set to the country where your company is based, not the country where your user is located. For all other products, &#x60;country_codes&#x60; represents the location of your user&#39;s financial institution.  If Link is launched with multiple country codes, only products that you are enabled for in all countries will be used by Link. While all countries are enabled by default in Sandbox, in Production only the countries you have requested access for are shown. To request access to additional countries, [file a product access Support ticket](https://dashboard.plaid.com/support/new/product-and-development/product-troubleshooting/request-product-access) via the Plaid dashboard.  If using a Link customization, make sure the country codes in the customization match those specified in &#x60;country_codes&#x60;, or the customization may not be applied.  If using the Auth features Instant Match, Instant Micro-deposits, Same-day Micro-deposits, Automated Micro-deposits, or Database Auth, &#x60;country_codes&#x60; must be set to &#x60;[&#39;US&#39;]&#x60;.
   * @return countryCodes
  **/
  @ApiModelProperty(required = true, value = "Specify an array of Plaid-supported country codes using the ISO-3166-1 alpha-2 country code standard. Institutions from all listed countries will be shown. For a complete mapping of supported products by country, see https://plaid.com/global/. By default, access is granted to US and CA. For Production or Limited Production access to other countries, [contact Sales](https://plaid.com/contact/) or your account manager.    If using Identity Verification, `country_codes` should be set to the country where your company is based, not the country where your user is located. For all other products, `country_codes` represents the location of your user's financial institution.  If Link is launched with multiple country codes, only products that you are enabled for in all countries will be used by Link. While all countries are enabled by default in Sandbox, in Production only the countries you have requested access for are shown. To request access to additional countries, [file a product access Support ticket](https://dashboard.plaid.com/support/new/product-and-development/product-troubleshooting/request-product-access) via the Plaid dashboard.  If using a Link customization, make sure the country codes in the customization match those specified in `country_codes`, or the customization may not be applied.  If using the Auth features Instant Match, Instant Micro-deposits, Same-day Micro-deposits, Automated Micro-deposits, or Database Auth, `country_codes` must be set to `['US']`.")

  public List<CountryCode> getCountryCodes() {
    return countryCodes;
  }


  public void setCountryCodes(List<CountryCode> countryCodes) {
    this.countryCodes = countryCodes;
  }


  public LinkTokenCreateRequest user(LinkTokenCreateRequestUser user) {
    
    this.user = user;
    return this;
  }

   /**
   * Get user
   * @return user
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "")

  public LinkTokenCreateRequestUser getUser() {
    return user;
  }


  public void setUser(LinkTokenCreateRequestUser user) {
    this.user = user;
  }


  public LinkTokenCreateRequest userId(String userId) {
    
    this.userId = userId;
    return this;
  }

   /**
   * A &#x60;user_id&#x60; generated using &#x60;/user/create&#x60;. Required for integrations that began using Plaid Protect, Multi-Item Link, or Plaid Check Consumer Report after December 10, 2025. For more details, see [new User APIs](https://plaid.com/docs/api/users/user-apis). One of either the &#x60;user_id&#x60; or the &#x60;user&#x60; field is required.
   * @return userId
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "A `user_id` generated using `/user/create`. Required for integrations that began using Plaid Protect, Multi-Item Link, or Plaid Check Consumer Report after December 10, 2025. For more details, see [new User APIs](https://plaid.com/docs/api/users/user-apis). One of either the `user_id` or the `user` field is required.")

  public String getUserId() {
    return userId;
  }


  public void setUserId(String userId) {
    this.userId = userId;
  }


  public LinkTokenCreateRequest products(List<Products> products) {
    
    this.products = products;
    return this;
  }

  public LinkTokenCreateRequest addProductsItem(Products productsItem) {
    if (this.products == null) {
      this.products = new ArrayList<>();
    }
    this.products.add(productsItem);
    return this;
  }

   /**
   * List of Plaid product(s) that the linked Item must support. If launching Link in update mode, should be omitted (unless you are using update mode to add a credit product, such as Assets, Statements, Income, or Plaid Check Consumer Report, to an existing Item); at least one &#x60;product&#x60; is required otherwise.  To maximize the number of institutions and accounts available, initialize Link with the minimal product set required for your use case, as the products specified will limit which institutions and account types will be available to your users in Link. Only institutions that support *all* requested products can be selected; if a user attempts to select an institution that does not support a listed product, a \&quot;Connectivity not supported\&quot; error message will appear in Link. For each specified product, the Item connected by the user must contain at least one compatible account. For details on compatible product / account type combinations, see [the account type/product support matrix](https://plaid.com/docs/api/accounts/#account-type--product-support-matrix).  To add products without limiting the institution list or account types, use the [&#x60;optional_products&#x60;](https://plaid.com/docs/api/link/#link-token-create-request-optional-products) or  [&#x60;required_if_supported_products&#x60;](https://plaid.com/docs/api/link/#link-token-create-request-required-if-supported-products) fields. Products can also be added to an Item by calling the product endpoint after obtaining an access token; this may require the product to be listed in the [&#x60;additional_consented_products&#x60;](https://plaid.com/docs/api/link/#link-token-create-request-additional-consented-products) array. For details, see [Choosing when to initialize products](https://plaid.com/docs/link/initializing-products/).  &#x60;balance&#x60; is *not* a valid value, the Balance product does not require explicit initialization and will automatically be initialized when any other product is initialized.  If launching Link with CRA products, &#x60;cra_base_reports&#x60; is required and must be included in the &#x60;products&#x60; array.  Note that, unless you have opted to disable Instant Match support, institutions that support Instant Match will also be shown in Link if &#x60;auth&#x60; is specified as a product, even though these institutions do not contain &#x60;auth&#x60; in their product array.  In Production, you will be billed for each product that you specify when initializing Link. Note that a product cannot be removed from an Item once the Item has been initialized with that product. To stop billing on an Item for subscription-based products, such as Liabilities, Investments, and Transactions, remove the Item via &#x60;/item/remove&#x60;.
   * @return products
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "List of Plaid product(s) that the linked Item must support. If launching Link in update mode, should be omitted (unless you are using update mode to add a credit product, such as Assets, Statements, Income, or Plaid Check Consumer Report, to an existing Item); at least one `product` is required otherwise.  To maximize the number of institutions and accounts available, initialize Link with the minimal product set required for your use case, as the products specified will limit which institutions and account types will be available to your users in Link. Only institutions that support *all* requested products can be selected; if a user attempts to select an institution that does not support a listed product, a \"Connectivity not supported\" error message will appear in Link. For each specified product, the Item connected by the user must contain at least one compatible account. For details on compatible product / account type combinations, see [the account type/product support matrix](https://plaid.com/docs/api/accounts/#account-type--product-support-matrix).  To add products without limiting the institution list or account types, use the [`optional_products`](https://plaid.com/docs/api/link/#link-token-create-request-optional-products) or  [`required_if_supported_products`](https://plaid.com/docs/api/link/#link-token-create-request-required-if-supported-products) fields. Products can also be added to an Item by calling the product endpoint after obtaining an access token; this may require the product to be listed in the [`additional_consented_products`](https://plaid.com/docs/api/link/#link-token-create-request-additional-consented-products) array. For details, see [Choosing when to initialize products](https://plaid.com/docs/link/initializing-products/).  `balance` is *not* a valid value, the Balance product does not require explicit initialization and will automatically be initialized when any other product is initialized.  If launching Link with CRA products, `cra_base_reports` is required and must be included in the `products` array.  Note that, unless you have opted to disable Instant Match support, institutions that support Instant Match will also be shown in Link if `auth` is specified as a product, even though these institutions do not contain `auth` in their product array.  In Production, you will be billed for each product that you specify when initializing Link. Note that a product cannot be removed from an Item once the Item has been initialized with that product. To stop billing on an Item for subscription-based products, such as Liabilities, Investments, and Transactions, remove the Item via `/item/remove`.")

  public List<Products> getProducts() {
    return products;
  }


  public void setProducts(List<Products> products) {
    this.products = products;
  }


  public LinkTokenCreateRequest requiredIfSupportedProducts(List<Products> requiredIfSupportedProducts) {
    
    this.requiredIfSupportedProducts = requiredIfSupportedProducts;
    return this;
  }

  public LinkTokenCreateRequest addRequiredIfSupportedProductsItem(Products requiredIfSupportedProductsItem) {
    if (this.requiredIfSupportedProducts == null) {
      this.requiredIfSupportedProducts = new ArrayList<>();
    }
    this.requiredIfSupportedProducts.add(requiredIfSupportedProductsItem);
    return this;
  }

   /**
   * List of Plaid product(s) you wish to use only if the institution and account(s) selected by the user support the product. Institutions that do not support these products will still be shown in Link. The products will only be extracted and billed if the user selects an institution and account type that supports them.  There should be no overlap between this array and the &#x60;products&#x60;, &#x60;optional_products&#x60;, or &#x60;additional_consented_products&#x60; arrays. The &#x60;products&#x60; array must have at least one product.  For more details on using this feature, see [Required if Supported Products](https://plaid.com/docs/link/initializing-products/#required-if-supported-products).
   * @return requiredIfSupportedProducts
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "List of Plaid product(s) you wish to use only if the institution and account(s) selected by the user support the product. Institutions that do not support these products will still be shown in Link. The products will only be extracted and billed if the user selects an institution and account type that supports them.  There should be no overlap between this array and the `products`, `optional_products`, or `additional_consented_products` arrays. The `products` array must have at least one product.  For more details on using this feature, see [Required if Supported Products](https://plaid.com/docs/link/initializing-products/#required-if-supported-products).")

  public List<Products> getRequiredIfSupportedProducts() {
    return requiredIfSupportedProducts;
  }


  public void setRequiredIfSupportedProducts(List<Products> requiredIfSupportedProducts) {
    this.requiredIfSupportedProducts = requiredIfSupportedProducts;
  }


  public LinkTokenCreateRequest optionalProducts(List<Products> optionalProducts) {
    
    this.optionalProducts = optionalProducts;
    return this;
  }

  public LinkTokenCreateRequest addOptionalProductsItem(Products optionalProductsItem) {
    if (this.optionalProducts == null) {
      this.optionalProducts = new ArrayList<>();
    }
    this.optionalProducts.add(optionalProductsItem);
    return this;
  }

   /**
   * List of Plaid product(s) that will enhance the consumer&#39;s use case, but that your app can function without. Plaid will attempt to fetch data for these products on a best-effort basis, and failure to support these products will not affect Item creation.  There should be no overlap between this array and the &#x60;products&#x60;, &#x60;required_if_supported_products&#x60;, or &#x60;additional_consented_products&#x60; arrays. The &#x60;products&#x60; array must have at least one product.  For more details on using this feature, see [Optional Products](https://plaid.com/docs/link/initializing-products/#optional-products).
   * @return optionalProducts
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "List of Plaid product(s) that will enhance the consumer's use case, but that your app can function without. Plaid will attempt to fetch data for these products on a best-effort basis, and failure to support these products will not affect Item creation.  There should be no overlap between this array and the `products`, `required_if_supported_products`, or `additional_consented_products` arrays. The `products` array must have at least one product.  For more details on using this feature, see [Optional Products](https://plaid.com/docs/link/initializing-products/#optional-products).")

  public List<Products> getOptionalProducts() {
    return optionalProducts;
  }


  public void setOptionalProducts(List<Products> optionalProducts) {
    this.optionalProducts = optionalProducts;
  }


  public LinkTokenCreateRequest additionalConsentedProducts(List<Products> additionalConsentedProducts) {
    
    this.additionalConsentedProducts = additionalConsentedProducts;
    return this;
  }

  public LinkTokenCreateRequest addAdditionalConsentedProductsItem(Products additionalConsentedProductsItem) {
    if (this.additionalConsentedProducts == null) {
      this.additionalConsentedProducts = new ArrayList<>();
    }
    this.additionalConsentedProducts.add(additionalConsentedProductsItem);
    return this;
  }

   /**
   * List of additional Plaid product(s) you wish to collect consent for to support your use case. These products will not be billed until you start using them by calling the relevant endpoints.  &#x60;balance&#x60; is *not* a valid value, the Balance product does not require explicit initialization and will automatically have consent collected.  Institutions that do not support these products will still be shown in Link.  There should be no overlap between this array and the &#x60;products&#x60; or &#x60;required_if_supported_products&#x60; arrays.  If you include &#x60;signal&#x60; in &#x60;additional_consented_products&#x60;, you will need to call [&#x60;/signal/prepare&#x60;](https://plaid.com/docs/api/products/signal/#signalprepare) before calling &#x60;/signal/evaluate&#x60; for the first time on an Item in order to get the most accurate results. For more details, see [&#x60;/signal/prepare&#x60;](https://plaid.com/docs/api/products/signal/#signalprepare).
   * @return additionalConsentedProducts
  **/
  @javax.annotation.Nullable
