Skip to main content

Cash Atlas V2 API Reference

API Overview

Introduction

This document provides information on how to interact with the Nova Credit API to obtain a Cash Atlas V2 report.

The best way to get the Cash Atlas report using Nova Credit's API is to have your applicants use NovaConnect, an easy-to-use and secure JavaScript module. Visit our Quickstart guide for all details on how to get Nova Credit API credentials and integrate NovaConnect into your app or website today.

Framework and Protocol

The Nova Credit API is organized around REST. It uses resource-oriented URLs, HTTP response codes, and native HTTP functionality such as authentication and verbs. Note that our APIs are served over HTTPS; HTTP is not supported in production.

Delivery Formats

JSON is the default response format.

Endpoints

Our API host is api.novacredit.com. (See Quickstart guide for environment information.)

Our resource URL patterns are:

EndpointDescription
GET /connect/accesstokenRetrieves an access token for an applicant's Cash Atlas report
GET /connect/cash-atlas/v2/jsonRetrieves an applicant's Cash Atlas report in JSON form
GET /connect/statusRetrieves the status of an applicant's Cash Atlas report

Visit our Quickstart guide to see details on how to call these endpoints with examples.

Data Types & Formats

Data Types

TypeDescription
StringExtended character set, numbers and punctuation symbols. This includes non-ASCII language-specific characters such as ß, à, ç, é, and more (all encoded as utf8).
IntegerA rounded numerical value.
FloatA 64-bit floating decimal point format.
BoolA boolean-flag indicating true or false.
ObjectNested JSON level with more field-values.
ArrayA value or type array contains a zero or positive amount of elements. The elements can be of any type.

Data Formats

FormatDescription
Timestamp(String) UTC ISO 8601 data and time format. Full specs according to RFC 3339. Example: 1982-09-26T32:20:50.52Z
Full Date(String) UTC ISO 8601 date format. Full date format in YYYY-MM-DD. Example: 1982-09-26
Short Date(String) UTC ISO 8601 date format. Shorter format in YYYY-MM. Example: 1982-09
UUID(String) Universally Unique Identifier according to RFC 4122
URI(String) Uniform Resource Identifier according to RFC 3986
Full Version(String) Semantic versioning. http://semver.org/

Report Body

Report Structure

The Cash Atlas report response structure is as follows:

  • meta {object}
  • product {object}
  • sources {array}
  • identities {array}
  • account_details {array}
  • attributes {array}
  • scores {array}

Example of the JSON structure of the Cash Atlas report response:

{
"meta": {
...
},
"product": {
...
},
"sources": [
...
],
"identities": [
...
],
"account_details": [
...
],
"attributes": [
...
],
"scores": [
...
]
}

meta {}

Example snippet of meta in the report response:

{
"meta": {
"public_token": "ff0886a4-f3ff-11e6-bc64-92361f002671",
"user_args": "235234224",
"created_at": "2024-01-13T11:07:46.51Z",
"api_version": "2.0.0",
"nova_report_revision": "1",
"external_id": "d167c6bb-225c-461c-be63-f0bc3a1f62ea",
"status": "SUCCESS",
"substatus": "MISMATCHED_PII"
},
...
}

Information specific to the report that's been returned.

FieldFormatNotes
public_tokenUUIDThe unique identifier of this report
user_argsStringThe input of the userArgs function in NovaConnect. Can be null
created_atTimestampThe date the credit report was retrieved
api_versionFull versionThe API version used to generate this report
nova_report_revisionStringThe revision name for this report. This field will be null if this report has never been revised.
external_idStringThe unique applicant identifier of the report from your system. Can be null if it is not provided.
statusStringThe status for this report. If a report is available, the status will be SUCCESS
substatusStringThe substatus for the report. See substatuses. Can be null

product {}

Example snippet of product in the report response:

{
"product": {
"name": "Village Communities",
"product_id": "9cf178e0-760e-11e7-abf3-5da9d338ae4b",
"inquiry_type": "TENANT"
},
...
}

Details of the product the applicant applied for. Please refer to the Client-Side Integration section in the Quickstart Guide.

FieldFormatNotes
nameStringProduct name
product_idUUIDThe unique identifier for the product
inquiry_typeStringSee product inquiry_type values

sources []

Example snippet of sources in the report response:

{
"sources": [
{
"source_id": "USA_FIN",
"source_type": "BANK_TRANSACTION",
"status": "SUCCESS"
},
{
"source_id": "CONSUMER_INPUT",
"source_type": "MANUAL",
"status": "SUCCESS"
}
],
}

A list of data sources used to build the applicant's report.

FieldFormatNotes
source_idStringA human-readable identifier for the source, unique within the context of the report
source_typeStringSee source_types
statusStringThe final status for the source. See status

identities []

Example snippet of identities in the response:

{
"identities": [{
"source_id": "USA_FIN",
"first_name": "Raymond",
"last_name": "Marshal",
"full_name": "Raymond Marshal",
"emails": ["raymond@email.com"]
...
}],
...
}

The applicant's personal identity information reported from each data source.

