Managing Plaid Accounts

Now that you've integrated Plaid Link with the Hurdlr API, you may find that your user needs the ability to take certain actions to manage their linked bank accounts. The Hurdlr API makes this process easy, reducing how much back-end you need to build to support your Plaid integration.

1. Getting Plaid items

Once you've sent your user's Plaid access_token to Hurdlr, Hurdlr will then fetch and store the associated Plaid "Item", which is a parent-level object for any given bank. You can obtain all of a given user's Plaid Items (one per banking institution), by running the following GET request:

curl \
  --request GET \
  --url https://sandbox.hurdlr.com/rest/v5/banks/plaidItems \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' 

The response from GET /plaidItems contains an array of the user's Plaid Items (banks):

{
	data: [
    {
      "id": 52320,
      "status": "ACTIVE",
      "createdDate": "2020-02-20T21:22:07.000Z",
      "isInitialReady": true,
      "isHistoricalReady": true,
      "apiItemId": "3E51DvPAgMigGmybkpv9tzNjbjboEotqykvEo",
      "apiInstitutionId": "ins_5",
      "apiInstitutionName": "Citi",
      "apiAccessToken": "access-sandbox-da40d92a-dbc7-4399-be1c-fdb63338a147",
      "apiErrorCode": "ITEM_LOGIN_REQUIRED",
      "apiErrorMessage": "the login details of this item have changed (credentials, MFA, or required user action) and a user login is required to update this information. use Link's update mode to restore the item to a good state"
    },
    {
      "id": 64002,
      "status": "ACTIVE",
      "createdDate": "2021-09-15T17:49:12.000Z",
      "isInitialReady": true,
      "isHistoricalReady": true,
      "apiItemId": "AE7w17gMyNtn81AjggmQCXnWRpAJ8ri9zEmL3",
      "apiInstitutionId": "ins_4",
      "apiInstitutionName": "Wells Fargo",
      "apiAccessToken": "access-sandbox-0a9d120a-6656-4dd2-87b6-9d7f52abc16e",
      "apiErrorCode": null,
      "apiErrorMessage": null
    }
  ],
  lastUpdatedDate: "2021-09-01T15:37:40.107Z"
}

On each item, you may find the following attributes to be of particular interest:

FieldDescriptionFormat
idId of the Plaid Item, for reference within the Hurdlr APINumeric
isInitialReadyWhether the INITIAL Plaid Item webhook has been sent by Plaid, indicating that recent transactions are availableBoolean
isHistoricalReadyWhether the HISTORICAL Plaid Item webhook has been sent by Plaid, indicating that historical transactions are availableBoolean
apiItemIdId of the Plaid Item, for reference within Plaid's APIString
apiAccessTokenaccess_token Plaid Item, for reference within Plaid's APIString
apiInstitutionIdId of the institution that the transaction originated fromString
apiErrorCodeerror_code of the Plaid Item errorString
apiErrorMessageerror_message of the Plaid Item errorString

If you are using Hurdlr's Embeddable Expense Dashboard or Income Dashboard, then your design and development teams do not need to spend any time figuring out how to handle bank authentication-related errors. Hurdlr's Embeddable User Interface gracefully handles Plaid-related errors and walks your users through the steps on resolving those errors.

If you intend to resolve these errors on your own, then you will find the apiErrorCode and apiErrorMessage fields critical to your successful implementation.

2. Getting Plaid accounts

To see the actual bank (and credit card) accounts that your user has linked, you will want to retrieve the user's Plaid accounts:

curl \
  --request GET \
  --url https://sandbox.hurdlr.com/rest/v5/banks/accounts?apiName=PLAID \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' 

The response from GET /accounts contains an array of the user's linked accounts:

{
  data: [
    {
      "id": 142563,
      "plaidItemId": 52320,
      "status": "ACTIVE",
      "createdDate": "2020-02-20T21:02:06.000Z",
      "lastExpenseSyncedDate": "2020-03-16T19:48:45.000Z",
      "lastRevenueSyncedDate": "2020-03-16T19:48:45.000Z",
      "tranStartDate": "2020-01-21",
      "tranMinStartDate": "2019-01-01",
      "apiAccountId": "dz1g6e8WxQFEPDrkvRzkcDNNbkDVyxfZ3rm1Z",
      "apiAccountName": "Citi Checking",
      "apiAccountNo": "3332",
      "apiAccountSubType": "CHECKING",
      "apiInstitutionId": "ins_5",
      "apiOfficialName": "Citi Gold Standard 0% Interest Checking",
      "apiAccountType": "DEPOSITORY",
      "apiAvailableBalance": 100.0,
      "apiCurrentBalance": 110.0,
      "apiLimitBalance": null,
      "autoClassify": "OFF",
      "defaultBusinessId": null
    },
    {
      "id": 142564,
      "plaidItemId": 52320,
      "status": "ACTIVE",
      "createdDate": "2020-02-20T21:02:06.000Z",
      "lastExpenseSyncedDate": "2020-03-16T19:48:45.000Z",
      "lastRevenueSyncedDate": null,
      "tranStartDate": "2020-01-21",
      "tranMinStartDate": "2019-01-01",
      "apiAccountId": "aqQkbJ9gzjilDyLK57qKI1QQ631X8yc79VzmZ",
      "apiAccountName": "Citi Credit",
      "apiAccountNo": "3333",
      "apiAccountType": "CREDIT",
      "apiAccountSubType": "CREDIT_CARD",
      "apiInstitutionId": "ins_5",
      "apiOfficialName": "Citi Premier® Card",
      "apiAvailableBalance": 200.0,
      "apiCurrentBalance": 210.0,
      "apiLimitBalance": null,
      "autoClassify": "OFF",
      "defaultBusinessId": null
    },
    {
      "id": 142565,
      "plaidItemId": 64002,
      "status": "ACTIVE",
      "createdDate": "2020-02-20T21:02:06.000Z",
      "lastExpenseSyncedDate": "2020-03-16T19:48:45.000Z",
      "lastRevenueSyncedDate": "2020-03-16T19:48:45.000Z",
      "tranStartDate": "2020-01-21",
      "tranMinStartDate": "2019-01-01",
      "apiAccountId": "4W165wG79lFGAMP58lR5iB66w4BN7aCdx4Zyl",
      "apiAccountName": "Wells Fargo CD",
      "apiAccountNo": "2222",
      "apiAccountType": "DEPOSITORY",
      "apiAccountSubType": "CD",
      "apiInstitutionId": "ins_4",
      "apiOfficialName": "Wells Fargo Bronze Standard 0.2% Interest CD",
      "apiAvailableBalance": null,
      "apiCurrentBalance": 1000.0,
      "apiLimitBalance": null,
      "autoClassify": "OFF",
      "defaultBusinessId": null
    }
  ],
  lastUpdatedDate: "2021-09-01T15:40:40.107Z"
}

