20-minute read 2.3.0 | updated Mar. 13, 2024

Tips and tricks to leverage the suite of ACH API’s quickly and efficiently

Key takeaways

TL;DR so here are the hits:

  • Use our ACH Origination API to make or collect authorized payments. You can also inquire on the transactions before they are officially submitted for processing.
  • Sometimes we make mistakes. With ACH you can undo a payment typically within a period of 10 minutes from origination.
  • Inquiring minds want to know? Monitor and report on ACH transactions that are collected, posted, or returned.
  • Look at our Webhooks specs to learn more about automatic push notifications for ACH transactions.
 

Try it out!

Wanna check out our ACH APIs? You first need to complete the KeyBank onboarding process.

Check out our Getting Started Guide. Or sign up for our waitlist and someone will contact you to learn more!

Sign up

With the ACH Origination API, you can originate a credit or debit transaction to an authorized receiver.

See the specs

To make or collect a payment there has to be an authorized agreement between the originator and the receiver. An authorized agreement means that the payee has an agreement with their financial institution or commercial entity that funds can be exchanged between the originator and the receiver.

The ACH Origination API uses only POST methods to generate new ACH transactions. In the request, you indicate if you are pushing or pulling funds and the method of authorization to transfer funds.

  • The creditDebitCode defines the action of the request, if you are taking funds (debit) or receiving funds (credit).
  • The secCode defines the authorized method to transfer funds, like from a corporate account, online account, by phone, etc. There is a path for each SEC code. Use the correct endpoint path and identify the secCode in the request.

All ACH payments, credit or debit, must include a SEC code. The code is implicit in how payment authorization is arranged (by standing, written, oral, online, etc.). A SEC code also helps determine the rules and requirements that apply to the transaction, including timing of settlement and eligibility for same-day processing.

KeyBank allows ACH origination payment types for the following SEC codes: CCD, CTX, PPD, TEL, and WEB.

 
CCD Corporate Credit or Debit
  • Deposits and withdrawals to corporate accounts.
  • Does not require individual consumer authorization for each payment.
  • Remittance information available with the transaction as an addendum record.
CTX Corporate Trade Exchange
  • One business pays another for goods or services.
  • An electronic payment that includes an invoice (addenda) intended for the receiving financial institution.
PPD Prearranged Payments and Deposits
  • Specify a certain amount to be transferred from one financial account to another.
  • Requires consumer authorization or prearrangement for the payment or deposit to occur.
  • Some examples are direct deposit of payroll, pension, and dividends, or payment of utility bills, mortgages, rent, membership dues, loans and other recurring payments.
TEL Telephone
  • Send a payment via the telephone.
  • Must provide verbal consent during the phone call to initiate the payment transaction.
WEB Online
  • Initiate a transaction through the web or online banking.
  • Requires consumer authorization for the payment or deposit to occur.

Nacha business, not your problem

With ACH, transaction processing happens in real-time while the file processing for Nacha occurs behind the scenes. We follow Nacha standards and recommend there are no more than 100 transactions per request.

The Nacha file format is the standard file format used for ACH electronic fund transfers (EFT) in the United States. Nacha stands for National Automated Clearing House Association, the organization responsible for managing the rules and regulations governing the ACH network in the US. The Nacha file format is used to create batch files that contain multiple transactions, like direct deposits, bill payments, and other types of electronic payments. These files are commonly used by businesses, financial institutions, and other organizations to initiate and process ACH transactions.

An addendum is an ACH record type that carries supplemental data like remittance information. This data may be needed to identify an electronic payment to the receiving financial institution and the payee, or it may contain additional information relating to the prior entry detail record.

This addenda record is optional. It is primarily used for business-to-business transactions, like CCD and CTX.

Addenda record settings and limitations:

  • CCD, PPD, and WEB payment transactions can have one addenda record. The addenda record displays as one line, not to exceed the 88-character limit.
  • A CTX payment transaction can have multiple addenda records, up to 9,999 records to be exact.
  • KeyBank does not allow more than 20 addenda records per request.
  • If you need additional records, there is a different request available to add addenda records and that endpoint is limited to 100 records per request.

