I haven’t seen a writeup of this elsewhere so thought I’d share! I set up a sensor using Plaid APIs to display a bank account balance in HA:
This is completely free (using the Limited Production environment) if you want to use it for a small personal setup like this.
Here are roughly the steps involved, which do require some development skills, or at least willingness to act like a developer . It also requires some patience, as you will need to contact support and wait for approval for certain steps.
(Sorry if I missed a step, since I’m writing this up after the fact.)
-
Sign up for Plaid. Depending on which financial institutions you want to link with, you may need to need to also request approval for Production access and fill out some additional forms/questionnaires for OAuth — even if you are going to be staying within the free Limited Production API calls. From the launch checklist:
Complete your application profile and company profile, which are required to access certain institutions that use OAuth-based connections.
You can view the status for your OAuth access here.
-
EDIT 2025/1/18: apparently Hosted Link no longer requires a support request!
Create a support ticket asking to enable Hosted Link. This is a fully-hosted version of the Plaid authentication flow that allows you to link your bank accounts without deploying any software (without Hosted Link you would need to provide a URL for the normal Link flow to redirect back to). You will have to describe to the support team what you’re planning to build, at least in enough detail to convince them you’re not a scammer.You can probably proceed without Hosted Link if you have the skills to implement a regular Link flow. -
Send a
POST /link/token/create
with yourclient_id
and Production secret, and include"hosted_link": {}
to enable Hosted Link:curl -X POST "https://production.plaid.com/link/token/create" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "client_id": "YOUR_CLIENT_ID_HERE", "secret": "YOUR_PRODUCTION_SECRET_HERE", "language": "en", "client_name": "Plaid Test App", "country_codes": ["US"], "products": ["transactions"], "hosted_link": {} }'
You should get a response that looks like this:
{ "expiration": "2024-06-15T04:09:15Z", "hosted_link_url": "https://secure.plaid.com/hl/...", "link_token": "link-production-...", "request_id": "..." }
Take note of the
link_token
andhosted_link_url
values. If thehosted_link_url
is missing, you did not complete the previous step! -
Copy and paste the
hosted_link_url
into your browser. This will take you through the regular Plaid linking flow that you see when linking accounts on other websites. Connect the bank account(s) you wish to display in HA. -
Once you’ve successfully linked your account, call
POST /link/token/get
with yourlink_token
:curl -X "POST" "https://production.plaid.com/link/token/get" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "client_id": "YOUR_CLIENT_ID_HERE", "secret": "YOUR_PRODUCTION_SECRET_HERE", "link_token": "link-production-THE_LINK_TOKEN_YOU_RECEIVED_ABOVE" }'
This will return a lengthy response from which you need to extract the
public_token
:{ "created_at": "2024-06-15T03:39:14Z", "expiration": "2024-06-15T04:09:15Z", "link_sessions": [ { "events": [ ...lots of stuff here... ], "finished_at": "2024-06-15T03:42:06.285807862Z", "link_session_id": "...", "results": { "item_add_results": [ { "accounts": [ { "name": "My account", ... } ], "institution": { "institution_id": "ins_56", "name": "Chase" }, "public_token": "public-production-THIS_IS_THE_IMPORTANT_PART!!!" } ] } } ], ... }
-
Call
POST /item/public_token/exchange
to convert the public token into an access token:curl -X "POST" "https://production.plaid.com/item/public_token/exchange" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "client_id": "YOUR_CLIENT_ID_HERE", "secret": "YOUR_PRODUCTION_SECRET_HERE", "public_token": "public-production-THE_PUBLIC_TOKEN_YOU_RECEIVED_ABOVE" }'
This will return an access_token, which is what Home Assistant will use to retrieve your account balance:
{ "access_token": "access-production-...", "item_id": "...", "request_id": "..." }
-
Edit your secrets.yaml and add the following:
plaid_client_id: YOUR_CLIENT_ID_HERE plaid_secret: YOUR_PRODUCTION_SECRET_HERE plaid_account_balance_get_payload: | {"access_token":"access-production-THE_ACCESS_TOKEN_YOU_RECEIVED_ABOVE"}
-
Finally, edit your configuration.yaml to add a RESTful sensor(s) using these secrets and
EDIT 2024/7/23: I believe/accounts/balance/get
/accounts/get
is completely free and equally satisfactory for this use case:rest: - scan_interval: 43200 # 12 hours resource: https://production.plaid.com/accounts/get method: POST headers: Content-Type: application/json PLAID-CLIENT-ID: !secret plaid_client_id PLAID-SECRET: !secret plaid_secret payload: !secret plaid_account_balance_get_payload sensor: - device_class: monetary name: My bank account current balance unique_id: my_bank_account.current_balance unit_of_measurement: USD # change as necessary :) value_template: | {{ (value_json.accounts | first).balances.current }} # Note: for extra sanity-checking, you can also use # `value_json.accounts | selectattr('account_id', 'equalto', '...') | first` # if you know which account_id refers to the account you want. - device_class: monetary name: My bank account available balance unique_id: my_bank_account.available_balance unit_of_measurement: USD # change as necessary :) value_template: | {{ (value_json.accounts | first).balances.available }}
If everything went smoothly you should have new sensor entities in HA
(If you want to link more than one financial institution, you’ll need to repeat steps 3-8.)
I imagine that this could be turned into a blueprint or integration or something, kind of like how the Google Assistant setup flow works — but I’m pretty new to customizing HA so I didn’t try to go down that route yet, I was just happy to get it working for myself. I’d be curious if anyone knows more about how to make this reusable or easier for others to set up!