clock 8-minute read calender Rel. 4.0.1 | updated Dec. 10, 2024

Get immediate confirmation of account ownership

Key takeaways

  • Use API v2 for the latest enhancements and for more meaningful results.
  • Help reduce fraud by validating the owner of an account, matching the intended counterparty before moving funds.
  • Help minimize returns by confirming an account is open and valid before transacting with the account.
  • Comply with Nacha rules requiring account validation for web debits in real time without need for prenotes or micro-deposits.
  • Help save time with immediate validation for account inquiries.

Try it yourself

If you want to use our Account Validation API, speak with a Payments Advisor to learn more.

Contact us

With the Account Validation API, you can inquire about an account and a get real-time confirmation about the status of the account and whether the ownership data matches. By real-time, we mean like 5 seconds or less on average. This is a far contrast to pre-notes or micro deposits which can take days and possibly accrue cost if there a return involved for illegitimate accounts.

This service is priced per each successful transaction. Speak with your Embedded Banking Payments Advisor to learn more. You can see our Getting Started Guide to learn more about how to partner with KeyBank APIs.

See the v2 specs

Account validation is simple. You send an inquiry request to evaluate the account information from a draft account item, typically a check or an ACH item. KeyBank completes Account Ownership Authentication (AOA). This is an API service that enables payment processors to verify the information matches data in the National shared Database (NSD). It reviews the payer’s name, address, and other elements and responds with whether the payer is authorized to transact on the account. 

Account validation flow steps for submitting a request and getting a response.

When the Account Validation API reviews the request, the case, spacing, and punctuation are ignored when matching values. The response returns codes that inform you of whether or not this is a genuine account. Codes returns include:

  • a condition code telling you the state of the account owner data provided.
  • match codes that confirm the data is the found or not with a Y (Yes), N (No), C (Conditional), or U (Unknown).
  • an overall match score is generated based on number of data points that did and did not match. If most of the match codes are Y, you will have a higher match score.

To send a valid request, the following parameters are required:

  • secondaryID: This is a unique identification assigned by KeyBank to each client of the API and identifies which client is making the call. This is not the same as your client credentials used to get an access token.
  • routingNumber: The routing number of the bank account holder.
  • accountNumber: The bank account number of the account owner.

Search by...

You can search by a person or a business, but not both.

A personal inquiry validates an account with the owner's full name. (firstName + lastName)

A business inquiry validate an account with a business name, company name, or the full name of the individual. (businessName)

More is better

To include more data points for verification, you can use the AcctOwner object to inquire about a personal or business account. The information you provide in the request is reviewed for a match in the database. If you do not enter any information in a field, it will not be reviewed for a match and returns as a blank field. The more information you provide, the better the validation when comparing data with the NSD. 


It is up to you and your business how you weigh the response codes returned and what it says about the validity of the account. KeyBank can only recommend guidelines on how to assess and interpret the response.

With the Account Validation API response, we recommend reviewing the following items in this sequence:

01

Check to see if the request was a good one

The response starts with the errorCode, a three-digit code that lets you know if there are any errors present with the account information from a draftable account item or the evaluation of the request message fields.

If no errors are present, this field is filled with three zeroes. If you do not get magical three zeroes, go to the Account Validation API document to view specific error handling codes.

02

Review the account status

The account status object (AcctStatus) returns a three-digit code for the current condition of the bank account. The primary status code (primaryStatusCode) indicates if the account is open, closed, or not found. Each code has an associated message with additional details (primMessage).

CodeMessage
000Routing number and account number combination cannot be found
012Account is closed
096No positive or negative information in known about the account
099Account is present in the participant’s master account file and has no other status code
699Open valid account for a non-participant

03

See if there are any conditions associated with the account information

Condition codes reflect the state of the account owner data provided. When a condition code is returned in the response payload (conditionCode), users may still receive a partial response, such as an account status.

Condition codes

CONDITION CODEDESCRIPTION
000Normal response - no system errors
300Valid routing number, but not a participant
301Valid participant, but not an account owner authentication contributor
302Valid participant, but account owner authentication data is unavailable
304No name field populated - first, last, or business name
396No known information for the account number
900/901No account owner response requested or provided

04

Review how much of the information matched

Review the overall match score (overallMatchScore) to see if the account validity is within acceptable limits. The overall match score is calculated on a scale of 1 to 100. This score is generated based on number of data points that did and did not match. If most of the match codes are Y, you will have a higher match score. If you have data points that return a C for a partial match or a N for no match, it will reduce the match score. Typical threshold recommendation for match score approval is 81 and above.