FieldFormatNotes
source_idStringThe identifier for the source that reported the identity information. See sources
first_nameStringThe first name of the applicant
last_nameStringThe last name of the applicant
full_nameStringThe full name of the applicant
emailsArray of StringA list of emails associated to the applicant
matchingObjectSee matching

matching {}

Example identities matching field object for case where there is a full name match:

{
"matching": {
"full_name": {
"matched_sources": [
{
"source_id": "USA_FIN",
"source_record_id": "5f19d40f-3c19-4a7d-ad7b-cc28dac40c4d"
}
],
"unmatched_sources": []
}
}
}

Example identities matching field object for case where there is no full name match:

{
"matching": {
"full_name": {
"matched_sources": [],
"unmatched_sources": [
{
"source_id": "USA_FIN",
"source_record_id": "c31bf8c7-c25b-4d2c-a4bc-61f79fd46e65"
}
]
}
}
}

Information about sources which have matching and conflicting values to a particular identity.

matching is returned in an object broken out by field, only certain fields are matched between sources. If only one identity item exists, there will be no matching field. Information about matching sources is stored wrapped in the MatchingField format, which indicates where each value was sourced from.

FieldFormatNotes
full_nameObjectMatched and unmatched sources for the full name of the applicant
MatchingField {}
Example matching field object for case where there is a field match:

{
"matched_sources": [
{
"source_id": "USA_FIN",
"source_record_id": "5f19d40f-3c19-4a7d-ad7b-cc28dac40c4d"
}
],
"unmatched_sources": []
}

Example matching field object for case where there is no field match:

{
"matched_sources": [],
"unmatched_sources": [
{
"source_id": "USA_FIN",
"source_record_id": "c31bf8c7-c25b-4d2c-a4bc-61f79fd46e65"
}
]
}

An object containing information about which sources have a matching value for a field and which sources contain conflicting values for the same field. A source is an object containing a source_id and a source_record_id if there are multiple source records.

FieldFormatNotes
matched_sourcesArrayList of sources which have a value that matches this identity. See sources
unmatched_sourcesArrayA list of sources which have a value that conflicts with this identity. See sources

account_details []

Example account detail field object:

{
"account_details": [{
"source_id": "USA_FIN",
"account_id": "36139831-0a91-4d1f-bc3e-edc908a978c6",
"months_available": 6,
"owner_full_name": "John Doe",
"institution_name": "CHASE",
"account_name": "INVESTMENT ACCOUNT",
"account_type": "INVESTMENT",
"date_opened": "2015-05-01",
"truncated_account_number": "1234",
"responsibility": "INDIVIDUAL",
"last_statement_end_date": "2015-05-30",
"addresses": [
{
"address_id": "80421b7e-7918-4963-b5fb-85055c2994b7",
"address": "225 Valencia St.",
"street": "Valencia St.",
"city": "San Francisco",
"zipcode": "94103",
"state": "CA"
}
],
"current_balance": 23422,
"ach_details": [{
"routing_number": "123445",
"full_account_number": "789682736",
}],
},
...
],
}

An array with each instance containing details about an account. The array can have zero objects, and there is no upper bound.

FieldFormatNotes
source_idUUIDThe identifier for the source that reported the account details.
account_idUUIDUnique identifier for the account
months_availableIntegerNumber of months of transaction data available on the report
owner_full_nameStringFull name of the owner of the account
institution_nameStringName of institution such as Chase or Bank of America
account_nameStringName of the account within the bank
account_typeStringType of the account within the bank. See account types
date_opened*Full DateDate the account was opened
truncated_account_numberStringIf available, the last four digits of the account number
responsibilityStringSee responsibility
last_statement_end_dateFull DateEnd date of the of the most recent statement
addressesArraySee addresses
current_balanceFloatCurrent balance of the account
ach_detailsArraySee ACH details
  • Denotes that the field may not be returned in the JSON response in all cases.

addresses []

Example addresses field array:

{
"addresses": [{
"address_id": "80421b7e-7918-4963-b5fb-85055c2994b7",
"address": "225 Valencia St., San Francisco, CA 94103",
"street": "Valencia St.",
"city": "San Francisco",
"zipcode": "94103",
"state": "CA"
}],
},

Addresses is a history of contact information attached to this account. Addresses are returned in an array, can have zero objects, and there is no upper bound.

FieldFormatNotes
address_idUUIDUnique identifier for the address
addressStringThe full mailing address of the account owner
streetStringThe street address where the account owner is located
neighborhoodStringThe neighborhood where the account owner is located
districtStringThe district where the account owner is located
cityStringThe city where the account owner is located
zipcodeStringThe zip code where the account owner is located
stateStringThe state where the account owner is located

ach_details []

Example ach_details field array:

{
"ach_details": [{
"routing_number": "123445",
"full_account_number": "789682736",
}],
},

ACH Details contains the ACH Details for this account. ACH Details are returned in an array, can have zero objects, and there is no upper bound.

FieldFormatNotes
routing_numberStringRouting number of financial institution for the account. Please contact your Nova Credit account representative to enable this field
full_account_numberStringThe full account number for initiating ACH transfers for this account. Please contact your Nova Credit account representative to enable this field

