Account Validation v2

clock 4-minute read calender 2.0.0 | updated Aug. 07, 2024

Validate an account and its owner with confidence

Before you begin

All KeyBank APIs require certificates, user credentials, and certain permissions. Check out our Getting Started Guide to learn more.

Use the Account Validation API to validate an account and its owner with confidence. This API evaluates account owner data through an inquiry request and response process.

Make a request

When you submit a request to the Account Validation API, the data in that request is compared to information in the National Shared Database. The National Shared Database is the financial industry's leading source of up-to-date, collaborative financial data. Results from the database comparison are evaluated and then returns a response to you in real time, verifying the account owner status quickly.

Request requirements

When you submit a request, in addition to your authentication credentials, you must provide:

  • The account number of the person or business you want to validate. (accountNumber)
  • The routing number for the financial institution of the person or business. (routingNumber)
  • Set the validation type to Owner to request for owner status and validation. (serviceType).
  • An ID provided during KeyBank onboarding that is a secondary authentication method for the call besides the access token. This is not the same as your client or consumer ID. (secondaryId)

Interpret the response

Results from the database comparison are evaluated and then returns a response to you in real time, verifying the account owner status quickly. The following response rules apply for all fields:

  • All fields included in the request will be matched against the database.
  • Case, spacing, and punctuation are ignored.
  • The account data matched in the database is determined based on the account number (accountNumber) and routing number (routingNumber) in the request.
  • Account matching will be performed only if a request contains the person's full name (firstName and lastName) OR the name of the business (businessName).

Result codes

Account Validation responses include a variety of codes and classifications to help you assess if the account is legitimate or not. Refer to the Account Validation User Guide to help decipher codes like these:

  • errorCode: Three-digit code about system errors. If there are no errors, you receive three zeros (000).
  • conditionCode: Three-digit code about the state and validity of account ownership.
  • primaryStatusCode: Three-digit code for account status.
  • accountOwnerResponse object: Account owner field matching showing a Y (Yes), N (No), C (Conditional), or U (Unknown).

Loads of codes

There are some codes you may need help with deciphering. Look at our Data values or if your code is part of an error message, look at our error handling section.

get /accounts/validations/v2/healthCheck

Verify you can connect to the API service. A bearer token is required.

NAMETYPEDESCRIPTION
StatusoptionalstringStatus of the health check response.
SourceoptionalstringOrigin of the system response can be 'Gateway' or 'Roundtrip'. Roundtrip returns a response from the farthest system involved.
TimestampoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) of response from the API service.
ClientIpoptionalstringClient IP address the gateway receives from the request.
X-Forwarded-ForoptionalstringSequence of IP addresses for systems between the client and the gateway.

Response example (200)

copylink
{
    "Status": "Ok",
    "Source": "Roundtrip",
    "Timestamp": "2022-09-15T04:49:03",
    "ClientIp": "156.77.111.28",
    "X-Forwarded-For": "[156.77.111.28]"
}

post /accounts/validations/v2/verifyAccount

Verify that an account owner's name, address, and other identifying elements match the account information in the National Shared Database Resource and that they are authorized to transact on the account. The National Shared Database Resource is the financial industry's leading source of up-to-date, collaborative financial data.

BODY FIELDTYPEDESCRIPTION
accountValidationV2RequestrequiredObjectaccountValidationV2Request

Request example

copylink
{
    "accountValidationV2Request": {
        "AOARequest": {
            "Inquiry": {
                "serviceType": "Owner",
                "secondaryId": "KeyCli03",
                "additionalId": "AddCli04",
                "routingNumber": "122199983",
                "accountNumber": "89455",
                "amount": "110.99",
                "serialNumber": "",
                "AcctOwner": {
                    "firstName": "Paul",
                    "lastName": "wilson",
                    "middleName": "Dan",
                    "namePrefix": "Mr",
                    "nameSuffix": "Lal",
                    "businessName": "",
                    "addressLine1": "206 GOODWIN ST",
                    "addressLine2": "Land",
                    "city": "MERRIT",
                    "state": "MI",
                    "zipCode": "49667",
                    "homePhone": "3077553623",
                    "workPhone": "3077555330",
                    "ssn": "666082367",
                    "dob": "19730801",
                    "idType": "2",
                    "idNo": "590909812",
                    "idState": "AL"
                },
                "Client": {
                    "clientDate": "2022-12-31",
                    "clientTime": "14:00:80",
                    "userDefined": ""
                }
            }
        }
    }
}
NAMETYPEDESCRIPTION
accountValidationV2ResponserequiredObjectaccountValidationV2Response

Response example (200)