The system reviews the data points provided so the more details you provide in your inquiry, the better the analysis. Small discrepancies like incorrectly spelled words or the wrong phone number can affect the match score. Remember, case, punctuation, and spacing are ignored when verifying data. Review the AcctOwner attributes provided in the request and responds with if they match the data in the NSD.

05

Dig into the details

The AcctOwner response object can contain several fields that end in "Match". Each of these match fields contains a single-character code that signifies whether or not an account owner element was found. You can get a confirmation of Y (Yes), N (No), C (Conditional), or U (Unknown).

Match codes

CODEDESCRIPTIONApplies to match fields
YClose or exact matchfirstNameMatch, lastNameMatch, middleNameMatch, namePrefixMatch, nameSuffixMatch, stateMatch, ssnMatch (if the last four digits are provided in the request), idType, idState
NNo match
CConditional matchnameMatch, businessNameMatch, addressMatch, cityMatch, zipCodeMatch, homePhoneMatch, workPhoneMatch, ssnMatch (if nine digits are provided in the request), dobMatch, idNoMatch
UNo identifying data is available

Applies to all fields

If you get a U with the businessNameMatch it could indicate that the routing and account numbers have been found in the database, but there is no business name associated with the account.


  • All requests require the secondaryId provided during KeyBank onboarding, routing number, and an account number.
  • If this is a personal inquiry, at a minimum search by accountNumber and routingNumber with firstName and lastName.
  • If this is a business inquiry, at a minimum search by accountNumber, routingNumber, and businessName.

Request

Response

"accountValidationRequest": {                                   
  "AOARequest": {
    "Inquiry": {
      "serviceType": "Owner"
      "secondaryID": "KeyCli01",
      "additionalID": "",
      "routingNumber": "122199983",
      "accountNumber": "89455",
      "amount":"50",
      "serialNumber": "",
      "AcctOwner": {
        "firstName": " Paul",
        "lastName": "Wilson ",
        "middleName": "V",
        "namePrefix": "Mr",
        "nameSuffix": "Jr",
        "businessName": "Bizness by Paul",
        "addressLine1": "206 GOODWIN ST",
        "addressLine2": "",
        "city": "MERRIT",
        "state": "MI",
        "zipCode": "49667",
        "homePhone": "5555551234",
        "workPhone": "5555561234",
        "ssn": "9999",
        "dob": "19730801",
        "idType": "2",
        "idNo": "6788",
        "idState": "AL"
       },
      "Client": {
        "ClientDt": "2022-03-04",
        "ClientTime": "14:45:05",
        "UserDef": "123xyz"
       }
     }
   }
"accountValidationResponse": {
  "AOAResponse": {
     "Result": {
        "errorCode": "000",
        "systemRecordId": "5934871120174384",
        "primaryId": "TROM122101",
       "secondaryId": "KeyCli01",
       "additionalId": "",
       "routingNumber": "122199983",
       "accountNumber": "89455",
       "feeAttrib": "HH",
       "amount":"50",
       "serialNumber":"",
    "AcctOwner": {
       "conditionCode": "000",
       "nameMatch": "Y",
       "firstNameMatch": "Y",
       "lastNameMatch": "Y",
       "middleNameMatch": "Y",
       "namePrefixMatch": "Y",
       "nameSuffixMatch": "Y",
       "businessNameMatch": "Y",
       "addressMatch": "Y",
       "cityMatch": "Y",
       "stateMatch": "Y",
       "zipCodeMatch": "Y",
       "homePhoneMatch": "Y",
       "workPhoneMatch": "Y",
       "ssnMatch": "Y",
       "dobMatch": "Y",
       "idTypeMatch": "Y",
       "idNoMatch": "Y",
       "idStateMatch": "Y",
        "overallMatchScore": "100"
      },
"AcctStatus": { "primaryStatusCode": "099", "primMessage": "Open Valid" }, "Client": { "clientDate": "2022-03-04", "clientTime": "14:45:05", "userDefined": "123xyz" } } } }

What to expect

The data provided in the request is compared to the NSD. After evaluation, you get a response that indicates if there is a match or any discrepancies.

Review the response and interpret the information according to your needs and business rules. You can consider the response data in your decision-making process, along with other risk management information.


What's next?