attributes []

Example snippet of attributes in the report response:

{
"attributes": [
{
"name": "ASSETS_CASH_EQUIVALENT_BALANCE",
"description": "Current cash equivalent balance on assets",
"node": "ASSETS",
"source_ids": ["USA_FIN"],
"value": 3200,
"adverse_action_code": "21"
},
{
"name": "ASSETS_CURRENT_RATIO",
"description": "Current ratio on assets",
"node": "ASSETS",
"source_ids": ["USA_FIN"],
"value": 9999998,
"adverse_action_code": "25"
},
...
],
}

Attributes are analytical values derived from the underlying data in the report. attributes are returned in an array; the array can have zero objects, and there is no upper bound. Please consider an approach that permits adding and removing attributes without incurring additional integration work. It is particularly important that you discuss the mechanics of your attributes integration if it relies on a fixed ordering or maximum number of attributes.

FieldFormatNotes
nameStringThe name of the attribute
descriptionStringHuman readable description of the attribute
nodeStringSee node_type
source_idsArrayA list of IDs of the sources utilized to generate this attribute. See sources
valueNumberValue of the attribute. See value types
adverse_action_codeStringSee adverse_action_codes

Calculations

This service retrieves up to two years of transaction history for the consumer’s provided accounts. This data is grouped based on the transaction posted date and used to generate attributes. This grouping is used to determine which data points will be used to calculate an attribute that is bound by a time frame. If an explicit time frame is given, then the data used to compute the attribute will only include data points for past complete months.

For example, an attribute that calculates the average number of expense transactions over a 12 month period when the consumer completed the application on February 17, 2022 will only include data points between January 1, 2021 to January 31, 2022 inclusive.

In the event an attribute calculation results in an infinite or undefined number, such as dividing by 0, a cap value will be returned.

CalculationFormatNotes
AverageIntegerThe average value over the specified duration
MinimumIntegerThe minimum value over the node's history over the specified duration
MaximumIntegerThe maximum value over the node's history over the specified duration
TrendIntegerCalculate the slope of the values over the specified duration
SumIntegerThe sum of all values over the specified duration
RatioFloatThe ratio between two different sets of data
CountIntegerThe number of occurrences a qualification nis met over the specified duration
BooleanBooleanTrue or false
RecencyIntegerCounts the number of days that fit the given qualification over the specified duration
BalanceFloatCalculate the dollar amount balance over the specified duration. Only two places after the decimal are returned

Default Condition Values

In the case that an attribute could not be calculated, an integer value will be returned indicating one of three scenarios. See Value Types for a table on values based on type.

ConditionDescription
No usable recordsNo relevant records were found for the given node type. This typically occurs in scenarios such as when the user did not connect any accounts or no transactions were found across all connected accounts
No usable records in the categoryRecords exist for the node, but not for the attribute's sub category
No usable valuesRecords exist for the node and category, but the records do not match a constraint such as time frame

Value Types

TypeMinimum ValueMaximum ValueCap ValueNo Usable RecordsNo Usable records in the CategoryNo Usable Values
Boolean015876
Dollar Amounts-9,999,999.999,999,994.999,999,9959,999,9989,999,9979,999,996
Float-9,999,999.999999,999,994.999999,999,9959,999,9989,999,9979,999,996
Short Integer-9,9999,99949,9959,9989,9979,996
Long Integer-9,999,9999,999,9949,999,9959,999,9989,999,9979,999,996

scores []

Example snippet of scores in the Cash Atlas response:

{
"scores": [
{
"source_ids": ["USA_FIN"],
"score_type": "NOVA_SCORE_CASH_FLOW",
"score_version": "1.0.0",
"value": 850,
"adverse_action_codes": [{
"code": "35",
"description": "Insufficient information on or lack of accounts"
}]
},
]
}

Information specific to the applicant's Nova Score. scores are returned in an array, and all elements follow the same structure.

FieldFormatNotes
source_idsArrayA list of ids of the sources utilized to generate this score.
score_typeStringSee score_type
score_versionFull version
valueIntegerValue of the score
adverse_action_codesArraySee adverse_action_codes

Tables

adverse_action_codes

adverse_action_codes give information about the key factors that affect the consumer’s score. The requirement for lenders to send adverse action notices is a part of the Fair Credit Reporting Act (FCRA), a federal law that promotes accuracy, fairness, and privacy of information.

adverse_action_codes can be found in two places within the report:

Within the scores node: adverse_action_codes are returned in an array of objects. Each attribute maps to one specific adverse action code, and the adverse_action_codes array will only contain the codes that are associated with attributes found in the attributes node of the API response.

Within the attributes node: adverse_action_code is a string code as defined in the table below.

FieldFormatNotes
codeStringNumeric code between 00 and 100, exclusive. Reach out to your Nova representative to retrieve the values of each code.
descriptionStringHuman readable description

account_type

Values of the account_type field.

Value
CASH_EQUIVALENT
CHECKING
SAVINGS
INVESTMENT
MONEY_MARKET
OTHER

inquiry_type

The human-readable labels are shown when creating and viewing products in the Nova Credit Dashboard. The value column shows the values that are returned in the JSON.

