Link Android SDK
Learn how to integrate your app with the Link Android SDK
Overview
The Plaid Link SDK is a quick and secure way to link bank accounts to Plaid in your Android app. Link is a drop-in module that handles connecting a financial institution to your app (credential validation, multi-factor authentication, error handling, etc), without passing sensitive personal information to your server.
To get started with Plaid Link for Android, clone the GitHub repository and try out the example application, which provides a reference implementation in both Java and Kotlin. Youʼll want to sign up for free API keys through the Plaid Dashboard to get started.

Prefer to learn by watching? A video guide is available for this content.
Initial Android setup
Before writing code using the SDK, you must first perform some setup steps to register your app with Plaid and configure your project.
Register your app ID
To register your Android app ID:
- Sign in to the Plaid Dashboard and go to the Developers -> API page.
- Next to Allowed Android Package Names click Configure then Add New Android Package Name.
- Enter your package name, for example
com.plaid.example. - Click Save Changes.
Your Android app is now set up and ready to start integrating with the Plaid SDK.
New versions of the Android SDK are released frequently, at least once every few months. Major releases occur annually. You should keep your version up-to-date to provide the best Plaid Link experience in your application.
Update your project plugins
In your root-level (project-level) Gradle file (build.gradle), add rules to include
the Android Gradle plugin. Check that you have Google's Maven repository as well.
1buildscript {2 repositories {3 // Check that you have the following line (if not, add it):4 google() // Google's Maven repository5 mavenCentral() // Include to import Plaid Link Android SDK6 }7 dependencies {8 // ...9 }10}Add the PlaidLink SDK to your app
In your module (app-level) Gradle file (usually app/build.gradle), add a line to the bottom of the file.
The latest version of the PlaidLink SDK is
and can be found on Maven Central.
1android {2 defaultConfig {3 minSdkVersion 21 // or greater4 }5}67dependencies {8 // ...9 implementation 'com.plaid.link:sdk-core:<insert latest version>'10}Enable camera support (Identity Verification only)
If your app uses Identity Verification, a user may need to take a picture of identity documentation or a selfie during the Link flow. To support this workflow, the CAMERA , WRITE_EXTERNAL_STORAGE, RECORD_AUDIO, and MODIFY_AUDIO_SETTINGS permissions need to be added to your application's AndroidManifest.xml. (While Plaid does not record any audio, some older Android devices require these last two permissions to use the camera.) The WRITE_EXTERNAL_STORAGE permission should be limited to < Android 9 (i.e. maxSdk=28). If these permissions are not granted in an app that uses Identity Verification, the app may crash during Link.
Opening Link
Before you can open Link, you need to first create a link_token by calling /link/token/create from your backend.
This call should never happen directly from the mobile client, as it risks exposing your API secret.
The /link/token/create call must include the android_package_name parameter, which should match the applicationId from your app-level
build.gradle file. You can learn more about applicationId in Google's Android
developer documentation.
1const request: LinkTokenCreateRequest = {2 user: {3 client_user_id: 'user-id',4 },5 client_name: 'Plaid Test App',6 products: ['auth', 'transactions'],7 country_codes: ['GB'],8 language: 'en',9 webhook: 'https://sample-web-hook.com',10 android_package_name: 'com.plaid.example'11 },12};13try {14 const response = await plaidClient.linkTokenCreate(request);15 const linkToken = response.data.link_token;16} catch (error) {17 // handle error18}Create a LinkTokenConfiguration
Each time you open Link, you will need to get a new link_token from your server and create a new
LinkTokenConfiguration object with it.
1val linkTokenConfiguration = linkTokenConfiguration {2 token = "LINK_TOKEN_FROM_SERVER"3}The Link SDK runs as a separate Activity within your app. In order to return the result
to your app, it supports both the standard startActivityForResult and onActivityResult
and the ActivityResultContract result APIs.
Register a callback for an Activity Result
1private val linkAccountToPlaid =2registerForActivityResult(OpenPlaidLink()) {3 when (it) {4 is LinkSuccess -> /* handle LinkSuccess */5 is LinkExit -> /* handle LinkExit */6 }7}Open Link
1linkAccountToPlaid.launch(linkTokenConfiguration)At this point, Link will open, and will trigger the onSuccess callback if the user successfully completes the Link flow.
onSuccess
The method is called when a user successfully links an Item. The onSuccess handler returns a LinkConnection class that includes the public_token, and additional Link metadata in the form of a LinkConnectionMetadata class.
publicTokenmetadataaccountsaccounts will only include selected accounts.idaccount_idnamemasksubtypetypeverification_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 deposit.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.null: The Item is not using micro-deposit verification.institutionnull.name'Wells Fargo'institution_idlinkSessionIdmetadataJson1val success = result as LinkSuccess23// Send public_token to your server, exchange for access_token4val publicToken = success.publicToken5val metadata = success.metadata6metadata.accounts.forEach { account ->7 val accountId = account.id8 val accountName = account.name9 val accountMask = account.mask10 val accountSubType = account.subtype11}12val institutionId = metadata.institution?.id13val institutionName = metadata.institution?.nameonExit
The onExit handler is called when a user exits Link without successfully linking an Item, or when an error occurs during Link initialization. The PlaidError returned from the onExit handler is meant to help you guide your users after they have exited Link. We recommend storing the error and metadata information server-side in a way that can be associated with the user. You’ll also need to include this and any other relevant information in Plaid Support requests for the user.
errorerror will be null.displayMessagenull if the error is not related to user action. This may change over time and is not safe for programmatic use.errorMessageerrorJsonLinkExitMetadatalinkSessionIdinstitutionnull.name'Wells Fargo'institution_idstatusrequires_questionsrequires_selectionsrequires_recaptcharequires_codechoose_devicerequires_credentialsrequires_account _selectioninstitution_not_foundinstitution_not _supportedunknownrequestId1val exit = result as LinkExit23val error = exit.error4error?.let { err ->5 val errorCode = err.errorCode6 val errorMessage = err.errorMessage7 val displayMessage = err.displayMessage8}9val metadata = exit.metadata10val institutionId = metadata.institution?.id11val institutionName = metadata.institution?.name12val linkSessionId = metadata.linkSessionId;13val requestId = metadata.requestId;onEvent
The onEvent callback is called at certain points in the Link flow. Unlike the handlers for onSuccess and onExit, the onEvent handler is initialized as a global lambda passed to the Plaid class. OPEN events will be sent immediately upon Link’s opening, and remaining events will be sent by the time onSuccess or onExit is called. If you need the exact time when an event happened, use the timestamp property.
The following onEvent callbacks are stable, which means that they will not be deprecated or changed: OPEN, EXIT, HANDOFF, SELECT_INSTITUTION, ERROR, BANK_INCOME_INSIGHTS_COMPLETED, IDENTITY_VERIFICATION_PASS_SESSION, IDENTITY_VERIFICATION_FAIL_SESSION. The remaining callback events are informational and subject to change.
eventNameBANK_INCOME_INSIGHTS _COMPLETEDCLOSE_OAUTHCONNECT_NEW _INSTITUTIONERRORerror_code metadata.FAIL_OAUTHHANDOFFIDENTITY_VERIFICATION _START_STEPview_name.IDENTITY_VERIFICATION _PASS_STEPview_name.IDENTITY_VERIFICATION _FAIL_STEPview_name.IDENTITY_VERIFICATION _PENDING_REVIEW_STEPIDENTITY_VERIFICATION _CREATE_SESSIONIDENTITY_VERIFICATION _RESUME_SESSIONIDENTITY_VERIFICATION _PASS_SESSIONIDENTITY_VERIFICATION _FAIL_SESSIONIDENTITY_VERIFICATION _PENDING_REVIEW _SESSIONIDENTITY_VERIFICATION _OPEN_UIIDENTITY_VERIFICATION _RESUME_UIIDENTITY_VERIFICATION _CLOSE_UIMATCHED_SELECT _INSTITUTIONrouting_number was provided when calling /link/token/create. To distinguish between the two scenarios, see LinkEventMetadata.match_reason.MATCHED_SELECT_VERIFY _METHODOPENOPEN_MY_PLAIDOPEN_OAUTHSEARCH_INSTITUTIONSKIP_SUBMIT_PHONESELECT_BRANDSELECT_BRAND event is only emitted for large financial institutions with multiple online banking portals.SELECT_DEGRADED _INSTITUTIONDEGRADED health status and was shown a corresponding message.SELECT_DOWN _INSTITUTIONDOWN health status and was shown a corresponding message.SELECT_FILTERED _INSTITUTIONSELECT_INSTITUTIONSUBMIT_ACCOUNT_NUMBERaccount_number_mask metadata to indicate the mask of the account number the user provided.SUBMIT_CREDENTIALSSUBMIT_MFASUBMIT_PHONESUBMIT_ROUTING_NUMBERrouting_number metadata to indicate user's routing number.TRANSITION_VIEWTRANSITION_VIEW event indicates that the user has moved from one view to the next.UPLOAD_DOCUMENTSVERIFY_PHONEVIEW_DATA_TYPESUNKNOWNUNKNOWN event indicates that the event is not handled by the current version of the SDK.LinkEventMetadataaccountNumberMaskaccount_number_mask is empty. Emitted by SUBMIT_ACCOUNT_NUMBER.errorCodeERROR, EXIT.errorMessageERROR, EXIT.errorTypeERROR, EXIT.exitStatusEXIT.institutionIdinstitutionNameinstitutionSearchQuerySEARCH_INSTITUTION.isUpdateModeOPEN.matchReasonreturning_user or routing_number if emitted by: MATCHED_SELECT_INSTITUTION.
Otherwise, this will be SAVED_INSTITUTION or AUTO_SELECT_SAVED_INSTITUTION if emitted by: SELECT_INSTITUTION.routingNumberSUBMIT_ROUTING_NUMBER.linkSessionIdlink_session_id is a unique identifier for a single session of Link. It's always available and will stay constant throughout the flow. Emitted by: all events.mfaTypecode device questions selections. Emitted by: SUBMIT_MFA and TRANSITION_VIEW when view_name is MFA.requestIdselectionselection is used to describe selected verification method, then possible values are phoneotp or password; if selection is used to describe the selected Auth Type Select flow, then possible values are flow_type_manual or flow_type_instant. Emitted by: MATCHED_SELECT_VERIFY_METHOD and SELECT_AUTH_TYPE.timestamp2017-09-14T14:42:19.350Z. Emitted by: all events.viewNameTRANSITION_VIEW.ACCEPT_TOSCONNECTEDCONSENTCREDENTIALDATA_TRANSPARENCYDATA_TRANSPARENCY _CONSENTDOCUMENTARY _VERIFICATIONERROREXITKYC_CHECKLOADINGMATCHED_CONSENTMATCHED_CREDENTIALMATCHED_MFAMFANUMBERSOAUTHRECAPTCHARISK_CHECKSCREENINGSELECT_ACCOUNTSELECT_AUTH_TYPESELECT_BRANDSELECT_INSTITUTIONSELECT_SAVED_ACCOUNTSELECT_SAVED _INSTITUTIONSELFIE_CHECKSUBMIT_PHONEUPLOAD_DOCUMENTSVERIFY_PHONEVERIFY_SMSmetadataJson1Plaid.setLinkEventListener { event -> Log.i("Event", event.toString()) }Upgrading
The latest version of the SDK is available from GitHub. SDK versions are supported for two years; with each major SDK release, Plaid will stop officially supporting any previous SDK versions that are more than two years old. While these older versions are expected to continue to work without disruption, Plaid will not provide assistance with unsupported SDK versions.
Next steps
If you run into problems integrating with Plaid Link on Android, see Troubleshooting the Plaid Link Android SDK.
Once you've gotten Link working, see Link best practices for recommendations on further improving the Link flow.