To manage the status of the addenda records, our system tracks it for the entire business day. The status changes from Waiting to Completed, indicating that the addenda records were successfully received, and the ACH transaction is ready to be processed.

Same-day ACH transactions are when the receiving depository financial institution (RDFI) posts the credit or debit to the payee account on the same day the transaction originated. Same-day ACH transactions cannot exceed a set maximum dollar amount per day. Typically, the total same-day ACH transactions cannot exceed $100,000 in a single business day.

This is an automatic setting for our clients. If you do not want the default option of same-day ACH transactions, you can choose to opt out. There is a surcharge for same-day transactions.

For the ACH Origination API, there are cutoff times for the ACH transaction to be posted the same day it originated:

SAME-DAY FLOW Window 1 Window 2 Window 3
Client cutoff 09:15 a.m. (EST) 11:15 a.m. (EST) 03:00 p.m. (EST)
File sent from KeyBank
to the ACH operator
09:30 a.m. (EST) 11:30 a.m. (EST) 03:45 p.m. (EST)
ACH transaction to RDFI 12:00 p.m. (local) 04:00 p.m. (local) 05:30 p.m. (local)
Posted to payee account 01:30 p.m. (local) 05:00 p.m. (local) RDFI end of day

Did you know?

With the ACH Origination API, you can inquire on the transactions before they are officially submitted for processing. The status endpoint tells you if the transaction was accepted (transaction request data is valid), rejected (there is missing or erroneous data in the request), or extracted (transaction received by the ACH core processing system).

Common terms

ACH operator
The central clearing facility managed by the Federal Reserve Bank.
ACH processor
The ACH core processing system takes the incoming transactions from the originating financial institution, which are then sorted, batched, and verified. After the transaction is legitimized, the funds are forwarded to the receiver’s financial institution.
Collected
The status when the originating transaction is received by the ACH processor.
Credit
To push funds to other accounts.
Debit
To pull funds from an account.
ODFI
Origination Depository Financial Institution is the financial institution of the originator. This ODFI has an active relationship with ACH services and sends transactions to the ACH network on behalf of the originator.
Originator
The company or business that initiates a credit (payment) transaction to the receiver (payee). Before a transaction can be sent, the originator has authorized the receiver to credit or debit their account.
PAR number
Payment Assigned Reference number is a unique identifier assigned by the ACH processor used to identify the transaction without exposing any sensitive consumer identification information. When you submit a request with the ACH Origination API, it creates a PAR number and returns the value in the response.
Posted
The status when a transaction is received by the ACH processor, reviewed by the ACH operator, and currently with core banking applications to secure and transfer funds. It could also indicate that the funds have been completely settled between originator and receiver.
RDFI
Receiving Depository Financial Institution is the financial institution of the receiver. The ACH operator processes the transactions and sends the funds to the financial institution before the money is posted to the receiver's account.
Receiver
The individual or company that receives the funds. Before a transaction can be received, the receiver has authorized the originator to credit or debit their account. The receiver may also be referred to as the payee.
Returned
The status when a transaction is reviewed by the ACH operator and the transaction is not cleared for transfer for reasons like insufficient funds or erroneous data.
Reversed
Cancel a payment after it has reached the ACH operator but not yet settled funds.
Trace number
The trace number is a unique identifier for an ACH transaction generated by the ACH Origination API. Use this number for your ACH Inquiry API requests.
Undo
Stop a transaction before it is received by the ACH processor. This window is typically 10 minutes in length.

With the ACH Inquiry API, you can check on the progress of a payment transaction after the ACH processor receives them. There is a status call for general inquiry and three additional endpoints that provide detailed information for each stage of an ACH transaction - collected, returned, and posted.

See the specs

Use the PAR number or trace number from the ACH Origination transaction request to inquire about the status of a transaction before it is posted. Use the KeyBank originator account number associated with ACH transaction to inquire about transactions that are posted.

 
PAR number

The PAR (Payment Assigned Reference) number is a unique identifier assigned by the ACH processor after you submit a request with the ACH Origination API. This is used to identify the transaction without exposing any sensitive consumer identification information.

Use the PAR number as an ACH Inquiry API request parameter to inquire about the unique transaction identifier.