Human-readable labelValue
MonitoringMONITORING
Credit CardCREDIT_CARD
Vehicle AutoVEHICLE_AUTO
Vehicle OtherVEHICLE_OTHER
MortgageMORTGAGE
PersonalPERSONAL
StudentSTUDENT
UtilityUTILITY
CommercialCOMMERCIAL
ConsumerCONSUMER
Tenant ScreeningTENANT
OtherOTHER

node_type

Select top level nodes from the report body that are associated with an attribute. At this time, not all node types may be available at the top level of the report. Certain category of attributes will belong to one of the existing node types.

ValueCategories
ASSETSCash equivalent accounts, investment accounts
EXPENSESFrom cash equivalent accounts, a transaction with a negative amount. NSFs (Non-sufficient funds) are an example
INCOMENet income, cash flow

source_type

Values of the source_type field.

ValueDescription
BANK_TRANSACTIONData was sourced from a bank connection
CONSUMER_INPUTData was manually entered by the applicant

substatus

Additional insight on certain cases that occur when fetching or parsing a report.

These substatuses may accompany a report with a SUCCESS status:

ValueDescription
MISMATCHED_PIIThere is a mismatch between the PII in the consumers input and the PII in the pulled supplier report

These substatuses may accompany a webhook with an ERROR status:

ValueDescription
MFA_REQUIRED_ON_FETCHThe bank account the user tried to connect to requires multi-factor authentication and may depend on the user's browser security settings.
INCOMPATIBLE_ACCOUNT_TYPES_SUBMITTEDThe user only submitted debt accounts (e.g. credit card).
INVALID_PREFILLS_PII_MISSINGMust provide firstName, lastName, email, and DOB or full address.
INVALID_PREFILL_ADDRESSThe address sent via prefill must be a string with max length 100 and contain a valid street address.
INVALID_PREFILL_CITYThe city sent via prefill must be a string with max length 100.
INVALID_PREFILL_DOBThe birthday sent via prefill is missing or not in YYYY-MM-DD format.
INVALID_PREFILL_EMAILThe email sent via prefill must be a valid email with max length 100.
INVALID_PREFILL_FIRST_NAMEThe first name sent via prefill must be a string less than 255 characters and contain only alphabetical, unicode, dots, apostraphes and dashes.
INVALID_PREFILL_LAST_NAMEThe last name sent via prefill must be a string less than 255 characters and contain only alphabetical, unicode, dots, apostraphes and dashes.
INVALID_PREFILL_INCOMEThe stated annual income sent via prefill must be an integer between 0 and 2147483647.
INVALID_PREFILL_PHONEThe phone number sent via prefill must be a string with max length 255.
INVALID_PREFILL_STATEThe state sent via prefill is missing or not in a valid two letter US state or territory code.
INVALID_PREFILL_ZIPThe zip code sent via prefill must a string with a valid USA zip code.

responsibility

Values of the responsibility field.

ValueDescription
INDIVIDUALThe individual is solely responsible for the account
JOINTThe individual is jointly responsible for the account

score_type

Values of the score_type field.

ValueDescription
NOVA_SCORE_CASH_FLOWThe Nova Score

Cash Atlas Report Example

This is a sample response of the Cash Atlas report. Not all possible data values are present.

{
"meta": {
"user_args": "22bbd586-12b9-4876-8ec0-d210d081f4a1|email@test.com",
"created_at": "2020-04-07T00:53:43.829Z",
"api_version": "2.0.0",
"public_token": "e3f60d3a-8a22-4940-9d1e-50f4f9878503"
},
"product": {
"product_id": "c3a37c41-7c62-11e7-8141-19157d9a48c7",
"name": "Pascoe Gardens Sandbox",
"inquiry_type": "TENANT"
},
"sources": [
{
"source_id": "USA_FIN",
"source_type": "BANK_TRANSACTION",
"status": "SUCCESS"
},
{
"source_id": "CONSUMER_INPUT",
"source_type": "CONSUMER_INPUT",
"status": "SUCCESS"
}
],
"identities": [{
"source_id": "CONSUMER_INPUT",
"first_name": "Raymond",
"last_name": "Marshal",
"full_name": "Raymond Marshal",
"emails": ["raymond@email.com"]
}],
"account_details": [{
"source_id": "USA_FIN",
"months_available": 6,
"account_id": "36139831-0a91-4d1f-bc3e-edc908a978c6",
"owner_full_name": "John Doe",
"institution_name": "CHASE",
"account_name": "INVESTMENT ACCOUNT",
"account_type": "INVESTMENT",
"date_opened": "2015-05-01",
"truncated_account_number": "1234",
"responsibility": "INDIVIDUAL",
"last_statement_end_date": "2015-05-30",
"addresses": [
{
"address_id": "80421b7e-7918-4963-b5fb-85055c2994b7",
"address": "225 Valencia St.",
"street": "Valencia St.",
"city": "San Francisco",
"zipcode": "94103",
"state": "CA"
}
],
"current_balance": 45971,
"ach_details": [{
"routing_number": "98164521",
"full_account_number": "01885674"
}]
}],
"attributes": [
{
"name": "EXPENSES_COUNT_3_MONTH_AVG",
"description": "Average count of expenses over the last 3 months",
"node": "EXPENSES",
"source_ids": ["USA_FIN"],
"adverse_action_code": "66",
"value": 10
},
{
"name": "EXPENSES_COUNT_0_50_3_MONTH_AVG",
"description": "Average count of expenses between $0 and $50 over the last 3 months",
"node": "EXPENSES",
"source_ids": ["USA_FIN"],
"adverse_action_code": "67",
"value": 9996
},
...
],
"scores": [{
"source_ids": ["USA_FIN"],
"score_type": "NOVA_SCORE_CASH_FLOW",
"score_version": "1.0.0",
"value": 850,
"adverse_action_codes": [{
"code": "35",
"description": "Current cash equivalent balance to short term balance ratio of assets"
}]
}],
}

