Skip to content
← Community packages

Read Plaid identity, items, accounts, balances, and transactions with sandbox-friendly secret-backed helpers.

Browse files

  • Integrations
  • plaid
  • banking
  • accounts
  • balances
  • transactions
  • identity
  • sandbox
  • finance
License
MIT
Published
August 22, 2026
Pinned commit
b7738cb
Rating
No ratings yet
Forks
0
Stars
0
Adaptation effort

README

@kody/plaid

Intent

Reusable Plaid helpers so Kody agents can read identity, Items, accounts, balances, and transactions on the caller's Plaid app — not a shared platform connection. Auth is a saved client id plus secret. Reads are free-form and sandbox-first. Link-token creation and other mutations default to a dry-run preview and need confirm: true to run live.

This listing is meant to be forked. After you fork, save your own plaidClientId / plaidSecret and call the helpers in your account. Never ask for or store a bank username or password in chat. Plaid Link (or the Sandbox public-token helper) is how Items are created.

Share this package as https://kody.codes/@kody/plaid

Auth

Client id + secret (secret-backed). There is no built-in Plaid OAuth integration and no bank-login flow in this package. Do not open /connect/oauth for Plaid. Do not collect institution credentials in chat.

SecretPurpose
plaidClientIdDashboard client id (PLAID_CLIENT_ID)
plaidSecretDashboard secret (PLAID_SECRET) — sandbox or production key
plaidAccessTokenOptional Item access_token after Link or sandbox exchange

Create keys at dashboard.plaid.com/developers/keys. Never paste the secret or a bank password into chat.

Required setup

  1. Create a Plaid account and copy the sandbox client_id and secret from the Plaid Dashboard keys page. Those dashboard fields are often documented as PLAID_CLIENT_ID / PLAID_SECRET in Plaid's quickstart env files.
  2. Save the client id (do not paste the value in chat):

https://kody.codes/account/secrets/new?name=plaidClientId&description=Plaid%20API%20client%20id%20from%20dashboard.plaid.com%2Fdevelopers%2Fkeys%20(PLAID_CLIENT_ID)&allowedHosts=sandbox.plaid.com,production.plaid.com&scope=user

  1. Save the secret:

https://kody.codes/account/secrets/new?name=plaidSecret&description=Plaid%20API%20secret%20from%20dashboard.plaid.com%2Fdevelopers%2Fkeys%20(PLAID_SECRET)&allowedHosts=sandbox.plaid.com,production.plaid.com&scope=user

  1. In the account secrets UI, approve hosts sandbox.plaid.com and production.plaid.com on both secrets. Saving a secret does not approve hosts by itself.
  2. Optional Item access token after Link or a confirmed sandbox exchange (this is not a bank password):

https://kody.codes/account/secrets/new?name=plaidAccessToken&description=Plaid%20Item%20access_token%20from%20Link%20or%20sandbox%20public-token%20exchange.%20Not%20a%20bank%20password.&allowedHosts=sandbox.plaid.com,production.plaid.com&scope=user

  1. Run the smoke test below.

Defaults to the Sandbox API (sandbox.plaid.com). Pass environment: "production" per call to use production.plaid.com. Items cannot move between environments.

Additional accounts

Pass account: "work" to use plaidClientId-work / plaidSecret-work / plaidAccessToken-work, or pass clientIdSecret / secretSecret / accessTokenSecret explicitly.

https://kody.codes/account/secrets/new?name=plaidClientId-work&description=Plaid%20API%20client%20id%20for%20the%20work%20account&allowedHosts=sandbox.plaid.com,production.plaid.com&scope=user

https://kody.codes/account/secrets/new?name=plaidSecret-work&description=Plaid%20API%20secret%20for%20the%20work%20account&allowedHosts=sandbox.plaid.com,production.plaid.com&scope=user

Hosts

  • sandbox.plaid.com — default, test Items only
  • production.plaid.com — live Items (environment: "production")

Bank login policy

Agents must never request, accept, or store a bank username or password. Plaid Link collects those credentials in Plaid's own UI. This package only creates a link_token (dry-run by default) or, in Sandbox, a public token via /sandbox/public_token/create without taking institution credentials.

If Plaid returns ITEM_LOGIN_REQUIRED, create a Link token in update mode and have the owner complete Link again. Do not ask them to type their bank password here.

Exports

  • kody:@kody/plaid — action dispatcher (defaults to smoke-test); also re-exports every helper below
  • kody:@kody/plaid/itemgetItem, exchangePublicToken, removeItem, updateItemWebhook
  • kody:@kody/plaid/accountsgetAccounts, getBalances
  • kody:@kody/plaid/identitygetIdentity
  • kody:@kody/plaid/transactionssyncTransactions, listTransactions, refreshTransactions
  • kody:@kody/plaid/institutionslistInstitutions, getInstitution, searchInstitutions
  • kody:@kody/plaid/linkcreateLinkToken (default dry-run)
  • kody:@kody/plaid/sandboxcreateSandboxPublicToken (default dry-run)
  • kody:@kody/plaid/smoke-test — dry-run self-check, then a live institutions read when plaidClientId and plaidSecret exist

Low-level transport (plaidRequest, PlaidApiError) stays pinned to sandbox.plaid.com / production.plaid.com with Plaid-Version: 2020-09-14.

Mutation safety

Link-token creation, sandbox public-token create, public-token exchange, Item remove, webhook update, and transactions refresh default to dry-run. They return { dryRun: true, method, path, body } unless you pass confirm: true. dryRun: true always previews, even with confirm.

import { createLinkToken } from 'kody:@kody/plaid/link'
import { createSandboxPublicToken } from 'kody:@kody/plaid/sandbox'
import { exchangePublicToken } from 'kody:@kody/plaid/item'

const preview = await createLinkToken({
	clientName: 'Example Finance',
	clientUserId: 'user-123',
})

const sandboxPreview = await createSandboxPublicToken()

const exchanged = await exchangePublicToken({
	publicToken: 'public-sandbox-…',
	confirm: true,
})

After a live exchange, save access_token as plaidAccessToken at the prefilled secrets URL. Do not leave it in chat longer than needed.

Smoke test

import { packages } from 'kody:runtime'

export default async function main() {
	return await packages.invoke({
		kodyId: 'plaid',
		exportName: './smoke-test',
	})
}

Without plaidClientId / plaidSecret this still returns { ok: true, live: false } plus the setup URLs. With those secrets saved it lists a few institutions — no Items created, no bank login.

A static import also works after publish:

import plaid from 'kody:@kody/plaid'

export default async function main() {
	return await plaid({ action: 'smoke-test' })
}

Example

import plaid from 'kody:@kody/plaid'

export default async function main() {
	return await plaid({ action: 'get-accounts' })
}

Errors

Plaid responseWhat to do
401 / INVALID_API_KEYSSave plaidClientId and plaidSecret at the URLs above and approve sandbox.plaid.com.
INVALID_ACCESS_TOKENSave plaidAccessToken or pass accessToken from a confirmed exchange.
ITEM_LOGIN_REQUIREDRecreate Link in update mode. Never ask for a bank password.
PRODUCTS_NOT_SUPPORTEDRecreate the Item with that product consented.

Branding

community-icon.svg is Plaid's official mark from the plaid.com header (same path as Wikimedia File:Plaid logo.svg), on Plaid black #111111. Plaid® is a trademark of Plaid Inc. This package is not affiliated with or endorsed by Plaid.

Docs

Report this listing

Log in to report this listing.