Link Search Menu Expand Document

Encrypt U.S Banks in your applications

This guide will quickly enable you to be compliant with new Nacha encryption rules.

Your customer’s bank information is as sensitive as their credit card data, and needs to be stored with the same care. Encrypting this data takes a strong encryption pattern, including a KMS, key rotation, multiple encryption keys, access controls, and so much more.

In this guide, we will show you how to take an existing API and use Basis Theory to safely store the bank data while retaining the exact application functionality.

If you’d like to follow along with this guide jump right into the code - Find it here!

Table of contents

  1. The existing application
    1. package.json
    2. app.js
  2. Install basis-theory-js
  3. Initialize basis-theory-js
  4. Secure your bank data
  5. Retrieve and return the raw data
  6. Optional: Add an endpoint to return masked data
  7. Wrap up
  8. Watch the video guide

The existing application

Below is an existing Node.js application that is currently storing bank data in memory, this will be used as our foundation as we update to more securely store the bank data.

(Note: this is only to simplify the guide, the same process will work when storing in a database).


Our simple package.json, only has two dependencies to start. express allows us to quickly create an HTTP API, and nodemon allows us to have our nodejs application restart automatically.

  "name": "bank-data",
  "description": "",
  "version": "1.0.0",
  "author": "Basis Theory",
  "scripts": {
    "start": "nodemon app.js"
  "dependencies": {
    "express": "^4.17.1"
  "devDependencies": {
    "nodemon": "1.18.4"


Our application simply allows a U.S. Bank Account to be sent into the system, stored in memory, and retrieved back. (Even though our example doesn’t show them, your systems will most likely have authentication, databases, etc.)

const express = require('express')
const app = express()
const port = 3000

// simple storage for this example, this is most likely a DB in your system
let account = {};

// returning the raw bank information
app.get('/get', async (req, res) => {

// storing the bank information'/create', async (req, res) => {
    const {accountNumber, routingNumber} = req.body;

    account = {accountNumber, routingNumber};


// starting up your API server
app.listen(port, async () => {
    console.log(`Example app listening at http://localhost:${port}`)

Install basis-theory-js

To start, you’ll need a new Private Application with the token:bank:create and token:bank:read:high permission. Click here to create one.

First, you’ll need to install the basis-theory-js npm module

    npm install @basis-theory/basis-theory-js --save

Initialize basis-theory-js

Next, we will need to initialize an instance of BasisTheory and store a reference to be used later:

let basisTheory; // top of your file

// ...

app.listen(port, async () => {
    basisTheory = await new BasisTheory().init("<YOUR API KEY>");

    console.log(`Example app listening at http://localhost:${port}`)

Secure your bank data

With your initialized BasisTheory, your system can securely store bank information with Basis Theory and store a reference to the data within your database:'/create', async (req, res) => {
    const {accountNumber, routingNumber} = req.body;

    const bankToken = await basisTheory.tokens.create({
      type: 'bank',
      data: {

    account = bankToken;

    res.send("Bank token created \n");

To test that you’re now storing this information, you can run this curl command:

curl --location --request POST '' \
--header 'Content-Type: application/json' \
--data-raw '{
    "routingNumber": "021000021",
    "accountNumber": "1234567891099"

Retrieve and return the raw data

After we’ve stored the information with Basis Theory, we will only be storing a reference to the raw bank account information. With that in mind, we will alter our /get endpoint to retrieve using our token:bank:read:high permission which grants us access to the raw bank data and return it from our API:

app.get('/get', async (req, res) => {
  if (!account) {
    return res.status(404).send();

  const bankToken = await basisTheory.tokens.retrieve(;

  return res.send(JSON.stringify( + "\n");

To test you’re retrieving the raw data from your updated endpoint:

(keep in mind: every time the sample app restarts you’ll need to call /create)

curl --location --request GET ''

/// { "routingNumber": "021000021", "accountNumber": "1234567891099" }

Success! You are now securely storing your data with Basis Theory (who will manage the encryption and keep the data safe on your behalf)!

Optional: Add an endpoint to return masked data

Your system may now be safely storing bank information, but how do you make your systems even safer?

Basis Theory by default returns a tokenId and masked bank information back to your system when creating a bank token, so you’re able to store and use this non-sensitive data while letting Basis Theory hold the raw sensitive data. Storing tokenIds or presenting masks to end users allows your systems to ONLY have direct access to non-sensitive data! The raw decrypted bank account data can be retrieved from Basis Theory only when you absolutely need it and only by applications that are explicitly granted access to this raw data.

Below is a new endpoint, showing how you can return the masked data stored in your system:

app.get('/get_mask', (req, res) => {
    res.send(JSON.stringify( + "\n");

To test you’re retrieving the masked data from your new endpoint:

(keep in mind: every time the sample app restarts you’ll need to call /create)

curl --location --request GET ''

/// { "routingNumber": "021000021", "accountNumber": "XXXXXXXXX1099" }

Wrap up

You’re now able to quickly update your existing systems to encrypt and safely store bank data with Basis Theory, you may now be asking “what’s next?”

See it in action

Want to see the final result? Find it here!

Watch the video guide