Sandbox Environment

Refer back to the Quickstart Guide for more information about Sandbox vs. Production.

To access a Cash Atlas sandbox report, you must pass certain identifying consumer information into the NovaConnect widget. This information may be passed in directly via prefill keys. Please refer to the Quickstart Guide to learn more about prefill keys.

Bank Accounts

The following Nova Credit test user reports have been created and can be accessed by inputting the following information:

InputsDefault UserSingle Primary Account UserMulti-Account UserJoint Account UserDebt Account Linked UserNo Income User
First nameRaymondSarahMikeJasonDerekNolan
Last nameMarshalSingleManyJointDebtNoTransactions
Date of birth1995-10-011986-10-121992-05-081976-03-091984-04-121992-03-07
Email addressraymond@email.comsarah@email.commike@email.comjason@email.comderek@email.comnolan@email.com
Phone310-555-6789415-231-5348917-340-3249208-351-0093512-213-3322217-277-6633
Address456 7th Street6100 Evergreen Way915 Snover Street2213 W Montrose Avenue1105 Bowie Rd6300 N Illinois St
CityModestoEverettHoustonChicagoAustinFairview Heights
StateCAWATXILTXIL
Zip953139820377007606187877362208
Stated employerRaymond's DesignsBoeingTargetMicrosoftCharles SchwabOptional
Stated annual income1200012000073000110000135000Optional

Along with the identifying consumer information that is collected, the user will need to connect their bank account through one of our partners, Finicity, Inc or Akoya.

Finicity

Finicity provides a set of usernames and password combinations for testing purposes that can be found in the Finicity documentation. For example, selecting FinBank and using a username/password of demo/go will allow you to connect test accounts.

These users will return a SUCCESS status in the webhook.

Refer to the Finicity documentation to view alternative user ID and password combinations to trigger different Finicity states.

If testing multiple aggregators in sandbox mode, you will need to select a bank first. Please select FinBank to connect with Finicity.

Akoya

Users may also connect their bank accounts through our partner Akoya to access a Cash Atlas sandbox report. Upon loading the widget, select the test user displayed, and the appropriate report will be fetched. The test users mirror those above for Finicity.

If testing multiple aggregators in sandbox mode, you will need to select a bank first. Please select Mikomo to connect with Akoya.

Simulating Different Cases in Sandbox

Enter the following inputs as the "Last Name" of the applicant in prefills to simulate a different case.

InputsDescription
expiresoonSimulates the EXPIRED status, immediatey instead of waiting 72 hours
supplierdownSimulates the SUPPLIER_UNRESPONSIVE status

Webhooks

Webhooks are the mechanism that Nova Credit uses to inform you of core initialization and completion steps for each NovaConnect widget interaction. A session is initialized when the NovaConnect widget is opened. One session can consist of multiple suppliers, and these supplier-flow outcomes are recorded and attached to the webhook body in the history node.

We make a POST API call to the webhook callback URL that you provide. Webhooks can be managed in the Developer tab on the Nova Credit Dashboard, where you must set your callback URL and can toggle your various event subscriptions on and off. Some events or statuses are subscribed to by default.

Webhook Event Types

Each Webhook API call will contain one of the event types listed below in the JSON body:

Event TypeDescription
VISITA single NovaConnect widget interaction, which can consist of multiple suppliers. Only one terminal status outcome is sent per widget open; other supplier-flow outcomes are recorded and attached to the webhook in the history node
REGENERATED_VISITOnly occurs for reports that have been regenerated. This event type also includes a novaReportRevision in the webhook body.

Webhook Status Codes

Each Webhook API call will contain one of the status codes listed below:

StatusDescriptionTerminal Status?Report Available?
PENDINGA visit has been initialized upon opening the NovaConnect widget
SUCCESSThe data source has successfully provided information on the applicant
EXPIREDThe visit has expired before the applicant was able to complete the flow. This will be sent if no completion 72 hours after initial widget opened
ERRORAn error occurred and the Cash Atlas Report could not be compiled. If there isn't a detailed substatus, send a message to your Nova Credit Representative with the publicToken
SUPPLIER_UNRESPONSIVEThe applicant has encountered a data supplier outage while going through the widget. They may need to go through NovaConnect again at a later time

Webhook Body

