Token endpoints
API reference for obtaining and managing tokens from Link
Token exchange flow
Most API calls to Plaid endpoints require an access_token. An access_token
provides access to a specific Item, which is a Plaid term for a login at a
financial institution.
The primary flow for obtaining a Plaid access_token works as follows:
- Obtain a
link_tokenby calling/link/token/create. - Initialize Link by passing in the
link_token. When your user completes the Link flow, Link will pass back apublic_tokenvia theonSuccesscallback. For more information on initializing and receiving data back from Link, see the Link documentation. - Exchange the
public_tokenfor anaccess_tokenby calling/item/public_token/exchange.
The access_token can then be used to call Plaid endpoints and obtain
information about an Item.
In addition to the primary flow, several other token flows exist. The
Link update mode flow allows you to update an
access_token that has stopped working. The Sandbox testing environment also
offers the /sandbox/public_token/create endpoint, which allows you to create a
public_token without using Link.
Token endpoints
| In this section | |
|---|---|
/link/token/create | Create a token for initializing a Link session |
/link/token/get | Get details about a previously created Link token |
/item/public_token/exchange | Exchange a public token from Link for an access token |
/item/access_token/invalidate | Rotate an access token without deleting the Item |
/item/public_token/create | (Deprecated) Create a public token for legacy flows |
/link/token/create
Create Link Token
The /link/token/create endpoint creates a link_token, which is required as a parameter when initializing Link. Once Link has been initialized, it returns a public_token, which can then be exchanged for an access_token via /item/public_token/exchange as part of the main Link flow.
A link_token generated by /link/token/create is also used to initialize other Link flows, such as the update mode flow for tokens with expired credentials, or the Payment Initiation (Europe) flow.
Request fields and example
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.client_name1 languageSupported languages are:
- Danish (
'da') - Dutch (
'nl') - English (
'en') - Estonian (
'et') - French (
'fr') - German (
'de') - Italian (
'it') - Latvian (
'lv') - Lithuanian (
'lt') - Norwegian (
'no') - Polish (
'pl') - Portuguese (
'pt') - Romanian (
'ro') - Spanish (
'es') - Swedish (
'sv')
When using a Link customization, the language configured here must match the setting in the customization, or the customization will not be applied.
1 country_codesIf 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. Note that while all countries are enabled by default in Sandbox and Development, in Production only US and Canada are enabled by default. Access to European institutions requires additional compliance steps. To request access to European institutions in the Production environment, file a product access Support ticket via the Plaid dashboard. If you initialize with a European country code, your users will see the European consent panel during the Link flow.
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, Same-day Micro-deposits, or Automated Micro-deposits,
country_codes must be set to ['US'].1 US, GB, ES, NL, FR, IE, CA, DE, IT, PL, DK, NO, SE, EE, LT, LV, PT, BEuserclient_user_idclient_user_id. It is currently used as a means of searching logs for the given user in the Plaid Dashboard.1 legal_namenamegiven_namefamily_namephone_numberphone_number_verified _timeYYYY-MM-DDThh:mm:ssZ). This was previously an optional field used in the returning user experience. This field is no longer required to enable the returning user experience.Only pass a verification time for a phone number that you have verified. If you have performed verification but don’t have the time, you may supply a signal value of the start of the UNIX epoch.
Example:
2020-01-01T00:00:00Zdate-time email_addressemail_address _verified_timeYYYY-MM-DDThh:mm:ssZ). This was previously an optional field used in the returning user experience. This field is no longer required to enable the returning user experience.Only pass a verification time for an email address that you have verified. If you have performed verification but don’t have the time, you may supply a signal value of the start of the UNIX epoch.
Example:
2020-01-01T00:00:00Zdate-time ssnid_number field instead.date_of_birthdate addressstreetstreet2cityregionpostal_codecountry2 id_numbervaluetypear_dni, au_drivers_license, au_passport, br_cpf, ca_sin, cl_run, cn_resident_card, co_nit, dk_cpr, eg_national_id, es_dni, es_nie, hk_hkid, in_pan, it_cf, jo_civil_id, jp_my_number, ke_huduma_namba, kw_civil_id, mx_curp, mx_rfc, my_nric, ng_nin, nz_drivers_license, om_civil_id, ph_psn, pl_pesel, ro_cnp, sa_national_id, se_pin, sg_nric, tr_tc_kimlik, us_ssn, us_ssn_last_4, za_smart_idproductsbalance is not a valid value, the Balance product does not require explicit initialization and will automatically be initialized when any other product is initialized.The products specified here will determine which institutions will be available to your users in Link. Only institutions that support all requested products can be selected; a 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. To maximize the number of institutions available, initialize Link with the minimal product set required for your use case. Additional products can be included via the
optional_products or required_if_supported_products fields, or can be initialized by calling the endpoint after obtaining an access token. For details and exceptions, see Choosing when to initialize products.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.assets, auth, employment, identity, income_verification, identity_verification, investments, liabilities, payment_initiation, standing_orders, transactions, transfer, signalrequired_if_supported _productsThere 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.
auth, identity, investments, liabilities, transactions, statementsoptional_productsThere 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.
auth, identity, investments, liabilities, statements, transactionsadditional_consented _productsbalance 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
products or required_if_supported_products arrays.auth, identity, investments, liabilities, transactions, signalwebhookaccess_tokenaccess_token associated with the Item to update or reference, used when updating, modifying, or accessing an existing access_token. Used when launching Link in update mode, when completing the Same-day (manual) Micro-deposit flow, or (optionally) when initializing Link for a returning user as part of the Transfer UI flow.1 link_customization _namedefault customization will be used. When using a Link customization, the language in the customization must match the language selected via the language parameter, and the countries in the customization should match the country codes selected via country_codes.redirect_uriredirect_uri should not contain any query parameters. When used in Production or Development, must be an https URI. To specify any subdomain, use * as a wildcard character, e.g. https://*.example.com/oauth.html. Note that any redirect URI must also be added to the Allowed redirect URIs list in the developer dashboard. If initializing on Android, android_package_name must be specified instead and redirect_uri should be left blank. If using Hosted Link (beta) the redirect_uri must be set to https://hosted.plaid.com/oauth/redirect.android_package_namelink_token to initialize Link on Android. Any package name specified here must also be added to the Allowed Android package names setting on the developer dashboard. When creating a link_token for initializing Link on other platforms, android_package_name must be left blank and redirect_uri should be used instead.institution_datarouting_numberaccount_filtersproducts parameter of /link/token/create, and, if auth is specified in the products array, will also filter out accounts other than checking and savings accounts on the Account Select pane. You can further limit the accounts shown in Link by using account_filters to specify the account subtypes to be shown in Link. Only the specified subtypes will be shown. This filtering applies to both the Account Select view (if enabled) and the Institution Select view. Institutions that do not support the selected subtypes will be omitted from Link. To indicate that all subtypes should be shown, use the value "all". If the account_filters filter is used, any account type for which a filter is not specified will be entirely omitted from Link. For a full list of valid types and subtypes, see the Account schema.The filter may or may not impact the list of accounts shown by the institution in the OAuth account selection flow, depending on the specific institution. If the user selects excluded account subtypes in the OAuth flow, these accounts will not be added to the Item. If the user selects only excluded account subtypes, the link attempt will fail and the user will be prompted to try again.
depositorydepository-type accountsaccount_subtypeschecking, savings, hsa, cd, money market, paypal, prepaid, cash management, ebt, allcreditcredit-type accountsaccount_subtypescredit card, paypal, allloanloan-type accountsaccount_subtypesauto, business, commercial, construction, consumer, home equity, loan, mortgage, line of credit, student, other, allinvestmentinvestment-type accounts (or brokerage-type accounts for API versions 2018-05-22 and earlier).account_subtypes529, 401a, 401k, 403B, 457b, brokerage, cash isa, crypto exchange, education savings account, fixed annuity, gic, health reimbursement arrangement, hsa, ira, isa, keogh, lif, life insurance, lira, lrif, lrsp, mutual fund, non-custodial wallet, non-taxable brokerage account, other, other annuity, other insurance, pension, prif, profit sharing plan, qshr, rdsp, resp, retirement, rlif, roth, roth 401k, rrif, rrsp, sarsep, sep ira, simple ira, sipp, stock plan, tfsa, trust, ugma, utma, variable annuity, allotherother-type accountsaccount_subtypesother, allinstitution_idpayment_initiationpayment_initiation is included in the products array. Either payment_id or consent_id must be provided.payment_idpayment_id provided by the /payment_initiation/payment/create endpoint.consent_idconsent_id provided by the /payment_initiation/consent/create endpoint.income_verificationincome_verification is included in the products array.income_verification_idincome_verification_id of the verification instance, as provided by /income/verification/create.asset_report_idasset_report_id of an asset report associated with the user, as provided by /asset_report/create. Providing an asset_report_id is optional and can be used to verify the user through a streamlined flow. If provided, the bank linking flow will be skipped.access_tokenstransactions product was not initialized for these Items during link, it will be initialized after this Link session.This field should only be used with the
payroll income source type.income_source_typesbank and payroll. Currently you can only specify one of these options.bank, payrollbank_incomeincome_verification is included in the products array and bank is specified in income_source_types.days_requested1 731 enable_multiple_itemsfalse payroll_incomeflow_typespayroll_digital_income, payroll_document_incomeis_update_modefalse item_id_to_updateparsing_configocr, risk_signalsstated_income_sourcesemployercategoryOTHER, SALARY, UNEMPLOYMENT, CASH, GIG_ECONOMY, RENTAL, CHILD_SUPPORT, MILITARY, RETIREMENT, LONG_TERM_DISABILITY, BANK_INTERESTpay_per_cycledouble pay_annualdouble pay_typeGROSS, NET, or UNKNOWN for a specified income sourceUNKNOWN, GROSS, NETpay_frequencyUNKNOWN, WEEKLY, BIWEEKLY, SEMI_MONTHLY, MONTHLYauthauth_type_select _enabledsame_day_microdeposits_enabled is set to true.false automated _microdeposits_enabledinstant_match_enabledfalse.same_day _microdeposits_enabledinstant_microdeposits _enabledreroute_to_credentialsOPTIONAL.OFF, OPTIONAL, FORCEDflow_typeauth_type_select_enabled.FLEXIBLE_AUTHupdateaccount_selection _enabledtrue, enables update mode with Account Select for institutions that do not use OAuth, or that use OAuth but do not have their own account selection flow. For institutions that have an OAuth account selection flow (i.e. most OAuth-enabled institutions), update mode with Account Select will always be enabled, regardless of the value of this field.false identity_verificationtemplate_idgave_consentIf
gave_consent is set to true, the accept_tos step will be marked as skipped and the end user's session will start at the next step requirement.false statementsstart_datedate user_token/user/create. Any Item created during the Link session will be associated with the user.investmentsallow_unverified _crypto_walletstrue, allow self-custody crypto wallets to be added without requiring signature verification. Defaults to false.allow_manual_entrytrue, allow users to manually enter Investments account and holdings information. Defaults to false.hosted_linkdelivery_methoduser.phone_number.
'email' will deliver via email. Must pass user.email_address. In the Sandbox environment, this field will be ignored; use the Production or Development environment to test Hosted Link session delivery instead.sms, emailurl_lifetime_secondsis_mobile_appfalse transactionsdays_requestedWe strongly recommend that customers utilizing Recurring Transactions request at least 180 days of history for optimal results.
1 730 90 identityis_document_uploadaccount_idsaccount_ids1const request: LinkTokenCreateRequest = {2 loading_sample: true3};4try {5 const response = await plaidClient.linkTokenCreate(request);6 const linkToken = response.data.link_token;7} catch (error) {8 // handle error9}Response fields and example
link_tokenlink_token, which can be supplied to Link in order to initialize it and receive a public_token, which can be exchanged for an access_token.expirationlink_token, in ISO 8601 format. A link_token created to generate a public_token that will be exchanged for a new access_token expires after 4 hours. A link_token created for an existing Item (such as when updating an existing access_token by launching Link in update mode) expires after 30 minutes.date-time request_idhosted_link_url1{2 "link_token": "link-sandbox-af1a0311-da53-4636-b754-dd15cc058176",3 "expiration": "2020-03-27T12:56:34Z",4 "request_id": "XQVgFigpGHXkb0b"5}Was this helpful?
/link/token/get
Get Link Token
The /link/token/get endpoint gets information about a previously-created link_token using the
/link/token/create endpoint. It can be useful for debugging purposes.
Request fields and example
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.link_tokenlink_token from a previous invocation of /link/token/create1const request: LinkTokenGetRequest = {2 link_token: linkToken,3};4try {5 const response = await plaidClient.linkTokenGet(request);6} catch (error) {7 // handle error8}Response fields and example
link_tokenlink_token, which can be supplied to Link in order to initialize it and receive a public_token, which can be exchanged for an access_token.created_atexpirationlink_sessionslink_token. This field will only be present if your client is enabled for Hosted Link (beta). Session data will be provided for up to six hours after the session has ended.link_session_idstarted_atfinished_atdate-time on_successpublic_tokenmetadatainstitutionnull.name'Wells Fargo'institution_idaccountsaccounts will only include selected accounts.idaccount_idnamemasktypesubtypeverification_statuspending_automatic_verification: The Item is pending automatic verificationpending_manual_verification: The Item is pending manual micro-deposit verification. Items remain in this state until the user successfully verifies the code.automatically_verified: The Item has successfully been automatically verifiedmanually_verified: The Item has successfully been manually verifiedverification_expired: Plaid was unable to automatically verify the deposit within 7 calendar days and will no longer attempt to validate the Item. Users may retry by submitting their information again through Link.verification_failed: The Item failed manual micro-deposit verification because the user exhausted all 3 verification attempts. Users may retry by submitting their information again through Link.database_matched: The Item has successfully been verified using Plaid's data sources. Note: Database Match is currently a beta feature, please contact your account manager for more information.database_insights_pass: The Item's ACH numbers have been verified using Plaid's data sources and have strong signal for being valid. Note: Database Insights is currently a beta feature, please contact your account manager for more information.database_insights_pass_with_caution: The Item's ACH numbers have been verified using Plaid's data sources and have some signal for being valid. Note: Database Insights is currently a beta feature, please contact your account manager for more information.database_insights_fail: The Item's ACH numbers have been verified using Plaid's data sources and have signal for being invalid and/or have no signal for being valid. Note: Database Insights is currently a beta feature, please contact your account manager for more information.null: micro-deposit-based verification is not being used for the Item.class_typebusiness or personal account.link_session_idtransfer_statusCOMPLETE– The transfer was completed.INCOMPLETE– The transfer could not be completed. For help, see Troubleshooting transfers.
COMPLETE, INCOMPLETEon_exiterrorerror_type. In general, 200 HTTP codes correspond to success, 40X codes are for developer- or user-related failures, and 50X codes are for Plaid-related issues. An Item with a non-null error object will only be part of an API response when calling /item/get to view Item status. Otherwise, error fields will be null if no error has occurred; if an error has occurred, an error code will be returned instead.error_typeINVALID_REQUEST, INVALID_RESULT, INVALID_INPUT, INSTITUTION_ERROR, RATE_LIMIT_EXCEEDED, API_ERROR, ITEM_ERROR, ASSET_REPORT_ERROR, RECAPTCHA_ERROR, OAUTH_ERROR, PAYMENT_ERROR, BANK_TRANSFER_ERROR, INCOME_VERIFICATION_ERROR, MICRODEPOSITS_ERRORerror_codeerror_messagedisplay_messagenull if the error is not related to user action.This may change over time and is not safe for programmatic use.
request_idcausescauses will return an array of errors containing a breakdown of these errors on the individual Item level, if any can be identified.causes will only be provided for the error_type ASSET_REPORT_ERROR. causes will also not be populated inside an error nested within a warning object.statusdocumentation_urlsuggested_actionmetadatainstitutionnull.nameWells Fargoinstitution_idstatusrequires_questionsrequires_selectionsrequires_codechoose_devicerequires_credentialsrequires_account _selectionrequires_oauthinstitution_not_foundinstitution_not _supportedlink_session_idrequest_ideventsevent_nameevent_idmetadata/link/token/create call.initial_productsproducts specified in the /link/token/create call.assets, auth, employment, identity, income_verification, identity_verification, investments, liabilities, payment_initiation, standing_orders, transactions, transferwebhookwebhook specified in the /link/token/create call.country_codescountry_codes specified in the /link/token/create call.US, GB, ES, NL, FR, IE, CA, DE, IT, PL, DK, NO, SE, EE, LT, LV, PT, BElanguagelanguage specified in the /link/token/create call.institution_datarouting_numberaccount_filtersaccount_filters specified in the original call to /link/token/create.depositorydepository-type accountsaccount_subtypeschecking, savings, hsa, cd, money market, paypal, prepaid, cash management, ebt, allcreditcredit-type accountsaccount_subtypescredit card, paypal, allloanloan-type accountsaccount_subtypesauto, business, commercial, construction, consumer, home equity, loan, mortgage, line of credit, student, other, allinvestmentinvestment-type accounts (or brokerage-type accounts for API versions 2018-05-22 and earlier).account_subtypes529, 401a, 401k, 403B, 457b, brokerage, cash isa, crypto exchange, education savings account, fixed annuity, gic, health reimbursement arrangement, hsa, ira, isa, keogh, lif, life insurance, lira, lrif, lrsp, mutual fund, non-custodial wallet, non-taxable brokerage account, other, other annuity, other insurance, pension, prif, profit sharing plan, qshr, rdsp, resp, retirement, rlif, roth, roth 401k, rrif, rrsp, sarsep, sep ira, simple ira, sipp, stock plan, tfsa, trust, ugma, utma, variable annuity, allredirect_uriredirect_uri specified in the /link/token/create call.client_nameclient_name specified in the /link/token/create call.request_id1{2 "created_at": "2020-12-02T21:14:54Z",3 "expiration": "2020-12-03T01:14:54Z",4 "link_token": "link-sandbox-33792986-2b9c-4b80-b1f2-518caaac6183",5 "metadata": {6 "account_filters": {7 "depository": {8 "account_subtypes": [9 "checking",10 "savings"11 ]12 }13 },14 "client_name": "Insert Client name here",15 "country_codes": [16 "US"17 ],18 "initial_products": [19 "auth"20 ],21 "language": "en",22 "redirect_uri": null,23 "webhook": "https://www.example.com/webhook"24 },25 "request_id": "u0ydFs493XjyTYn"26}Was this helpful?
/item/public_token/exchange
Exchange public token for an access token
Exchange a Link public_token for an API access_token. Link hands off the public_token client-side via the onSuccess callback once a user has successfully created an Item. The public_token is ephemeral and expires after 30 minutes. An access_token does not expire, but can be revoked by calling /item/remove.
The response also includes an item_id that should be stored with the access_token. The item_id is used to identify an Item in a webhook. The item_id can also be retrieved by making an /item/get request.
Request fields and example
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.public_tokenpublic_token, obtained from the Link onSuccess callback or /sandbox/item/public_token/create.1const request: ItemPublicTokenExchangeRequest = {2 public_token: publicToken,3};4try {5 const response = await plaidClient.itemPublicTokenExchange(request);6 const accessToken = response.data.access_token;7 const itemId = response.data.item_id;8} catch (err) {9 // handle error10}Response fields and example
access_tokenitem_iditem_id value of the Item associated with the returned access_tokenrequest_id1{2 "access_token": "access-sandbox-de3ce8ef-33f8-452c-a685-8671031fc0f6",3 "item_id": "M5eVJqLnv3tbzdngLDp9FL5OlDNxlNhlE55op",4 "request_id": "Aim3b"5}Was this helpful?
/item/access_token/invalidate
Invalidate access_token
By default, the access_token associated with an Item does not expire and should be stored in a persistent, secure manner.
You can use the /item/access_token/invalidate endpoint to rotate the access_token associated with an Item. The endpoint returns a new access_token and immediately invalidates the previous access_token.
Request fields and example
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_token1// Generate a new access_token for an Item, invalidating the old one2const request: ItemAccessTokenInvalidateRequest = {3 access_token: accessToken,4};5try {6 const response = await plaidClient.itemAccessTokenInvalidate(request);7 // Store the new access_token in a persistent, secure datastore8 const accessToken = response.data.new_access_token;9} catch (error) {10 // handle error11}Response fields and example
new_access_tokenrequest_id1{2 "new_access_token": "access-sandbox-8ab976e6-64bc-4b38-98f7-731e7a349970",3 "request_id": "m8MDnv9okwxFNBV"4}Was this helpful?
/item/public_token/create
Create public token
Note: As of July 2020, the /item/public_token/create endpoint is deprecated. Instead, use /link/token/create with an access_token to create a Link token for use with update mode.
If you need your user to take action to restore or resolve an error associated with an Item, generate a public token with the /item/public_token/create endpoint and then initialize Link with that public_token.
A public_token is one-time use and expires after 30 minutes. You use a public_token to initialize Link in update mode for a particular Item. You can generate a public_token for an Item even if you did not use Link to create the Item originally.
The /item/public_token/create endpoint is not used to create your initial public_token. If you have not already received an access_token for a specific Item, use Link to obtain your public_token instead. See the Quickstart for more information.
Request fields and example
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_token1// This endpoint is deprecated and not2// supported in the Beta librariesResponse fields and example
public_tokenpublic_token for the particular Item corresponding to the specified access_tokenexpirationrequest_id1{2 "public_token": "public-sandbox-b0e2c4ee-a763-4df5-bfe9-46a46bce993d",3 "request_id": "Aim3b"4}