Quick Start Guide

Here's a brief guide to help you get started building with Narmi. For any questions or if you need assistance, feel free to reach out to us at support@narmi.com.

In this article:


Narmi offers the following REST APIs:

  • Narmi Application Framework (NAF) API - Use this API to interact with user data from our Online Banking platform. Execute transfers, read account data, or integrate an app extension or service for your institution's customers. Go to Setup below to get started.
  • Admin API - Use this API to build custom functionality for our Admin platform. Access data to read and write secure messages, monitor events on the platform, or feed user data into your CRM platform. Please contact support@narmi.com for setup.
  • Account Opening API - Use this API to pass account opening data from our Digital Account Opening platform, such as processing applications through a third-party service. For this API, please use your financial institution’s user acceptance testing (UAT) environment, as access to a test core banking system is needed. Contact support@narmi.com for setup.

In addition to our APIs, Narmi provides an application layer that allows you to embed an app within the Narmi online banking experience. For more information, go to Narmi Application Framework.

Setup for the NAF API

To get started building with the NAF API, you'll need access to our sandbox environment. Our sandbox environment for Online Banking is https://online.sandbox.narmi.dev/. Please email us at sandbox@narmi.com to request access.

What Is the Sandbox?

The production environment is where you launch your custom functionality. The sandbox environment is a replica of our production environment, supporting all of the same API endpoints. Applications should be tested against the sandbox environment before being used in production.