Webhook Body KeyDescription
eventTypeEvent Type (see event type table above) corresponding to this webhook
statusStatus (see status code table above) corresponding to this webhook
substatusA more detailed status. See substatus types
publicTokenUnique UUID associated with this status, which can be used to retrieve the Nova Credit report
externalIdOptional unique identifier passed in by the Nova Credit customer (you) with this application. This key will only be present if externalId was passed in
userArgsOptional string passed in by the Nova Credit customer (you) with this application. This key will only be present if userArgs was passed in
eventIdUnique ID for the webhook
eventCreatedTimeWebhook event timestamp
novaReportRevisionOnly included for webhooks with the REGENERATED_VISIT eventType. Refers to the revision number of the report
historyAn array containing 1 or more objects, containing data on all of the statuses an applicant has reached within one Cash Atlas widget instance, sorted by most recent to least recent
history.eventTypeEach history object will have a SUPPLIER event type
history.companyCodeData supplier for this history object
history.dateAttemptedTimestamp marking when this corresponding history object was begun
history.statusStatus (see status code table above) corresponding to this history object
history.substatusA more detailed status. See substatus types

Note that the status will be informed by the most recent supplier event status.

Example:

{
eventType: 'VISIT',
status: 'SUCCESS',
publicToken: '6b986690-458b-11e7-98fb-a71570ea65a6',
externalId: '25ad7063-fe76-437a-b4d8-3662ba4cc9c7',
userArgs: '235234224',
eventId: '028d9354-3991-46c4-97df-bd6c2ff09733',
eventCreatedTime: '2019-09-26T33:15:23.17Z',
history: [
{
eventType: 'SUPPLIER',
status: 'SUCCESS',
companyCode: 'USA_FIN',
dateAttempted: '2019-09-26T19:20:00.00Z' // newest timestamp
},
{
eventType: 'SUPPLIER',
status: 'PENDING',
companyCode: 'USA_FIN',
dateAttempted: '2019-09-26T19:18:00.00Z' // oldest timestamp
}
]
}

Webhook Failures

When a webhook fails we retry posting with an exponential increase in the time between each attempt. For example, the first retry happens after 1 second, the second after 2 seconds etc.

Number of AttemptsTime Until Retry if Unsuccessful
11 second
22 seconds
34 seconds
48 seconds
......

This strategy allows for several retries within a few minutes but expands to daily retries in the case of an outage, allowing customers to restore before receiving the callback. However, if a callback is still unsuccessful after one week we do not continue retrying.

For more information, please visit the server integration section in our Quickstart Guide.

Webhook Signature

Nova Credit optionally signs webhook payloads in order to allow for trust verification of inbound webhook requests.

When configured, the webhook request will contain these additional headers:

HeaderValue
X-Timestamptimestamp of request generation
X-Nova-SignatureSHA256 HMAC digest of request timestamp and payload, period-delimited. Your Webhook Signatures Secret Key is found under the Webhooks section on the Developer tab of your Nova Credit Dashboard.

Please contact your Nova Credit account manager to enable this feature.

Example verification of signature:

const crypto = require('crypto');

const signature = req.get('X-Nova-Signature');
const timestamp = req.get('X-Timestamp');

const checkPayload = `${timestamp}.${JSON.stringify(req.body)}`;
const checkDigest = crypto.createHmac('sha256', '< webhook secret key >')
.update(checkPayload)
.digest('base64');

return crypto.timingSafeEquals(signature, checkDigest);

For more information, please visit the server integration section in our Quickstart Guide.

Error Codes & Responses

At Nova Credit, we distinguish between two status message deliveries:

  1. Delivered by Nova Credit to the webhook
  2. If you call a resource endpoint Nova Credit provides a status in the response

Resource Endpoint Errors

When an error occurs while calling the endpoints the Nova Credit servers send back a JSON object with the following format:

{
"error": "UNKNOWN_CUSTOMER",
"terminated": true,
}

Error Codes

The Nova Credit endpoints return the following HTTP status codes and error messages:

CodeTextDescription
200-Everything went well and the requested resource is either in the body or in the generic text field depending on the content-type
400MALFORMED_HEADERSThe request headers are incorrectly formatted
400MISSING_INPUTAn input is missing that the endpoint expected
408REQUEST_TIMEOUTThe request timed out
403UNKNOWN_CUSTOMERThe public_id or client_id Nova Credit received in the request from is not recognized
403UNAUTHORIZEDThe client_id and secret_key combination is not recognized. Please email support via support@novacredit.com
403ORIGIN_UNAUTHORIZEDThe origin of the request is not whitelisted on the Nova Credit servers for CORS
401EXPIRED_TOKENThe access_token you're sending in the request headers has expired. Please request a new one
404INVALID_EXTERNAL_IDThe external ID is not valid
400INVALID_PUBLIC_IDThe public ID is not valid
404INVALID_TOKENThe public_token or access_token is not valid for reasons other than expiration
500INTERNAL_ERRORSomething went wrong. Please send a note to support@novacredit.com with additional details so we can investigate

Bank Statements Beta