You can use the parNumber to inquire about ACH transactions with the following ACH Inquiry API endpoints:

Trace number

The trace number is a unique identifier for an ACH transaction generated assigned by the ACH processor after you submit a request with the ACH Origination API. The trace number is useful for the transaction inquiries and traceability.

Save this trace number if you intend to check on the progress of the ACH transaction. To get the status of multiple transactions with either identifying number, separate the numbers with a comma.

You can use the traceNumber to inquire about ACH transactions with the following ACH Inquiry API endpoints:

In the table below we associate each endpoint in the ACH Inquiry API with the key identifiers you can use to request the status of an ACH transaction.

ENDPOINT IDENTIFIER EXAMPLE
ACH Status /accounts/transactions/v1/ACHStatusInquiry/list

traceNumber: 021300012341234

parNumber: 1234567891113

ACH Collected /accounts/transactions/v1/collectedACHtransactions/list
ACH Returned /accounts/transactions/v1/returnACHtransactions/list parNumber: 1234567891113
ACH Posted /accounts/transactions/v1/postedACHtransactions/list accountNumber: 321234567890

A good reminder...

We recommend that you check on the status after 06:00 a.m. EST the following business day. By this time, the ACH processor has run the batch and consolidation processes.

 

Your ACH inquiry should begin with the ACH Status Inquiry or ACH Collected Inquiry endpoints. The ACH Status Inquiry endpoint provides a status along with a reduced subset of data.

Request and response example

  • If you have originated an ACH transaction, utilize the accountNumber and traceNumber fields in your request. The traceNumber is a key field returned from the ACH Origination API.
  • If you are inquiring about an ACH transaction, utilize parNumber, accountNumber, and traceNumber fields in your request. The parNumber could be a better choice in this situation depending on the available data.
Request
{
"getACHStatusInquiryRequest": {
  "accountNumber": ["32123456789"],
  "parNumber": ["23074005623452"],
  "traceNumber": ["041001034453247"],
  "startRowIndex": "1",
  "endRowIndex": "1000"}
}
Response
"ACHStatus": "COLLECTED",
"ACHCollectedTransaction": {
  "transactionParNumber": "23074005623452",
  "transactionCode": "22",
  "transactionAmount": "712.54",
  "creditOrDebitCode": "C",
  "receivingAccountNumber": "32123456789",
  "receivingCompanyName": "KINNEY DRUGS #11",
  "originatingAccountNumber": "45987654321",
  "originatingCompanyName": "COMPANY,LLC",
  "nachaSecCode": "CCD",
  "traceNumber": "041001034453247",
  "transactionDescription": "DCSETL0315"}

 

What to expect

  1. In the response, you can expect to see a status of Collected or Returned. If you get the Collected status, use the ACH Collected endpoint for more details. If you get the Returned status, use the ACH Returns endpoint next.
  2. The parNumber returns in the response. This is a key field to inquire with the ACH Returns endpoint.
 

 

The ACH Collected inquiry endpoint has all the available data elements at the time an ACH transaction is collected.

 

Request and response example

The request field recommendation for the ACH Collected inquiry is similar to the ACH Status Inquiry request. One of the fields or a combination will result in a response with details for a specific item.

  • For originators, utilize the accountNumber and traceNumber fields in your request. The traceNumber is a key field returned from the ACH Origination API.
  • For receivers, utilize accountNumber and traceNumber fields in your request. You could also use the parNumber as it could be a better choice depending on the available data.

To further filter your results, use the date range fields (fromDate, toDate), amount range (fromAmount, toAmount), and pagination controls (startRowIndex, endRowIndex).

 

Request
{
  "getACHCollectedTransactionsRequest": {
    "accountNumber": [
      "3212345689"
    ],
    "fromDate": "2023-09-18",
    "toDate": "2023-09-30",
    "sourceTransactionSettledDate": "",
    "creditOrDebitCode": "",
    "fromAmount": "",
    "toAmount": "",
    "traceNumber": "",
    "parNumber": "23268007704844",
    "startRowIndex": "1",
    "endRowIndex": "1000"
  }
}

