X Enterprises
fastify-xplaid

accounts.getBalance

Get real-time account balances for a Plaid Item — makes a fresh call to the financial institution, not cached.

accounts.getBalance

Fetches live balance data directly from the financial institution. Unlike accounts.get, which returns the last-known balance snapshot, getBalance makes a real-time network call so the available and current figures are always fresh. Use this for transfer pre-checks or any UI that must display up-to-the-minute balances.

Signature

fastify.xplaid.accounts.getBalance(
  accessToken: string,
  options?: {
    accountIds?: string[]
  }
): Promise<{
  accounts: PlaidAccount[]
  item: PlaidItem
  requestId: string
}>

Params

NameTypeRequiredDescription
accessTokenstringYesThe Item's permanent access token.
options.accountIdsstring[]NoRestrict results to specific account IDs. Omit to return all accounts.

Returns

Promise<{ accounts: PlaidAccount[], item: PlaidItem, requestId: string }>

Each PlaidAccount in the accounts array includes:

FieldTypeDescription
account_idstringStable Plaid account identifier.
namestringAccount name as it appears at the institution.
typestringAccount type: "depository", "credit", "investment", etc.
subtypestringAccount subtype: "checking", "savings", "credit card", etc.
maskstring | nullLast four digits of the account number.
balances.availablenumber | nullAvailable balance (funds available to spend or withdraw).
balances.currentnumberCurrent posted balance.
balances.limitnumber | nullCredit limit (credit accounts only).
balances.iso_currency_codestringCurrency code, e.g. "USD".

Throws

  • [xPlaid] accessToken is required and must be a non-empty string — when accessToken is missing or empty.
  • Plaid API errors wrapped via wrapPlaidError — shape: { message, statusCode, plaidError }.
  • PRODUCTS_NOT_SUPPORTED Plaid error if the balance product was not enabled for this Item.

Examples

Basic — display balances

const { accounts } = await fastify.xplaid.accounts.getBalance(accessToken);

const balances = accounts.map((a) => ({
  name: a.name,
  available: a.balances.available,
  current: a.balances.current,
  currency: a.balances.iso_currency_code,
}));

Realistic — balance dashboard route with error handling

fastify.get("/dashboard/balances", async (request, reply) => {
  const item = await db.plaidItems.findFirst({ where: { userId: request.user.id } });
  if (!item) return reply.status(404).send({ error: "No linked account found" });

  try {
    const { accounts } = await fastify.xplaid.accounts.getBalance(
      decrypt(item.accessToken)
    );

    return accounts.map((a) => ({
      id: a.account_id,
      name: a.name,
      type: a.type,
      subtype: a.subtype,
      mask: a.mask,
      available: a.balances.available,
      current: a.balances.current,
      currency: a.balances.iso_currency_code,
    }));
  } catch (error) {
    if (error.plaidError) {
      const { error_type, error_code } = error.plaidError;
      if (error_type === "ITEM_ERROR") {
        // Token needs re-auth — signal the client to re-launch Link in update mode
        return reply.status(428).send({ error: "reauth_required", error_code });
      }
      request.log.error({ error_code, error_type }, "Plaid balance fetch failed");
      return reply.status(error.statusCode ?? 500).send({ error: error.message });
    }
    throw error;
  }
});

ACH transfer pre-check

async function hasSufficientFunds(accessToken, accountId, amountCents) {
  const { accounts } = await fastify.xplaid.accounts.getBalance(accessToken, {
    accountIds: [accountId],
  });
  const availableBalance = accounts[0]?.balances.available ?? 0;
  // Plaid returns balances in dollars — convert cents for comparison
  return availableBalance * 100 >= amountCents;
}

See Also

AI Context

package: "@xenterprises/fastify-xplaid"
note: This page is an alias/overview — see accounts-get-balance.md for the primary docs
method: fastify.xplaid.accounts.getBalance(accessToken, options?)
Copyright © 2026