Bank statements for Cash Atlas is a new feature that is currently in beta, allowing your applicants to submit transaction data using their 4 most recent statements. If you are interested in trying it out, please reach out to your Nova Credit representative for more details.

Report Body

When bank statements are submitted, Cash Atlas reports include the standard nodes as described above plus an additional top-level array:

  • document_uploads {array}

document_uploads []

The document_uploads array contains information about each bank statement file uploaded by the applicant and used as a source for the Cash Atlas transaction analysis.

{
"document_uploads": [
{
"document_upload_id": "0236cf90-04df-11f0-88c8-813899895a3e",
"source_filepath": "d63ddc84-a078-4aad-bc7d-a3ec84b60b94/62f6cc64-91cf-4f5a-9116-67c47d79ceaf.pdf",
"irregularity_detection": {
"status": "NOT_DETECTED",
"reasons": [],
"version": "3.1",
"genuine_pdf": true
}
},
{
"document_upload_id": "023f8220-04df-11f0-88c8-813899895a3e",
"source_filepath": "d63ddc84-a078-4aad-bc7d-a3ec84b60b94/3a02a218-d5a9-4ac8-b633-6fa4a5042459.pdf",
"irregularity_detection": {
"status": "NOT_DETECTED",
"reasons": [],
"version": "3.1",
"genuine_pdf": true
}
},
{
"document_upload_id": "024a9350-04df-11f0-88c8-813899895a3e",
"source_filepath": "d63ddc84-a078-4aad-bc7d-a3ec84b60b94/7b91cc32-e4f8-4d2b-9c45-8d3579a61c23.pdf",
"irregularity_detection": {
"status": "NOT_DETECTED",
"reasons": [],
"version": "3.1",
"genuine_pdf": true
}
},
{
"document_upload_id": "0255b480-04df-11f0-88c8-813899895a3e",
"source_filepath": "d63ddc84-a078-4aad-bc7d-a3ec84b60b94/9f4e2d15-b367-4c91-a8d2-ef298c4a9b76.pdf",
"irregularity_detection": {
"status": "DETECTED",
"reasons": [
{
"reason": "No Transaction Presented",
"severity": "High Risk"
},
{
"reason": "Unusual Document Source Detected",
"severity": "High Risk"
}
],
"version": "3.1"
}
}
]
}
FieldFormatNotes
document_upload_idStringA unique identifier for the uploaded document
source_filepathStringThe filepath to access the uploaded document
irregularity_detectionObjectSee irregularity detection below
irregularity_detection {}

If Irregularity Detection is enabled, this node will contain details about any irregularities detected.

FieldFormatNotes
statusStringSee irregularity detection status values
reasonsArraySee irregularity detection reasons below
genuine_pdfBoolean or nullTrue only if document is exceptionally genuine, not provided otherwise
versionStringThe version of the fraud algorithm used to generate the results
irregularity detection reasons []

Specific reasons supporting the provided irregularity_detection status.

FieldFormatNotes
reasonStringSee irregularity detection reason values
severityStringSee irregularity detection severity values

Sources

Bank statement reports introduce a new source ID:

ValueDescription
OCROLUSData was sourced from uploaded bank statements processed by Ocrolus

Example source in the report response:

{
"sources": [
{
"source_id": "OCROLUS",
"source_type": "BANK_TRANSACTION",
"status": "SUCCESS"
}
]
}

Account Details

For bank statements, the account_details node includes an additional field:

FieldFormatNotes
last_statement_end_dateFull DateThe end date of the most recent statement provided by the applicant

Example account details with statement date:

{
"account_details": [
{
"source_id": "OCROLUS",
"account_id": "21490d35-dddb-4ff1-adf8-4b98328bde64",
"owner_full_name": "JILL S COFFEE",
"institution_name": "CHASE",
"account_name": "488083738759 CHASE CHECKING",
"account_type": "CASH_EQUIVALENT",
"responsibility": "INDIVIDUAL",
"last_statement_end_date": "2025-03-15",
"addresses": [
{
"address_id": "7d07905b-429d-4d85-9f9b-a1be0a617961",
"address": "74 Prospect Park West Park Slope, New York, NY, 11215, US",
"street": "74 Prospect Park West Park Slope",
"city": "New York",
"zipcode": "11215",
"state": "NY"
}
],
"ach_details": []
}
]
}

Tables

irregularity_detection_status

Values of the status field in the irregularity_detection node.

ValueDescription
NOT_DETECTEDNo irregularities were detected on the file
DETECTEDIrregularities were detected on the file
REVIEWMinor fraud indications detected, manual review recommended

irregularity_detection_reason

Values of the reason field in the v3 irregularity_detection reasons node.

Value
Serial Fraud Detected
Edited Content Detected
Suspicious Modification Detected
Browser/Os Processed
No Textual Document Detected
Unusual Document Source Detected
Screenshot Detected
PDF/Image Converted
Suspicious Format Detected
Editing Software Detected
Others

irregularity_detection_severity

Values of the severity field in the v3 irregularity_detection reasons node.

Value
High Risk
Medium Risk
Low Risk

Accessing Uploaded Statement Files