On each account, you may find the following attributes to be of particular interest:

FieldDescriptionFormat
idId of the Plaid Item account, for reference within the Hurdlr APINumeric
plaidItemIdId of the Plaid Item that this account belongs to, for reference within the Hurdlr APINumeric
lastExpenseSyncedDateLast date that expense transactions were pulled for this accountyyyy-MM-dd'T'HH:mm:ss.SSSZ
lastRevenueSyncedDateLast date that income transactions were pulled for this accountyyyy-MM-dd'T'HH:mm:ss.SSSZ
tranStartDateEarliest transaction date that Hurdlr pulled transactional data fromyyyy-MM-dd
tranMinStartDateEarliest transaction date that Hurdlr can pull transactional data fromyyyy-MM-dd'T'HH:mm:ss.SSSZ
apiInstitutionIdId of the institution that the transaction originated fromString
apiAccountNameName of the account, either assigned by the user or financial institutionString
apiAccountTypeType of the accountString
apiAccountSubTypeSubtype of the accountString
apiOfficialNameOfficial name of the account, as given by the financial institutionString
apiMaskMask of the user's bank account, often the last 4 digits of the account number2-4 Alphanumeric characters
apiAvailableBalanceAmount of funds available to be withdrawn from the accountNumeric, with 2 decimal places
apiCurrentBalanceAmount of funds in or owed by the accountNumeric, with 2 decimal places
apiLimitBalanceCredit or overdraft limitNumeric, with 2 decimal places
autoClassifyType of auto-classification; for any bank or credit card account that is not a business-only account, use "OFF"Must be one of the following: "OFF", "BUSINESS", "NOT_BUSINESS"
defaultBusinessIdId of the business that transactions from this account should be auto-assigned to; required (and only used) if autoClassify is set to "BUSINESS"Numeric

3. Pulling historical transactions

When you link your user's Plaid accounts to the Hurdlr API, Hurdlr pulls 30 days of transactions by default. Leveraging our experience iterating Hurdlr's own app with over 700k+ users, we concluded that 30 days is the best balance between giving users enough information to provide value, but without providing too much information so as to overwhelm them. With that being said, there are many use cases where you or your users may want to pull transactions further back, and Hurdlr makes that easy to do so.

For any given Plaid account, you can simply update the tranStartDate field to the desired historical date, and POST that account to the /accounts endpoint:

curl \
  --request POST \
  --url https://sandbox.hurdlr.com/rest/v5/banks/accounts \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
  	"accounts": [
      {
      	"id": 142565,
        "tranStartDate": "2019-01-01",
      }
    ]
  }'

🚧

The tranStartDate must be greater than or equal to the tranMinStartDate on the given account. The tranMinStartDate is the earliest date that Plaid has transactional data for the given account. That date varies by banking institution as well as when the user first linked with Plaid (including in other applications).

4. Setting an account to business-only

If a user has a business account that they do not commingle personal transactions into, you can set their account up so that every transaction that comes in is automatically classified as a business transaction. For any given Plaid account, you can simply update the autoClassify and defaultBusinessId fields, and POST that account to the /accounts endpoint:

curl \
  --request POST \
  --url https://sandbox.hurdlr.com/rest/v5/banks/accounts \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
  	"accounts": [
      {
      	"id": 142565,
        "autoClassify": "BUSINESS",
        "defaultBusinessId": 416080
      }
    ]
  }'

📘

The defaultBusinessId field is not required for users who only have one business; the Hurdlr API will automatically default to the user's sole business.

5. Removing a Plaid item

If your users wants to unlink a bank altogether, you can unlink the associated Plaid Item by making the following DELETE call, including the relevant Plaid Item's ID from the Hurdlr API:

curl \
  --request DELETE \
  --url https://sandbox.hurdlr.com/rest/v5/banks/plaidItem \
  --header 'Authorization: Bearer ${access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "id": 1234,
    "removeFromPlaid": true
  }'

Setting the removeFromPlaid parameter to true will also unlink the account with Plaid, so that Plaid no longer bills you for this item.