Response
"ACHCollectedTransaction": [ {
  "transactionParNumber": "23268007704844",
  "sourceBankNumber": "0101",
  "sourceAccountNumber": "32123456889",
  "transactionCodeDescription": "Automated Payment",
  "transactionFlowTypeDescription": "Outbound",
  "transactionAmount": "0.03",
  "transactionDescription": "ST10021702",
  "creditOrDebitCode": "D",
  "sourceTransactionProcessDate": "2023-09-25",
  "sourceTransactionSettledDate": "2023-09-25",
  "sourceTransactionPostDate": "2023-09-25",
  "receivingAccountNumber": "32123456889",
  "receivingCompanyName": "COMPANY INC",
  "originatingAccountNumber": "45987654321",
  "originatingCompanyName": "ABC COMPANY",
  "nachaSecCode": "WEB",
  ...ect.

 

What to expect

  1. In the response, you can expect 50-100 data elements for each transaction. This includes the parNumber which is an essential field for the ACH Returns Inquiry endpoint.
  2. The traceNumber also returns in the response which can be used in the ACH Status Inquiry endpoint.
 

 

ACH Returns are made available during our end-of-day processes and can be inquired upon at approximately 01:00 a.m. EST for the previous business day.

Request and response example

  • To inquire about one or more transactions, use the accountNumber and date range fields (fromDate, toDate) to look up information.
  • To look up a specific returned transaction, use the parNumber returned in the ACH Status Inquiry and ACH Collected endpoints. It is a unique identifier that matches the returned transaction to the original Collected transaction.

 

Request
{
  "getACHReturnTransactionsRequest": {
    "accountNumber": ["359681604732"],
    "fromDate": "2022-07-26",
    "toDate": "2022-07-30",
    "creditOrDebitCode": "",
    "fromAmount": "",
    "toAmount": "",
    "parNumber": "22202011366290",
    "startRowIndex": "1",
    "endRowIndex": "10"  }  }


Response
"ACHReturnTransaction": [   {
"returnTransactionParNumber": "22207010038422",
"sourceAccountNumber": "359681604732",
"snapshotDate": "2022-07-27",
"originalACHTransactionParNumber": "22202011366290",
"originalTransactionProcessDate": "2022-07-21",
"originatingReceiverDescription": "Originating Return",
"transactionCode": "26",
"transactionCodeDescription": "Automated Return",
"transactionFlowTypeDescription": "Outbound",
"transactionAmount": "181.98",
"transactionDescription1": "PYMNT",
"transactionDescription2": "S",
"creditOrDebitCode": "D",
"sourceTransactionCreatedDate": "2022-07-21",
"sourceTransactionProcessDate": "2022-07-21",
"sourceTransactionSettledDate": "2022-07-22",
"receivingAccountNumber": "2133478",
"receivingCompanyName": "Joann Cockrell",
"originatingAccountNumber": "359681604732",
"returnReleaseDate": "2022-07-26",
"returnReasonCode": "R07",
"returnReasonDescription": "Authorization  Revoked",
"nachaSecCode": "PPD",
"traceId": "041001030038422",
  ...ect.

What to expect

  1. The ACH Returns Inquiry endpoint response includes 50+ data elements detailing the returned item along with transaction details from the collection of the item.
  2. The response includes the original parNumber and traceNumber values.
 

 

A transaction received for processing is considered Posted to the receivers account once it completes processing through all participants in the ACH network like the ODFI and RFDI.

Request and response example

  • The transaction availability is based on the effective date (effectiveDate) provided in the ACH Origination API request.
  • There is no association between the ACH Posted inquiry endpoint and the ACH Status Inquiry or ACH Collected Inquiry endpoints at the individual item level. You cannot use the parNumber or traceNumber associated with the ACH Status Inquiry or ACH Collected Inquiry endpoints in the ACH Posted inquiry.

 

Request
{
  "getACHPostedTransactionsRequest": {
    "accountNumber": ["32123456789"],
    "fromDate": "2023-03-15",
    "toDate": "2023-03-15",
    "creditOrDebitCode": "",
    "fromAmount": "",
    "toAmount": "",
    "parNumber": "",
    "startRowIndex": "1",
    "endRowIndex": "1"  }
}
Response
"ACHPostedTransaction": [ {
"snapshotDate": "2023-03-15",
"processDate": "2023-03-15",
"sourceAccountNumber": "32123456789",
"transactionParNumber": "23072003214013",
"transactionAmount": "2078.09",
"creditOrDebitCode": "C",
"baiCode": "165",
"transactionCode": "22",
"regulationDescription1": "DIRECT DEPOSIT ",
"regulationDescription2": "ABC COMPANY",
"postingWindow": "0600"}]

 

What to expect

  1. The ACH Posted endpoint returns results for a client at the account posting level. All results for the ACH origination transactions display at the batch level. 
  2. The batch level summary ACH transaction details that are returned look as how you see them on the DDA statement or in KeyNavigator.
 

We all make mistakes. Sometimes we need to pull things back before we can move forward. KeyBank understands and our API Origination API has a few ways to do that.

You can undo a payment before it is collected by the ACH processor. Use the undo endpoint to stop the transaction before it is received by the ACH processor. The time window to undo is dependent upon the collection windows. The typical window to undo a payment is about 10 minutes but it can be more depending on when the payment is submitted and the collection schedule.

If the payment was collected and you still need to delete the payment, you can reverse the transaction within five banking days from the original effective date. When you reverse the transaction, it generates a reversal to the receiver’s account to pull back payments that were originated erroneously. While reversals are not a guaranteed success, it is an option to undo the original payment submitted after collection.

You must submit the file maintenance form for a payment reversal.

If you are a client of the ACH Origination API, Key Bank recommends the following guidelines for reversing a transaction:

  1. Complete an ACH Originate API request with the opposite credit or debit indicator in the creditDebitCode field of the request body.
  2. Update the companyEntryDescription in the request body to reflect REVERSAL.

A payment can be returned for various reasons like insufficient funds, unable to verify accounts, incorrect data in the request, or a security concern.

KeyBank recommends that you inquire about returns daily with the ACH Inquiry API. Here’s how:

  • To inquire about one or more transactions, use the account number and date fields to look up information.
  • To look up a specific returned transaction, use the PAR number. The PAR number is generated by the API and provided in the response. It is a unique identifier that matches the returned transaction to the original transaction.

 

Unauthorized returns apply mainly to disputed transactions where the person or company being charged does not consent to the funds transfer. There are different return time frames by SEC code so consider the exposure to unauthorized returns when you originate a payment with a certain SEC code. As the originator, if you are debiting an account to collect payments, use the CCD or CTX SEC code. PPD transactions have a longer window for unauthorized returns than CCD and CTX.

 

  Consumer transactions Commercial transactions
SEC code PPD, TEL, WEB CCD, CTX
Unauthorized returns window up to 60 calendar days 24 hours (two banking days)
 

Does ACH stand for Actual Common Help? It sure doesn’t, but we can answer some questions for you!

 

Where is my transaction? How can I get more information?

You submitted a request with the ACH Origination API to send or get money. Get the traceNumber or parNumber from the ACH Origination API response and use that identifier with the ACH Inquiry API request to track the status of the ACH transaction (or batch of transactions).

See our information on the ACH Inquiry API to learn more.

I got an error. What went wrong?

Everything went wrong. And you forgot to send that birthday card too!

OK, it’s not that serious. We can’t fix the birthday card situation, but we can help with that API error.

Check out more information in Errors section of the API documentation for the ACH Origination API or the ACH Inquiry API.

What’s the difference between undo, reversal, and returned?

When you undo a transaction, you stop the ACH processor from receiving the request before the collection window.

For example, let’s say there is a 10-minute window to undo a payment before it is received by the ACH processor. You submit a transaction with the API at 08:15 a.m. EST. You have until 08:25 a.m. EST to undo this transaction before the ACH processor begins to the process the transaction.

When you reverse a transaction, you missed the window to undo a request and now need to submit the file maintenance form for a payment reversal.

When a transaction is returned, it means that something was not right when going through core banking applications for review and settlement. The transaction is returned to the originator without ever being posted.

CCD and PPD seem similar. What is the difference?

PPD transactions are typically from a corporate account to an individual account. Like if you are sending payroll to your employees, you are sending money from a corporate account to a personal account of the employee.

CCD transactions are usually from one commercial or business account to another. It could also be an individual account sending money to a vendor account. One example could be a renter (individual account) sending their rent check to the property management office (business account).

Is there a way to input a value in the request that I recall when using the ACH Inquiry API?

There are two fields available to attached additional information to a transaction.

  1. The entry description (companyEntryDescripiton) describes the purpose of the payment as defined by you. This is required for reporting and helps identify any differences between the transactions. This information is visible to the originator and the receiver.
  2. Use the custom data (customData) field to append specific information to a payment transaction. This information is only visible to the originator can be recalled by the originator after a payment is collected.

    The custom data does not transmit with the payment as it is processed. The custom data is safely stored in KeyBank’s database. The traceNumber links the incoming collected or posted payment to the custom data, recalled from the request input.

What is the timing with payments?

ACH transactions are collected/distributed several times throughout the day. KeyBank’s final cutoff time for clients to send us an ACH file is 09:00 p.m. EST. The schedule is as follows:

# ACH transmission Time (EST)
1 Collection/Distribution 06:00 a.m.
2 Collection 09:30 a.m.
3 Collection/Distribution 11:30 a.m.
4 Collection 02:00 p.m.
5 Collection/Distribution 04:30 p.m.
6 Collection/Distribution 07:00 p.m.
7 Collection/Distribution 09:00 p.m.

 

Can I do same-day payment?

For an additional fee, you can make same-day payments until approximately 03:00 p.m. EST. Funds are withdrawn the date the payment is processed and delivered by the following business day. The account’s available balance is updated when the payment is processed. The account ledger is updated the day after the payment is sent.

What about future date payments?

You can future date a transaction. The payment transaction is processed as normal and collected, but the payment does not post to the bank until the date specified.

Use effectiveDate in the request to specify when a collected transaction is posted. The effective date can be up to 30 days in the future. Typically, the effective date is set 1-2 days before it is posted. When setting the effective date, consider the schedule for collection windows and supporting processes.

Is there a limit to how many transactions I can send in a single request?

The ACH Origination API request is limited to 100 transactions per request for each of KeyBank’s clients. For each of the requests submitted, the clients will receive a message acknowledging either a successful transaction or a transaction error.

Is there a limit to how much money I can send in a same-day transaction?

Total same-day ACH payments cannot exceed $100,000 in a single business day.

Are there client requirements I should know about?

There are some required fields to initiate an ACH transaction. After you complete the KeyBank onboarding process, we will assign you values for point and collection application ID parameters that map to a legitimate bank account.

  • Point (point) is a short name specific to your company that’s assigned by KeyBank. The point name is nine characters long, but KeyBank limits the assigned name to eight characters. One character is used to match the input data of the request associated with this point value to the shared services payment system before batch processing. The point value is included in the file name and improves security for file transfers.
  • Collection application ID (collectionApplicationId) is a sub-level to the point value assigned by KeyBank. Every point requires at least one collection application identifier. The ID must not exceed 9 characters. If you have different settlement accounts, you'll need multiple collection application IDs, each connected to a specific settlement account.

There is another important parameter that is not required, but strongly encouraged. The universal unique identifier (uuid) is a custom value used to identify each transaction created by you. The UUID is required to undo a payment. The ID must not exceed 45 alphanumeric characters. The UUID is only part of the ACH Originate API and is not used to trace a transaction across its lifecycle, meaning it cannot be used as a lookup field in the ACH Inquiry API. The UUID is at the transaction level and provides the status of a specific transaction as Accepted, Waiting for Addenda, Consolidated, or Failed.

How do I send a prenote versus a live transaction?

A prenote (or as my grandfather calls it formerly - the prenotification entry) is a non-monetary entry submitted by an originator to an RDFI before sending a credit or debit entry to the receiver’s account with the RDFI.

A live transaction is a monetary entry submitted by an originator to a RDFI to send a credit or debit to the receiver’s account with the RDFI.

Word soup, right? Basically, a prenote is a notification the tells the RDFI to verify the account information. A live transaction is an actual payment.

In the request, define if the transaction is a prenote (P) or a live (L) transaction with the transactionType field.

 

What's next