Document uploads in a report include a source_filepath that can be used to retrieve the original bank statement file. These files can be downloaded by making a GET request to the Cash Atlas file endpoint using the same accessToken used to get the report and the publicToken provided by the webhook. Make sure to encode the accessToken using base 64.

GET https://api.novacredit.com/connect/cash-atlas/v2/files/<filepath>

Required headers

  • X-PUBLIC-TOKEN The unique identifier of the report you are retrieving, provided to you via webhook.
  • Authorization Bearer Auth, containing the strict base-64 encoded string of the valid accessToken you previously retrieved.

Possible responses‍‍

  • 200 (OK) Bank statement file is found and returned.
  • 403 (Forbidden) Unauthorized request.
  • 400 (Bad Request) Malformed request, headers or missing required parameters.
  • 404 (Not Found) File was not found. This could be because the X-PUBLIC-TOKEN was not correct, or because the filepath is incorrect.

Example request

require('request').request(
{
url: 'https://api.novacredit.com/connect/cash-atlas/v2/files/d63ddc84-a078-4aad-bc7d-a3ec84b60b94/62f6cc64-91cf-4f5a-9116-67c47d79ceaf.pdf',
method: 'GET',
encoding: null,
headers: {
Authorization: `Bearer ${new Buffer('<valid access token>').toString('base64')}`,
'X-PUBLIC-TOKEN': '8ac61af8-65ae-4d78-8e02-9f10cbc0adf0',
},
},
function (err, res, body) {
fs.writeFile('bank_statement.pdf', body, function (err) {
if (err) {
throw err;
}
console.log('DONE');
});
},
);

Sandbox Testing

To test the Bank Statements feature in sandbox mode, you can supply at least one bank statement with a filename that matches against a known test user:

FilenameOutcome
jill.pdfValid statement with normal transaction history
jill_detected.pdfStatement with irregularities detected

Changelog

We're always working to improve the Nova Credit platform! Here's a snapshot of API features we're shipping and bugs we're squashing.

Changelog History

March 2025

  • Added Bank Statements (Beta) feature details

February 2025

  • Fixed bug with identities[].full_name: If source has first_name and last_name but no full_name, we will now populate full_name with a concatenated first_name last_name

November 2024

  • Added error substatuses for prefills
  • Added external_id to report meta

October 2024

  • Added status and substatus to the meta object in the JSON response

September 2024

  • Added the error substatus INVALID_PREFILL_DOB
  • Added EXPIRED status for Webhooks and way to simulate in sandbox

July 2024

  • Added instructions on testing the SUPPLIER_UNRESPONSIVE status
  • Added REGENERATED_VISIT to webhook eventType
  • Added Webhook Signature section
  • Denoted that date_opened may not always be present in the JSON response

June 2024

  • Added Changes from Cash Atlas v1 to Cash Atlas v2 section in Changelog

Changes from v1 to v2

View V1 Docs.

  • Additions/Modifications:

    • Created an account_details node which includes data from the old bank_transactions[].account_details and bank_transactions[].summary nodes
    • Moved account_details.routing_number and account_details.full_account_number into a new node named account_details.ach_details
    • Created scores node that will hold our Nova Score Cash Flow.
    • ENUM modifications:
      • Renamed the BUREAU_UNRESPONSIVE status to SUPPLIER_UNRESPONSIVE
      • Created a new MISMATCHED_PII substatus that can accompany some SUCCESS visits where the consumer input differs from the received account_details
    • Added source_id to account_details node
  • Removals:

    • Removed /connect/cash-atlas/<version>/files/<filepath> endpoint
    • Removed Supplier Webhooks
    • Removed references to Paystub Verification and USA_ATOMIC
    • Removed middle_name, other_names and telephones from identities node
    • Removed oldest_transaction_date from account_details node
    • Removed employments node
    • Removed bank_transactions node including all subnodes except for account_details and summary which were moved into the new account_details node at the top-level of the JSON (see Additions above)
    • Removed expenses node
    • Removed income node including all subnodes
    • Removed metrics node
    • Removed adverse_action_codes node
    • Removed account-level attributes which used to exist in bank_transactions[].account_details[].attributes
    • Removed info text around attributes being available for select customers only. All Cash Atlas V2 customers will receive an attributes node.
    • Removed DEBT from the node_type table
    • ENUM removals:
      • Removed STATUSES
        • SKIPPED
        • NOT_AUTHENTICATED
        • NON_CONTRIBUTING_APPLICANT
      • Removed a few SUBSTATUSES that usually accompany SUCCESS visits
        • ACCOUNT_TOO_NEW
        • NO_RECENT_USABLE_INFORMATION
        • NO_USABLE_INCOME_INFORMATION
      • Removed a couple SUBSTATUSES that usually accompany ERROR visits
        • INVALID_DATE_FORMAT_SUBMITTED
        • INCOMPLETE_INFORMATION
      • Removed a SUBSTATUSES that usually accompany NON_CONTRIBUTING_APPLICANT visits
        • COAPPLICANT_GUARANTOR_PROVIDING
      • Removed EMPLOYMENT and PAYROLL from source_type enum
    • Reworked the Sandbox Mode section