It's important to note the following differences between sandbox environment and the production environment:

  • The sandbox contains only test data and is completely separate from your production account.
  • All API endpoints use the sandbox base URL (https://api.sandbox.narmi.dev/v1/), not a production URL.
  • Actual money is not sent or received as part of test transactions.
  • Transfers may not create corresponding transactions, they remain pending indefinitely.

Note: Real financial data and personal data (such as Social Security Numbers) should never be used in the sandbox.

The sandbox is shared by other Narmi customers, so it is not an isolated test environment. If you are a third-party vendor and require testing in a specific financial institution’s UAT environment with their test core, please contact them to get access.

Access to the Sandbox

Once you request access from support@narmi.com, our team will respond with the following information:

  • Your sandbox test account login credentials
  • The Client ID of your Narmi Application Framework (NAF) application. This is not treated as sensitive and often visible in URLs or static configuration.
  • The Client Secret (Shared Secret) of your NAF application. This is a cryptographically secure character string. It is treated as sensitive and only used for secure server-to-server communication.
  • The URL of your NAF app. This is the URL that the app will use to redirect/authenticate users.

With this information, you can begin making calls to the NAF API.

Understanding App Launch

When your NAF app is loaded on Narmi's platform, a HTTP POST request is made to your specified NAF app URL. This POST request will contain some parameters in the body, including the signed_request parameter which you should decode for user information, and a signature to verify the security and authenticity of this data.

The signed_request is base64 encoded and signed with an SHA256 HMAC of your Client Secret, sometimes referred to as a JSON Web Token. You can parse this parameter like this:

  1. Split the signed request into three parts delineated by a '.' character (eg. 34k324nsfsfm.238fsdfsd.oijdoifjsidf899).
  2. Calculate the expected signature of the request, and compare it to the third part—the encoded signature.
  3. If the expected signature and signature match, decode the second part—the payload—from base64 and then decode the resultant JSON object.

This JSON object has several keys:

Name Type Description Example
exp number expiration, a Unix epoch timestamp 1291840400
iat number issued at, a Unix epoch timestamp 1516239022
aud string client id of the application “7ugpYTwyIoFkhz6bLnzQJGYUEaJGtcnrv8pfOJCb”
sub string subject, the Narmi user id “0b0b893f-9885-4789-b26d-6e879f0fc693”
user.institution_user_identifier string uniquely identifies the current user on the core “555555”
user.institution_business_identifier string uniquely identifies the current user's business on the core (if any). Is not the EIN “555556”
user.narmi_business_identifier string UUID, uniquely identifies the business to Narmi "823686a9-6412-4a3e-b1bc-79371702f7fb"

Note: If exp is greater than the current time, then the request should be considered invalid.

Make Calls to the NAF API

Once you have a valid Sandbox account and the information from our team (listed above), you can start making calls to the API. 

For the NAF API:

  1. Log into Narmi at https://online.sandbox.narmi.dev.
  2. Select your NAF app name from the right side of the page, or select Tools, then select your NAF app name.
  3. A POST request is made to the Redirect URI with an auth code in the URL parameters.
    1. Additionally, the user’s uuid can be obtained from the signed request jwt. Parse the second section (payload) using base64 url decoding and the user's uuid will be the ‘sub’ field.
  4. You will exchange the code, scope, Client ID, and Client Secret for an access token and secret specific to the user (see example curl below).
  5. The access token can be used to query the user's data. All requests to the NAF API must be signed. Refer to our API reference documentation for more information. 

Example curl:

curl -X POST https://api.sandbox.narmi.dev/v1/tokens -H 'Content-Type: application/json' -d '{"grant_type": "authorization_code", "code": "INSERT_HERE", "scope": "read write read:profile write:preferences", "client_id": "INSERT_HERE", "client_secret": "INSERT_HERE"}'

Example Code for Auth (NodeJS)

All imports can be completed with NodeJS built-ins, meaning this example requires no additional dependencies. Narmi will provide the environment information as part of your initial setup. This includes the Client ID, Client Secret, and API Root.

Import Requirements:

const crypto = require('crypto');

const { Buffer } = require('buffer');

const https = require('https');

const clientSecret = "Client Secret";

const clientId = "Client ID";

const apiRoot = "API Domain";

The following code snippet lays the groundwork for making http requests.

Build Request Helper:

async function requestSync(url, options, postBody) {

return new Promise((resolve, reject) => {

const req = https.request(url, options, (res) => {


let responseBody = '';

res.on('data', (chunk) => {

responseBody += chunk;


res.on('end', () => {



}).on('error', (err) => {



if(postBody) {






When a NAF Client receives a request from Narmi, the first thing it should do is verify that it was signed by the same Client Secret that the NAF Client is using. This allows the Client to verify the sender's identity and provides information about the sender.

Validate Signed JWT:

const decodedBody = Buffer.from(requestBody, 'base64').toString('ascii');

const requestParts = decodedBody.split("&")[0].split("=")[1].split('.');

const signedMessage = [...requestParts[0], '.', ...requestParts[1]].join('');

const hmac = crypto.createHmac('sha256', clientSecret).update(signedMessage).digest('base64url');

let payload;

if(hmac !== requestParts[2]) {

console.log("failed to validate signed jwt");


payload = JSON.parse(Buffer.from(requestParts[1], 'base64').toString('ascii'));

console.log(`validated signed jwt: ${payload}`);

After the request sender's identity is verified, use the authorization code—passed either in the request body or querystring parameter—to obtain an access token. This token will be limited to querying Narmi for the user that authorized access.

Token Exchange:

const payload = {

"grant_type": "authorization_code",

"code": code,

"scope": "read write read:profile write:preferences",

"client_id": clientId,

"client_secret": clientSecret


const response = requestSync(`${apiRoot}/v1/tokens`, {

headers: { "Content-Type": "application/json" },

method: "POST"

}, JSON.stringify(payload));

const responseBody = await response;

responseObj = JSON.parse(responseBody);

Using the token and secret obtained from the step above, you can now make requests against the NAF API on behalf of the user who authorized access. A full list of endpoints can be found here.

Get API Helper:

async function getAPI(endpoint, token, secret) {

const date = new Date(Date.now()).toISOString();

const signature = crypto.createHmac('sha256', secret).update(`date: ${date}`).digest('base64');

const sigHeader = `keyId="${token}",algorithm="hmac-sha256",signature="${signature}",headers="date"`;

const requestHeaders = {

"Authorization": `Bearer ${token}`,

"date": date,

'Content-Type': 'text/javascript',

"Signature": sigHeader


const response = requestSync(`${apiRoot}${endpoint}`, {

headers: requestHeaders,

method: "GET"


const responseBody = await response;

let responseObj;

try {

responseObj = JSON.parse(responseBody);

} catch (error) {



return responseObj;


Read Our API Documentation

For comprehensive information on our APIs, go to our API reference documentation:

Back to Get Started

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us