copylink
{
    "accountValidationV2Response": {
        "AOAResponse": {
            "Result": {
                "errorCode": "000",
                "systemRecordId": "8168140724120284",
                "primaryId": "TROM122101",
                "secondaryId": "KeyCli01",
                "routingNumber": "122199983",
                "accountNumber": "89455",
                "feeAttrib": "HH",
                "AcctOwner": {
                    "conditionCode": "000",
                    "addressMatch": "Y",
                    "cityMatch": "Y",
                    "stateMatch": "Y",
                    "zipCodeMatch": "Y",
                    "ssnMatch": "Y",
                    "overallMatchScore": "100"
                },
                "AcctStatus": {
                    "primaryStatusCode": "099",
                    "primMessage": "Open Valid"
                },
                "Client": {
                    "clientDate": "2022-12-31",
                    "clientTime": "14:00:80",
                    "userDefined": ""
                }
            }
        }
    }
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (400)

copylink
{
    "ErrorMessage": "Error received from backend service",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "X-CorrelationId": "abcgd133",
    "TransactionTime": "2021-06-11T16:31:34.041Z",
    "ServiceError": {
        "AOAResponse": {
            "Result": {
                "errorCode": "104"
            }
        }
    }
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (401)

copylink
{
    "ErrorMessage": "Received request is unauthorized, please provide valid credentials",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (403)

copylink
{
    "ErrorMessage": "Access Denied for client ip",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (404)

copylink
{
    "ErrorMessage": "Requested resource is not found, please verify the resource then resubmit the request",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (415)

copylink
{
    "ErrorMessage": "Requested media type is not allowed, please verify the media type and resubmit the request",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (429)

copylink
{
    "ErrorMessage": "Number requests threshold reached, please resubmit the request after sometime",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (500)

copylink
{
    "ErrorMessage": "Runtime error occurred in the service, please check with application support team before resubmitting the request",
    "X-CorrelationId": "abcgd133",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z"
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (502)

copylink
{
    "ErrorMessage": "Error received from backend service",
    "X-CorrelationId": "2ebd5c24-0e8d-5a70-0e91-ffd2727c1aab",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z",
    "ServiceError": {
        "ConnectError": "Connectivity error occurred with the downstream service (Unexpected EOF at target), please check with application support team before resubmitting the request"
    }
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (503)

copylink
{
    "ErrorMessage": "Error received from backend service",
    "X-CorrelationId": "2ebd5c24-0e8d-5a70-0e91-ffd2727c1aab",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z",
    "ServiceError": {
        "ConnectError": "Service is currently unavailable (NoActiveTargets), please check with application support before resubmitting the request."
    }
}
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError

Response example (504)

copylink
{
    "ErrorMessage": "Error received from backend service",
    "X-CorrelationId": "2ebd5c24-0e8d-5a70-0e91-ffd2727c1aab",
    "TransactionId": "rrt-7709400285867417207-b-gce-27587-2383364-1",
    "TransactionTime": "2021-06-11T16:31:34.041Z",
    "ServiceError": {
        "ConnectError": "Request could not be processed on time (GatewayTimeout), please wait a moment and resubmit the request"
    }
}
NAMETYPEDESCRIPTION
StatusoptionalstringStatus of the health check response.
SourceoptionalstringOrigin of the system response can be 'Gateway' or 'Roundtrip'. Roundtrip returns a response from the farthest system involved.
TimestampoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) of response from the API service.
ClientIpoptionalstringClient IP address the gateway receives from the request.
X-Forwarded-ForoptionalstringSequence of IP addresses for systems between the client and the gateway.
NAMETYPEDESCRIPTION
ErrorMessageoptionalstringA human-readable message that describes the type or source of the error.
TransactionIdoptionalstringA unique transaction ID returned with the response, useful for traceability.
X-CorrelationIdoptionalstringA unique identifier generated for each transaction that remains with the transaction through the chain of API operations.
TransactionTimeoptionalstringDate (YYYY-MM-DD) and time (HH:MM:SS) the error occurred.
ServiceErroroptionaloneOfserviceErrorData connectError
NAMETYPEDESCRIPTION
ConnectErroroptionalstringAPI connectivity error information, if available.
NAMETYPEDESCRIPTION
errorCodeoptionalstringThree-digit error code. Returns a "000" when no errors are present.
NAMETYPEDESCRIPTION
AOARequestoptionalObjectAOARequest
NAMETYPEDESCRIPTION
serviceTyperequiredstringRepresents the type of request made to the API. This value is case-sensitive and must be set to "Owner".
secondaryIdrequiredstringSecondary client ID provided by KeyBank. No special characters are allowed. This values is provided by KeyBank during onboarding.
additionalIdoptionalstringAdditional client ID provided by KeyBank. This is rarely used and if required, the value is provided during onboarding.
routingNumberrequiredstringNine-digit routing number for the account, including leading zeroes.
accountNumberrequiredstringFull bank account number, without separators or leading zeroes. The length and format depends on the bank. This field cannot exceed 17 characters.
amountoptionalstringDollar amount of the transaction or the field can be zero-filled. The amount can be formatted as a whole dollar with or without cents. This field cannot exceed 12 characters.
serialNumberoptionalstringSerial number of the check. Serial number does not apply to ACH inquiries.
AcctOwneroptionalObjectAcctOwner
ClientoptionalObjectClient
NAMETYPEDESCRIPTION
InquiryoptionalObjectInquiry
NAMETYPEDESCRIPTION
ResultoptionalObjectResult
NAMETYPEDESCRIPTION
businessFaultoptionalObjectbusinessFault
systemFaultoptionalObjectsystemFault
NAMETYPEDESCRIPTION
conditionCodeoptionalstringThree-digit system response code that reflects the state of the account owner provided.
nameMatchoptionalstringFirst name, middle name, and last name match status. Valid values: Y, N, U
firstNameMatchoptionalstringFirst name match status. Valid values: Y, N, U
lastNameMatchoptionalstringLast name match status. Valid values: Y, N, U
middleNameMatchoptionalstringMiddle name or initial match status. Valid values: Y, N, U
namePrefixMatchoptionalstringName prefix match status. U will always be returned for a name prefix if included in the request.
nameSuffixMatchoptionalstringName suffix match status. U will always be returned for a name suffix if included in the request.
businessNameMatchoptionalstringBusiness name match status. Valid values: Y, N, U
addressMatchoptionalstringCombined address line one and two match status. Valid values: Y, N, U
cityMatchoptionalstringCity match status. Valid values: Y, N, U
stateMatchoptionalstringState match status. Valid values: Y, N, U
zipCodeMatchoptionalstringZIP code match status. Valid values: Y, N, U
homePhoneMatchoptionalstringHome phone number match status. Valid values: Y, N, U
workPhoneMatchoptionalstringWork phone number match status. Valid values: Y, N, U
ssnMatchoptionalstringSSN/TIN or last four digits of SSN match status. If you are a merchant provider, the value returned will always be 'U'. Valid values: Y, N, U
dobMatchoptionalstringDate of birth match status. Valid values: Y, N, U
idTypeMatchoptionalstringID type match status. Valid values: Y, N, U
idNoMatchoptionalstringID number match status. Valid values: Y, N, U
idStateMatchoptionalstringState or place of issuance match status. Valid values: Y, N, U
overallMatchScoreoptionalstringThe measure of how closely the inquiry request attributes match the actual account ownership data. This number is calculated based on the analysis of all information sent. Valid values: 0-100
NAMETYPEDESCRIPTION
errorCodeoptionalstringThree-digit error code. Returns a "000" when no errors are present.
systemRecordIdoptionalstringUnique, system-generated transaction ID.
primaryIdoptionalstringPrimary client ID returned via a KeyBank lookup. This is a KeyBank ID.
secondaryIdoptionalstringSecondary client ID provided in the original request.
additionalIdoptionalstringAdditional client ID, if provided in the original request. This is rarely used.
routingNumberoptionalstringNine-digit routing number for the account provided in the original request.
accountNumberoptionalstringFull bank account number provided in the original request.
feeAttriboptionalstringTwo-character code that represents how a transaction took place. Currently, the only value reported is "HH", which represents an ACH transaction.
amountoptionalstringAmount of the transaction, if provided in the original request.
AcctOwneroptionalObjectAcctOwner_1
AcctStatusoptionalObjectAcctStatus
ClientoptionalObjectClient_1
NAMETYPEDESCRIPTION
errorDescriptionoptionalstringDescriptive error message that identifies if it is a system issue or business fault.
NAMETYPEDESCRIPTION
primaryStatusCodeoptionalstringPrimary three-digit account status code. This is an informational response code that represents the status of an account.
primMessageoptionalstringMessage associated with the primary status code.

accountValidation_POST_bodyParameters

NAMETYPEDESCRIPTION
accountValidationV2RequestrequiredObjectaccountValidationV2Request
NAMETYPEDESCRIPTION
errorDescriptionoptionalstringDescriptive error message that identifies if it is a system issue or business fault.
NAMETYPEDESCRIPTION
clientDateoptionalstringClient-provided date the inquiry request was made. Format: YYYY-MM-DD
clientTimeoptionalstringClient-provided time the inquiry request was made. Format: HH:MM:SS
userDefinedoptionalstringClient-provided descriptive text about the inquiry request. This field cannot exceed 255 characters.

accountValidation_POST_response

NAMETYPEDESCRIPTION
accountValidationV2ResponserequiredObjectaccountValidationV2Response
NAMETYPEDESCRIPTION
AOAResponseoptionalObjectAOAResponse
errorResponserequiredObjecterrorResponse
NAMETYPEDESCRIPTION
clientDateoptionalstringClient-provided date the inquiry request was made. Format: YYYY-MM-DD
clientTimeoptionalstringClient-provided time the inquiry request was made. Format: HH:MM:SS
userDefinedoptionalstringClient-provided descriptive text about the inquiry request. This field cannot exceed 255 characters.
NAMETYPEDESCRIPTION
firstNameoptionalstringFirst name of the account owner. Required with lastName if businessName is null.
lastNameoptionalstringLast name of the account owner. Required with firstName if businessName is null.
middleNameoptionalstringMiddle name of the account owner.
namePrefixoptionalstringOptional name prefix of the account owner. This field cannot exceed four characters. Example: Dr., Mr., Mrs.
nameSuffixoptionalstringOptional name suffix of the account owner. This field cannot exceed four characters. Example: Jr., PhD
businessNameoptionalstringBusiness name that owns the account. Required if lastName is null.
addressLine1optionalstringFirst line of the address on the account. This field cannot exceed 40 characters.
addressLine2optionalstringSecond line of the address on the account.
cityoptionalstringCity on the account.
stateoptionalstringTwo-character state abbreviation on the account.
zipCodeoptionalstringZIP code on the account. This can either be five digits or nine digits. If a nine-digit ZIP code is provided, a dash between the groups of digits is acceptable. Do not use a space.
homePhoneoptionalstring10-digit home phone number on the account. Do not add dashes, parenthesis, or any other non-numeric value.
workPhoneoptionalstring10-digit work phone number on the account. Do not add dashes, parenthesis, or any other non-numeric value.
ssnoptionalstringFull social security/tax ID number or the last four digits of the social security number of the account owner.
doboptionalstringDate of birth for the individual on the account. Format: YYYYMMDD
idTypeoptionalstringOne-character [code that represents the type of identification used to verify the account owner.
idNooptionalstringID number for the account owner's form of identification. This field cannot exceed 28 characters.
idStateoptionalstringTwo-character state of issuance for the account owner's form of identification. If not a US state, enter the place of issuance. This field must be between 2-6 characters in length.

For more information about errors, see Error handling.

When a problem occurs with the capture of the account information from a draftable account item or the evaluation of the request message fields, a 3-digit error code is provided in the response payload (errorCode). If no errors are present, this field is filled with three zeroes.

ERROR CODEDESCRIPTION
000Normal response - no errors
001Invalid routing number
003Invalid account number
005Invalid serial number
006Missing a required field
008Length of account number is incorrect
010Inquiry field length too short
011Inquiry field length too long
013Invalid amount field
103Client ID does not match
104Improper data type or value
105Bad layout or format
106Missing client record ID
107Invalid required format
997Authorization unavailable
998System failure
999Timeout

 


YAML file download

Account Validation

clock -minute read calender v2, v1 | updated Aug. 07, 2024

There are currently two versions of the Account Validation API. We strongly recommend using the most current version, v2. 

What's changed?

This latest version includes security and request schema enhancement to help deliver more meaningful responses. 

  • Enabled OAS validation for required request parameters. 
    • Going forward, the serviceType must be set to 'Owner' to be a valid request. 
    • Search for the account owner information by full name (firstName and lastName) OR by business name (businessName). 
  • Condensed 5 similar schemas into one simple request object, AcctOwner. 
  • Error responses built out for better clarification about the status of the results. 

Account Validation API v2 (use me!)

The latest specifications for our Account Validation API that include validation enhancements and improved search logic for account owner verification.

Account Validation API v1 (soon to be deprecated)

Uses the original search criteria logic without enforced account owner validation. The account owner schemas are not as accurate as v2. If you are an existing client, we strongly recommend upgrading to v2 for the latest enhancements.

Account Validation User Guide

Get a better idea of what to expect with our Account Validation API, how to make a quality inquiry, and interpret the response.

Release notes

clock 3-minute read calender 3.1.0 | updated Aug. 07, 2024

KeyBank will post release notes to this page for every minor and major portal release. Release notes summarize breaking and non-breaking changes made to the API product and/or the API developer portal. 

The developer portal release notes are organized by month and year of the release, starting with the most current. Each release also identifies the level of impact for the changes made. This is a quick cue to know if you need to make any necessary changes immediately or if you can integrate the API enhancements at your own pace.

 

MID IMPACT

  • Introduction of the Account Validation API v2
  • Enhancements to the Account Validation API User Guide that includes information about version 2 of the API with greater clarity about significant parameters that can help improve your validation process.
  • ACH Inquiry API has retired the following endpoints:
    • /accounts/transactions/v1/ACHStatusInquiry/list
    • /accounts/transaction/v1/collectedACHtransactions/list
    • /accounts/transactions/v1/postedACHtransactions/list
    • /accounts/transactions/v1/returnACHtransactions/list
  • Webhooks ACH alert code consolidated to a single value AL00906.
  • Data values now has the full list of all Wire/RTP webhook statuses including intermittent statuses and account validation ID types.
  • Sign up has been postponed for the time being as we develop our authenticated portal. If you are interested in using an Embedded Banking API product, please go to the EB Payments Advisor Contact Form.

LOW IMPACT

  • X-CorrelationId has been removed as a request header field for all endpoints in each API product. The parameter is no longer in the request body, but still remains in the code. The system assigns a unique ID when you submit a request and returns the X-CorrelationId value in the response.
  • In the ACH Inquiry API, added two new endpoints. These endpoints will eventually replace the other status queries in the upcoming v2 of the API.
    •  /accounts/transactions/v1/ach/details/{parNumber}
    • /accounts/transaction/v1/ach/list
  • Added the requestReference parameter to the getWireInquiryResult object in the Wire Inquiry API.
  • KeyVAM introduction on the dev portal home page and an summary guide on KeyVAM with links to learn more.
  • API Simulator product is now available for ACH API products endpoints (ACH Origination and ACH Inquiry). Speak to your Payments Advisor to learn more.

Levels of impact

Impact levelDescription
Low
  • Non-breaking changes
  • Small change requests to improve content like to better define a term or provide an example for added clarity.
Mid
  • May include breaking changes like adding or removing an API parameter.
  • Code or configuration enhancement to an API in Production.
High
  • Breaking changes and/or a hot fix.
  • New product being released.

Types of API changes

API product changes are changes made to the code or configuration of the API product or related services. This can include adding a schema, adding or remove parameters, modification of parameter type or function, etc.

  • Breaking changes require upgrading to a new version of the API framework. These changes can cause incompatibility and possibly disrupt your connection to API services. Some examples of breaking changes are a change to the type of a parameter, removing request fields, or developing an existing object with additional parameters.
  • Non-breaking changes are changes that do not require you to upgrade to a new version or disrupt your connection to current API services. Some examples of a non-breaking change are to add an optional parameter field like a custom data field or removing a deprecating parameter no longer valid or in use.

API specification versioning

The API version in the API specification file (YAML) is a three-number format that incrementally increase based on the significance of the change. All API specifications are initially released with the version 1.0.0. 

There are three numbers for the major version, minor version, and patch number (X.X.X). 

MAJORMINORPATCH
1.3.51.3.51.3.5
There is a significant release for code and functional changes. This includes breaking changes like developing new schemas, breaking existing integration points, removing attributes, changing a parameter type, etc.A smaller release that include new operations and enhancements.Small incremental, non-breaking changes that are often backend or related to technical content like minor improvements or grammatical edits/clarity. This can include hot fixes.

clock 1-minute read calender 2.5.0 | updated May. 29, 2024

Make managing multiple accounts as easy as managing just one

Key takeaways

There are many benefits to virtual account management at KeyBank. With KeyVAM, you can:

  • Send and receive ACH, RTP, and Wire transactions on behalf of the parent account.

  • Instant opening and closed of sub-accounts for an individual or business.

  • View transaction and reconciliation data for each virtual sub-account while the total funds settle in one parent account with advance reporting.

 

Virtually amazing

Check it out yourself. There is a lot of great information on the Key Virtual Account Management site.

If you are ready to get started or have any questions, reach out to an Embedded Banking advisor.

What is VAM?

Key Virtual Account Management (KeyVAM) is an embedded service of the KeyNavigator platform. KeyVAM enhances how you manage money by linking a set of a set of virtual accounts (sub-accounts) to a single, physical account (parent). You can create and manage virtual sub-accounts in real-time. This is a great option if you need to open and close high-value virtual sub-accounts common in industries like technology, property management, or corporate cost centers.

 

KeyVAM APIs

Integrate your application with APIs. KeyVAM APIs are available to further develop your virtual account management experience with task automation for common activities like creating accounts, transferring funds, or reports. View the Key Virtual Account Management API Documentation to see what is possible.

 

clock 8-minute read calender 3.1.0 | updated Aug. 07, 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, please contact us to learn more.
Contact us

With the Account Validation API, you can inquire about an account and a get real-time confirmation back on 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.

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. 

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

 

When you make a request, you must know the following parameter information:

  • 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 validates an account with a business or company name.
(businessName)

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.

Good to know

  • AOA is possible at KeyBank with the Account Validation API product.
  • We only confirm account ownership. At the moment, we do not provide a detailed account status or risk-based score.

In each response, the result shows the levels of review that take place to validate an account that can be broken up into four categories.

  1. Request summary - Returns the search parameters sent in the request.
  2. Account ownership - Reviews the AcctOwner attributes provided in the request and responds with if they match the data in the NSD. This includes the overall match score, a score from 1 to 100 for how much of the data matched.
  3. Account status - The validity of the account and routing numbers.

The response starts with an error code (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.

Following the error code, is a summary of the request information provided. Client information that is part of the submitted request is returned as part of the response. This includes pertinent identification parameters useful for reference, traceability, and security.

Important API identifiers
  • systemRecordId: The system record ID is a unique ID assigned to the response for traceability purposes.
  • primaryID: The primary ID is a KeyBank ID that is generated as part of the data lookup. This indicates that the call came from inside the house.
  • secondaryId: The secondary ID is your unique ID that is assigned to you as part of the API onboarding process. This indicates that you made the call for verification.
  • additionalId: This ID is rarely used. If it is used, KeyBank will provide you with the additional ID value during API onboarding.

It also returns the account number, routing number, and amount if provided in the request. The fee attribute (feeAttrib) only returns the 'HH' value for ACH transaction types.

Basic validation passes additional data points from the AcctOwner object like the address, phone number, and date of birth to compare with the NSD. The case, spacing, and punctuation are ignored when matching values.

The response returns:

  • 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.

If the response returns an empty field, there is no entry in the database.

Condition codes

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 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

Match codes

Depending on the service type configured, the accountOwnerResponse 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). 

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.

Overall match score

The provided overall match score uses an banking industry standard to calculate on a scale of 1 to 100 the level of data that matches between the account owner and the NSD.  The industry recommendation is to approve any account with a match score of 81 and above. 

This may not be your standard of owner validity. It is important to know what is an appropriate risk tolerance for account owner validation. Reaching out to one of KeyBank's Payment Advisors is a good place to begin this conversation if you need help.

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

Common terms

AOA

Account Owner Authentication matches the account owner identity to the bank account, confirming if data is accurate when compared against the NSD.

EB

Embedded Banking is a sector of KeyBank dedicated to developing and delivering quality digital services integration in both traditional and modern environments.

Micro deposits

Small amounts of money sent from one financial account to another to verify and authenticate account ownership.

Nacha

National Automated Clearing House Association the organization responsible for managing the rules and regulations governing the ACH network in the US.

NSD

National Shared Database is the collection of data contributed to by consumers and used to verify account owner information.

Prenotes

Test transactions to help confirm the correct bank account information, like the penny test.

Onboarding

The process of helping KeyBank partners and API consumers get familiar with our suite of API products. This can include assessment, setup, and environment access.

  • 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.50",
      serialNumber: "",
      AcctOwner: {
        firstName: " Paul;",
        lastName: "Wilson ",
        middleName: "V",
        namePrefix: "Mr",
        nameSuffix: "",
        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.50",
      serialNumber:"",
      AcctOwner: {
        conditionCode: "000",
        nameMatch: "Y",
        firstNameMatch: "Y",
        lastNameMatch: "Y",
        middleNameMatch: "Y",
        namePrefixMatch: "",
        nameSuffixMatch: "",
        businessNameMatch: "Y",
        addressMatch: "Y",
        cityMatch: "Y",
        stateMatch: "Y",
        zipCodeMatch: "Y",
        homePhoneMatch: "",
        workPhoneMatch: "",
        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

  1. 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.
  2. 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?

 

Custom data

clock 3-minute read calender 2.4.0 | updated Apr. 24, 2024

Add data or tags specific to your application or use case

If you send or validate a payment with the ACH Origination API or the Wire Origination API, you can add information to the customData in the request payload.

Custom data is client-specific metadata that you can:

  • Use to append certain information or details
  • Use as an identifier to filter certain types of transactions

The customData information is not transmitted with the payment or stored in any KeyBank database. This information is only visible to you, the originator, with the ACH Inquiry API or the Wire Inquiry API. In the inquiry response, the customData field returns any custom values that were part of the payment request stored for recall after a successful ACH or wire transaction completes. This information is not visible to the recipient or any of the participating parties.

Here's how it works

  1. Define the customData in the request payload. It is a free-form text field that can contain up to 500 alphanumeric characters that you can use however you like - for invoice number, product number, customer number, date/time stamp, etc.

    KeyBank recommends the common custom data format of name-value pairs. You can list multiple name-value pairs in the custom data field within the 500-character limit. The custom data fields will return exactly what is sent; it does not parse name-value pairs within the API response. The custom data should not contain any personal identifiable information (PII).

    Custom data examples

    //Example of name:value pairs
    "customData": "Type:DD; Status:Submitted; POnumber:12556"
    
    //Example of regular text
    "customData": "General products"
    
    //Example of timestamp
    "customData": "05-MAR-2023:12:19:53EST"
    
    

     

  2. As the originator, you can use the ACH Inquiry API or Wire Inquiry API to retrieve the custom data information.

  3. Review the response for the customData field.

    • If there is custom data, it returns any custom values that were part of the payment request stored for recall after a successful ACH or wire transaction completes.
    • If no custom data is defined, the response returns an empty field.

Error handling

clock 5-minute read calender 2.4.0 | updated Mar. 13, 2024

Is it you? Is it me? Is it us? Let's figure it out.

An error can indicate a problem with the request, the network, or the API itself. Use the error handling information to get a better understanding of what went wrong and possible corrective actions.

Each error response returns the standard HTTP code number with the exception schema. KeyBank utilized the standard HTTP messaging so nothing too fancy.

CodeStatusDescription
200OK; SuccessfulThe action was successful. No additional actions are needed.
400Missing mandatory informationRequest is missing required information.
401Unauthorized requestInvalid credentials for the request.
403Forbidden request accessYou do not have permission to complete the request.
404Resource not foundThe resource for the request cannot be found.
405Invalid request methodThe wrong request method was used.
415Invalid request typeThe wrong media type submitted with the request.
429Request timeoutThere are too many requests to the API and a timeout goes into effect.
500Unknown errorThere was an unknown error with the server.
502Bad gatewayThe servers cannot talk to each other or there is a miscommunication.
503Unavailable serviceThe service is temporarily down.
504Unable to process requestRequest needs more time to be processed.

 

 

The exception schema includes the error message, your unique X-CorrelationId, and additional information like TransactionId and TransactionTime. The transaction ID and timestamp are helpful in diagnosing the issue. The X-CorrelationId is helpful for transaction traceability and may help determine where did the error occurred.

The exception schema may also contain the ServiceError field for API-specific errors or problems with backend services. This object can contain a few different values, depending on the API or circumstance:

  • connectError - error information of the connectivity with downstream service.
  • detailMessage - an error code with a detailed message.
  • serviceErrorData - API-specific error details about the failed transaction.
  • variable field based on API - custom messages about API-related functional business messages or faults.

 

Standard error format

{
"ErrorMessage": string,
"X-CorrelationId": string,
"TransactionId": string,
"TransactionTime": string,
"ServiceError": object
}

Some APIs contain status messages in the responseHeader object of the response payload. Review the status field to see if the transaction was successful (S), was successful but has a warning (W), or failed (F). Additional information is shared in the statusDescription field.

  • S: A successful response. (HTTP 200) 
  • W: The transaction was not not processed as expected. A warning message means the request was successfully received, but there was a minor issue that requires your attention. (HTTP 299)
  • F: The transaction was not processed. (HTTP 400s/500s)

API-specific status messages are explained in depth on the API doc pages where applicable.

 

Status message example

{
                  "responseHeader": {
                     "status": "S",
                     "statusDescription": "Successfully returned results for the requested range 1 to 1",
                     "retrivedRows": "1",
                     "totalRows": "1",
                     "dataLoadDate": "2022-07-13"
                     },
                }
                

Pagination

clock 2-minute read calender 2.4.0 | updated Apr. 24, 2024

It's a real page-turner

You can use pagination parameters to manage a response with large amounts of data. Adjusting these parameters can improve system performance. You can limit or parse data to prevent a lag or delay in a response. You can control how much information is returned in a response.

Pagination parameters are usually available on APIs that return lists of transactions like the ACH Inquiry API, Wire Inquiry API, Previous Day API, Intraday API, and RTP Send Payment API. There are several pagination parameters that can help you control how an endpoint will return the information requested.

 

 

PAGINATION
PARAMETER
API ENDPOINT REQUIRED
OR OPTIONAL
startRowIndex

endRowIndex

ACH Inquiry POST /accounts/transactions/v1/returnACHtransactions/list
POST /accounts/transactions/v1/collectedACHtransactions/list
POST /accounts/transactions/v1/postedACHtransactions/list
POST /accounts/transactions/v1/ACHStatusInquiry/list
Optional
startRowIndex

endRowIndex

Wire Inquiry POST /wireInquiry/v1/transactions/details Optional
startRowIndex

endRowIndex

Previous Day POST /ddaReports/accounts/v1/transactions/list Optional
startRowIndex

endRowIndex

Intraday POST /ddaReports/accounts/v1/transactions/intraday/list Optional
limit

offset

RTP Send Payment GET /rtp/v1/payment/rtp/participant Required

 

 

Common pagination controls

Row pagination

There are common pagination parameters like startRowIndex and endRowIndex that help retrieve and organize large data sets into separate, scrollable pages. This is commonly used with information reporting and transaction inquiry APIs. These are optional fields and not required for the request.

  • The startRowIndex query string parameter sets the first row of data of the response. The default value is 1.
  • The endRowIndex query string parameter sets the final row of data of the response. The default value is 1000 records and is also the maximum number of records allowed in a single transaction.
  • If the startRowIndex or endRowIndex parameters are blank, all the rows of data return up to the maximum limit of the endRowIndex value for transaction records.
  • In the response header of the API, an endpoint may return totalRows or retrievedRows. These parameters provide a summary of the total number of transactions that match the request criteria or were retrieved based on the request criteria.

 

Example

Here is an example of a request with general pagination parameters applied in the query string for the Previous Day API:

POST /ddaReports/accounts/v1/transactions/list?startRowIndex=1&endRowIndex=20

In this example, the startRowIndex is 5 so the first row of data is the fifth row, skipping the first four rows of data. The endRowIndex is 20 so that there is only 20 records per page following the fifth row.

Offset pagination

The offset pagination parameters are limit and offset. These parameters tell the server how many records to search for at a time and what records to skip. This parameter is not reliant on the sort controls and is not a recommended parameter for very large sets of data. Offset pagination is available with the RTP Send Payment API and is required for the RTP list of participants endpoint.

  • The limit is a query string parameter field that tells the server what items to return during a search. The limit restricts how many rows are returned. There is no maximum limit to this parameter.
  • The offset is a query string parameter field that specifies which set of rows to return. You can use this field to set the starting row for the data that is returned, and control what rows of data to skip. The default value is zero (0).
  • Be cautious when you use these parameters because if the data set changes it can affect the result and may return an incorrect response.

 

Example

Here is an example of a request with the offset pagination parameters applied in the query string for the RTP Send Payment API:

GET /rtp/v1/payment/rtp/participant?limit=15&offset=0

In this example, the offset is 0 so that no items are skipped, and the limit is 15 meaning the request will search 15 items at a time.

clock 8-minute read calender 3.1.0 | updated Aug. 07, 2024

We've created this simple, user-friendly developer portal with you in mind. Here's a few good things to know first.

Key takeaways

TL;DR? We got you. Here are the highlights to this guide:

  • You need to be an authenticated and authorized user with our developer portal to use our APIs. To get started, see our overview of the onboarding process.
  • After you onboard, you get your own private API keys and can access our test environment.
  • Get an access token to connect to your APIs and start building.

Want in?

Contact a Payments Advisor to learn more about the KeyBank API developer portal and we'll have someone contact you with more information! 
Contact us

01

Contact and consult

If you are interested in a particular API product or a group of APIs, sign up for our waitlist. KeyBank will follow-up with you to help get you started.

To work with KeyBank APIs, there needs to be an established agreement between the service provider (KeyBank) and the client (you). This agreement details the API services you want, its services, and settings. It also gathers important system information needed for the KeyBank onboarding team to configure and secure the provisioned app.

02

Determine API needs

Determine which APIs are needed, define the frequency of use, and the transaction activity timeframe. Some APIs require specific configurations and may have a certain object to include in the call. Also, be mindful of our rate limiting.

For each API, provide the following information:

  • General details like transaction volume
  • Call frequency (number of calls per second, number of calls per minute, etc.)
  • Call timeframe (e.g., 24 hours a day or only during business hours)

The KeyBank onboarding team will reach out via email communication for additional details, if necessary.

03

Set up security

It is essential to have a secure connection before we start exchanging data, especially data as sensitive as financial data. For us to trust one another and verify that our pathways are safe, private, and guarded, we need to know your IP address and exchange certificates.

A digital certificate verifies your identity and keeps your data safe. Think of it like a virtual ID card for a website, or in this case the developer portal. When you connect to the site, the certificate legitimizes your identity. Then, when making API requests and transferring data on a cloud network, the certificate helps encrypt the data.

We use a mTLS authentication mechanism. This means when you request a mTLS certificate, you will get a public certificate chain and a private key. On your end, configure your application with the private key and certificate. You do not need to share your private key with KeyBank. After we exchange certificates, you will use the private key to encrypt the exchange and KeyBank uses the public certificate chain to verify it.

Certificate requirements:

  • Must have a CSR and private key. Do not share the private key.
  • Must include the root, intermediate, and leaf.
  • File format can be *.pem, *.crt, or *.cer.
  • Certificates cannot be self-signed.
  • Issued by a trusted certificate authority organization like DigiCert.
  • Only one certificate is required for all APIs.

04

Grant access

KeyBank sets up your account entitlements. Entitlements authenticate your identity and contain the authorization rules for the APIs you need to access. Part of the account entitlements are the API keys.

KeyBank shares the API keys needed to create an access token and make an API call.

KeyBank will set you up with a test environment to start and help you get a better idea of how the API functions and how it can integrate with your application. We share the environment details to you once setup is complete.

Common terms

Access token

A temporary token to that gives you permission to use the API. Use your API keys to generate the token. This is also known as a bearer token.

API consumer:

An authenticated developer portal user that has completed the onboarding process, has access to API services and possibly the KeyBank test environment.

API keys:

There are two sets of API keys that we privately share with you to authenticate and authorize your ability to use and access our API products. Can’t turn that engine without a key.

Authentication:

A method of identifying you and your application as a trusted and accepted source to exchange data. With authentication, we use your KeyBank client credentials (part of your API keys) to identify you.

Authorization:

A method of permitting access to certain APIs and services.

Certificates:

A digital exchange of several encrypted codes that verify your ability to connect with our API products safely, securely, and cautiously. These certificates typically expire annually.

CSR:

Certificate signing request is an encoded message that contains the information needed by the Certificate Authority (CA) to create your certificate. This can include your name, domain, organization information, or location.

Domain:

A human-readable name for an application or web address that identifies the name of the online application. Domain names are used to help set up web servers, communication, and other online services.

IP address:

The internet protocol address is a numerical label assigned to each device or application connected to the internet. Addresses can uniquely identify devices and route data to its intended destination.

mTLS:

Mutual Transport Layer Security is mechanism for the mutual authentication between the service provider and the client. No catfishing here. Digital certificates are exchanged and signed with the PKI framework.

Onboarding:

The process of helping KeyBank partners and API consumers get familiar with our suite of API products. This can include assessment, setup, and environment access.

PKI:

A public key infrastructure is a system to create, store, and distributes digital certificates. This framework matches the public keys to digital entities to authenticate the identity of users, devices, and services.

Pre-production:

A test environment that allows you try the API product using sample data.

Production:

KeyBank’s live environment that exchanges real proprietary data between your application and our API products.

Service agreement:

A contract between KeyBank and financial businesses and applications that intend to use and integrate with KeyBank’s suite of APIs. The service agreement identifies the API products allowed, data volume, and other specifics require to ensure a proper configuration of services.


We recommend that you always start your API builds with a health check. To perform a health check, you must have valid certificates exchanged with KeyBank and API keys to request an access token.

To ensure efficient and consistent API performance, we've placed a limit of 5 transactions per second (TPS) across all KeyBank APIs. API requests that exceed the rate limit receive an HTTP 429 response status code. If you've exceeded this limit, wait for at least 2 minutes before making another API call.

While we established the 5 TPS threshold to maximize stability and performance, we understand that your consumption needs might not fit within those limits. To request an increased rate limit, contact your KeyBank Client Success Manager.

The X-CorrelationId is a unique 36-digit alphanumeric identification code generated automatically for each API transaction. This field helps support teams at KeyBank quickly track down an inquiry or issue. The ID stays with the transaction so we can trace the chain of API operations in the event logs. If you see different X-CorrelationId values for the same transaction, this could indicate that duplicate requests.

 

KeyBank requires an OAuth 2.0 access token to authorize API calls. To make a call for a token, you must have access to our environments, your certificates, private key, and API keys. 

Copy and modify the cURL command template. Be sure to replace the curly brackets {{xxxx}} with your specific information.

 

  1. For line 1, identify the certificates.
    • For client.crt, enter the location of your certificate signing request (CSR). The file must be in one of these formats *.pem, *.crt, or *.cer.
    • For client.key, enter the name of your certificate’s private key file.
    • For ca.crt, enter the name of your certificate authority (CA) certificate.
  2. For line 2, identify the host. Enter the URL address for the KeyBank environment. Make sure to add scope=rs-read as a path parameter in the URL.
  3. For line 3, enter your application credentials (consumer_key and consumer_secret) API keys in Base64 encoded format. Use a trusted site to generate an encoded string for your consumer key and secret.
  4. For line 6, enter your client credentials from KeyBank. For client id enter your client_id API key and for client password, enter the client_secret API key from KeyBank.

cURL command template

curl -X POST --cert {{client.crt}} --key {{client.key}} --cacert {{ca.crt}} \
                    ‘{{host}}/oauth/v1/token?scope=rs-read'
                    -H 'Authorization: Basic {{base64 encoded consumer key and secret}}' 
                    -H 'Content-type: application/x-www-form-urlencoded'
                    -H 'Accept: application/json'
                    -d 'Id={{client id}}&Key={{client password}}&grant_type=client_credentials'
                    
  • The response contains a field named access_token. Use this access token in the Authorization header when you call the API over a secure mTLS connection.

     

  • If you are unable to retrieve an access code, reassess your setup, review your API keys, and make sure you are properly connected to the environment before you try again.

 

Request

Response

 
curl -X POST --cert client.crt --key client.key --cacert ca.crt \
'https://api.qv.keybank.com/oauth/v1/token’
-H 'Authorization: Basic KFddrcHQwQ3JDGQTamdqRUI0bEFHVVlHQcg'
-H 'Content-type: application/x-www-form-urlencoded'
-H 'Accept: application/json'
-d 'Id=b1194a183b8e01&Key=165a15dfanqf1d60&grant_type=client_credentials'
curl -X POST --cert {{client.crt}} --key {{client.key}} --cacert {{ca.crt}} \
{
"refresh_token_expires_in": "0",
   "api_product_list": "[API 1, API 2, API 3]",
   "api_product_list_json": [
      "API Inquiry",
      "API test product",
   ],
   "organization_name": "keybank-non-prod",
   "developer.email": "yourEmail",
   "token_type": "BearerToken",
   "issued_at": "2255448892"
   "client_id": "KBConsumerKey”,
   "access_token": "gPd4ZXMi927aoWhvmc",
   "application_name": "9IIa42-134320dk32s",
   "scope": "apiauth-read apiauth-write rs-create rs-delete rs-oauth rs-read rs-update rs-write",
   "Id": "KBClientId",
   "expires_in": "86399",
   "refresh_count": "0",
   "status": "approved"
}

 

What to expect

  1. You get a response with access token and information about which API products you can use, the refresh token time cycle, expiration time, etc.
  2. Select and copy the access_token value to use with your API requests.
  3. The access token remains valid for 24 hours. If it expires, try the refresh token to receive a new access token and pass in the API request.

 


What's next?

  • If this all sounds nice to you, sign up to speak with an Embedded Banking Payments Advisor. Our people will reach out to your people.
  • Read our API documentation to learn more about KeyBank’s API products. Or if you prefer to look under the hood, download an API specification file in YAML format.

 

Data values

clock 8-minute read calender 3.1.0 | updated Aug. 07, 2024

Decrypting and decoding API parameters

There are fields present across KeyBank APIs, in both request and response objects, that have predefined values. Some of these values are specific to KeyBank and others are industry-standard values. The purpose of this page is to catalog as many of these data values as possible and provide definitions for their usage within our APIs.

Each data value definition contains a brief description, the specific fields and APIs where the data value can be found, and a tabular listing of possible values and what these values mean.

Data valuesField namesApplicable APIsDescription
Addenda type codesaddendaTypeCodeACH Origination, ACH InquiryA two-digit code that defines the specific interpretation and format for the addenda information contained in the addenda record.
BAI codesbaiCode, amountTypeCode, derivedBaiCode,transactionCodeBAI2ACH Inquiry, Intraday Reporting, Previous Day ReportingA BAI (Bank Administration Institute) code is a three-digit code identifying a banking transaction and are divided into balance codes and transaction codes.
Change codeschangeCode, nocChangeCodeACH Inquiry, Webhooks (ACH alerts)In the case of a Notification of Change (NOC), this is a three-character code beginning with the letter 'C' that indicates the information being changed.
Foreign bank type codesforeignBankSystemTypeWire Transfer, RTP Send PaymentFive-character global routing/clearing codes for payments in foreign countries.
ID type codesidTypeAccount ValidationOne-character code that indicates the type of ID used to verify account ownership.
Pay subtype codespaySubTypeWire InquiryA four-digit code that corresponds to a particular wire drawdown scenario.
Return reason codesreturnReasonCode, retReturnReasonCodeACH Inquiry, Webhooks (ACH alerts)In the case of a returned ACH payment, this is a three-character code beginning with the letter 'R' that identify a reason an ACH payment was returned.
Transaction codestransactionCode, retTranCode, tranCodeACH Inquiry, ACH Origination, Intraday Reporting, Webhooks (ACH alerts)A two-digit code identifying various types of debit and credit entries.
Wire and RTP alert statusestransBusnStatusCodeWebhooks (Wire/RTP alerts)The intermittent or final statuses possible for Wire and RTP webhook alerts.

A two-digit code that defines the specific interpretation and format for the addenda information contained in the addenda record.

Addenda type codes can be found in the following fields:

CodeDescription
02Point of Sale Entry (POS), Shared Network Transaction (SHR), or Machine Transfer Entry (MTE)
05Corporate Credit or Debit (CCD), Customer Initiated Entries (CIE), Corporate Trade Exchange (CTX), Prearranged Payment and Deposit (PPD), Internet Initiated/Mobile Entries (WEB)
10-161st-7th addenda records for International ACH Transaction (IAT)
17IAT Remittance Information addenda record
18IAT Foreign Correspondent Bank addenda record
98Used for Notification of Change (NOC) entries
99Used for Return entries

A BAI (Bank Administration Institute) code is a three-digit code identifying a banking transaction and are divided into balance codes and transaction codes.

BAI codes can be found in the following fields:

Balance codes

CodeDescription
010Opening Ledger
015Closing Ledger
040Opening Available
045Closing Available
072One Day Float
074Two or More Day Float
100Total Credits
109Current Day Total Lockbox Deposits
111Lockbox Deposit - Zero Day Float
112Lockbox Deposit - One Day Float
113Lockbox Deposit - Two Day Float
115Lockbox Deposit
140Total ACH Credits
190Total Incoming Money Transfers
400Total Debits
450Total ACH Debits
490Total Outgoing Money Transfers
580Total Controlled Disbursement Debits
584Total Disbursements Late Amount
585Disbursing Funding Requirement
602Total CDA Adjustments

Transaction codes

CodeDescription
158Real Time Payment Credit
165Pre-authorized ACH Credit
171Individual Loan Deposit
172Deposit Correction
195Incoming Money Transfer
201Individual Automatic Transfer Credit
206Book Transfer Credit
213Letter of Credit
214Foreign Exchange Credit
229Miscellaneous International Credit
237Individual Collection Credit
238Collection of Dividends
244Interest / Matured Principle Payment
252Debit Reversal
258ACH Reversal Credit
275ZBA Credit
295ATM Credit
301Commercial Deposit
306Fed Funds Sold
351Individual Investment Sold
354Interest Credit
357Credit Adjustment
359Interest Adjustment Credit
395Check Reversal
398Miscellaneous Fee Refund
399Miscellaneous Credit
451ACH Debit Received
455Pre-authorized ACH Debit
458Real Time Payment Debit
475Check Paid
481Individual Loan Payment
495Outgoing Money Transfer
501Individual Automatic Transfer Debit
506Book Transfer Debit
512Letter of Credit Debit
513Letter of Credit
514Foreign Exchange Debit
529Miscellaneous International Debit
544Interest / Matured Principle Payment
552Credit Reversal
555Deposited Item Returned
558ACH Reversal Debit
564Overdraft Fee
567Return Item Fee
575ZBA Debit
595ATM Debit
627Fed Funds Purchased
631Debit Adjustment
651Individual Investment Purchased
654Interest Debit
659Interest Adjustment Debit
661Account Analysis Fee
666Currency and Coin Shipped
690Miscellaneous Debit
694Deposit Reversal
695Deposit Correction Debit
698Miscellaneous Fees
699Miscellaneous Debit
760Commercial Loan Debit

In the case of a Notification of Change (NOC), this is a three-character code beginning with the letter 'C' that indicates the information being changed.

Change codes can be found in the following fields:

CodeDescription
C01Incorrect bank account number
C02Incorrect transit/routing number
C03Incorrect transit/routing number and bank account number
C04Bank account name change
C05Incorrect transaction code
C06Incorrect bank account number and transaction code
C07Incorrect transit/routing number, bank account number, and transaction code
C08Incorrect Receiving DFI Identification (IAT only)
C09Incorrect individual identification
C10Incorrect company name
C11Incorrect company identification
C12Incorrect company name and identification
C13Addenda format error

Five-character global routing/clearing codes for payments in foreign countries.

Foreign bank type codes can be found in the following field:

CodeDescription
ATBLZAustria
AUBSBAustralia
CACPACanada
CHSICSwitzerland
DEBLZGermany
ESNCCSpain
GBDSCGreat Britain
HKNCCHong Kong
IENCCIreland
INFSCIndia
ITNCCItaly
NZNCCNew Zealand
PTNCCPortugal
USABAUS FedWire
ZANCCSouth Africa

The idType indicated the type of identification used to verify the identification of an account owner.

ID type codes can be found in the Account Validation API.

CodeIdentification type
0Driver's license (USA)
1Military (USA)
2Passport
3Resident alien ID
4State identification
5Student identification
6Driver's license (intercontinental)
7Driver's license (Canada)
8Driver's license (Mexico)
9Other primary ID (intercontinental)
AMatricula Consular card
BSouth America Cedula No.

A four-digit code that corresponds to a particular wire drawdown scenario.

Pay subtype codes can be found in the following field:

CodeDescription
1031Request for customer drawdown
1032Transfer honoring customer drawdown request
1033Refusal of customer drawdown request
1631Request for bank-to-bank drawdown
1632Transfer honoring bank-to-bank drawdown request
1633Refusal of bank-to-bank drawdown request

In the case of a returned ACH payment, this is a three-character code beginning with the letter 'R' that identify a reason an ACH payment was returned.

Return reason codes can be found in the following fields:

CodeDescription
R01Insufficient funds - The available and/or cash reserve balance is not sufficient to cover the dollar value of the debit entry.
R02Account closed – A previously active account has been closed by action of the customer or the RDFI.
R03No account/unable to locate account – The account number structure is valid and it passes the check digit validation, but the account number does not correspond to the individual identified in the entry, or the account number designated is not an existing account.
R04Invalid account number structure – The account number structure is not valid.
R05Unauthorized debit to consumer account using corporate SEC code – CCD or CTX debit entry was transmitted to a Consumer Account of the receiver and was not authorized by the receiver.
R06Returned per ODFI’s request – The ODFI has requested that the RDFI return an erroneous entry.
R07Authorization revoked by customer – The RDFI’s customer (the receiver) revoked the authorization previously provided to the originator for this debit entry.
R08Payment stopped – The receiver has placed a stop payment order on this debit entry.
R09Uncollected funds – A sufficient ledger balance exists to satisfy the dollar value of the transaction, but the available balance is below the dollar value of the debit entry.
R10Customer advises unauthorized, improper, ineligible, or part of an incomplete transaction – The RDFI has been notified by the receiver that the entry is unauthorized, improper, ineligible, or part of an Incomplete Transaction.

A two-digit code identifying various types of debit and credit entries.

Transaction codes can be found in the following fields:

DDA credits

CodeDescription
20Reserved
21Return or Notification of Change for original transaction code 22, 23, or 24
22Demand credit (checking deposit)
23Prenotification for a demand credit; death notification (non-dollar); automated enrollment entry (non-dollar)
24Zero dollar with remittance data (for CCD, CTX, and IAT entries); acknowledgement entries (ACK and ATX entries)

DDA debits

CodeDescription
25Reserved
26Return or Notification of Change for original transaction code 27, 28, or 29
27Demand debit (checking withdrawal)
28Prenotification for a demand debit (non-dollar)
29Zero dollar with remittance data (for CCD, CTX, and IAT entries)

Savings credits

CodeDescription
30Reserved
31Return or Notification of Change for original transaction code 32, 33, or 34
32Savings credit (savings deposit)
33Prenotification for a savings credit; death notification (non-dollar); automated enrollment entry (non-dollar)
34Zero dollar with remittance data (for CCD, CTX, and IAT entries); acknowledgement entries (ACK and ATX entries)

Savings debits

CodeDescription
35Reserved
36Return or Notification of Change for original transaction code 37, 38, or 39
37Savings debit (savings withdrawal)
38Prenotification for a savings debit (non-dollar)
39Zero dollar with remittance data (for CCD, CTX, and IAT entries)

Loan credits

CodeDescription
51Return or Notification of Change for original transaction code 52, 53, or 54
52Loan account credit
53Prenotification for a loan account credit
54Zero dollar with remittance data (for CCD, CTX, and IAT entries)

Loan debits

CodeDescription
55Loan account debit (reversals only)
56Return or Notification of Change for original transaction code 55

Review the tranBusnStatusCode in the alertBody object in Webhooks. The status value identifies the payment event in an intermittent (payment under processing), final (completed payment processed), and success (payment successfully completed) status.

StatusDescriptionInterim StatusFinal StatusSuccess
Pre QualifyingPayment is being evaluated for errors by the Network.X  
Funds ReleasePayment is waiting for OLDS memo post response.X  
PaymentNotificationPayment stopped pending manual release for various reasons.X  
RepairPayment needs correction before it continues processing.X  
Duplicate ContentPayment matches criteria of another payment. Requires action to process further.X  
Regulatory FilterPayment is waiting for response from Fraud or OFAC check.X  
ClearingPayment is waiting for a response from the Payment Network.X  
Product SelectionEPP determines the product for the payment that drives which steps in the workflow will execute.X  
Limit checkChecks EPP for any applicable account or customer limits.X  
AdvisingMost of our customer advising is done outside of EPP, but this could be performing payment network advising of some sort as well.X  
PricingBilling codes and/or network channel fees are applied to the paymentX  
Held Requiring CoverThis payment requires an Operator to clear it out of the Direct and Cover Matching-in Payment Intervention.X  
Internal FilterScans EPP filters for alternate or special processing of the paymentX  
Future WarehouseThe payment is moved to a future business date because it missed the payment network cutoff time. When that future business date arrives and the payment network opens for business, the payment will re-enter the workflow to ultimately reach a FINAL status.X  
CancelledPayment was cancelled. X 
ReturnedPayment was returned by receiving bank. X 
FatalA serious error has occurred. Payment will not complete workflow. X 
RejectedPayment was rejected by Network. Payment will not complete workflow. X 
Future Warehouse CancelledPayment was cancelled from Future Warehouse Queue. X 
AbandonedPayment was manually forced to not complete in EPP. X 
CompletedPayment processed successfully through workflow.  X