Corgi BankDocumentation
OpenAPI

Returns

A return sends an entry back with a reason code. The bank takes returns of entries it originated, and returns entries it received that cannot or should not post.

When an originated entry comes back

The return is recorded at POST /rails/ach/returns with the entry's trace_number and a return_code. Bank staff, the operations service and the FedACH connector may call it. In a sandbox, POST /simulate/transfers/ach/return takes the same body and uses R03 when return_code is left out.

  • Any code in the Nacha return reason table is accepted. An unknown code answers validation_failed on return_code.
  • Only a settled transfer can be returned. Any other state answers payments.transfer_not_settled. A second notice of the same return answers the transfer unchanged.
  • The settlement journal is reversed, dated the current business date. On a credit the money is back in the account. On a debit the money collected is taken back out.
  • The transfer becomes returned with return_code, return_reason (the Nacha title of the code) and reversal_journal_id. hold_id is cleared.
  • A returned prenotification also gets prenote_status returned. It has no journal to reverse.

No event announces the return; see States and notifications. The API has no operation for a dishonored or contested return.

Return rates

Returns of an originator's debits are measured over the sixty days to a date, against the debits it originated in that time. GET /ach-originators/{id}/return-rates reads the figures in basis points.

MeasureCodes countedBreached above
unauthorizedR05, R07, R10, R11, R29, R510.5%
administrativeR02, R03, R043%
overallEvery return15%

A scheduler routine evaluates every originator once per business date and records an ACH Return Rate Evaluation with an action of none, alerted or suspended. A breach suspends an active originator until staff review it, and its new transfers answer payments.originator_suspended. An originator that staff reviewed after its last suspension, inside the same sixty days, is alerted and not suspended again.

Entries the bank returns on receipt

These are decided while the file is processed. Nothing posts for the entry, and the return goes to the ODFI in the return_file of the same call. The receipt has outcome returned with the code.

CodeWhen the bank uses it
R01A debit the available balance does not cover, after the overdraft decision declined to pay it.
R02The account is closed.
R03No account has that number.
R07A debit covered by a stop payment order that records a revoked authorization.
R08A debit covered by any other stop payment order of kind ach_debit.
R16The account is frozen or has a debit block. Also a debit that names a party with a screening match, or that the Gateway Operator flagged.
R17The account or its stop payments could not be read, or a debit could not be screened because compliance did not answer.
R20The account is in another status that is not open, or its product does not allow the debit now.
R24The same ODFI, trace number and settlement date already arrived in an earlier file. Prenotifications are exempt.

A credit that sanctions screening did not clear, or that the Gateway Operator flagged, is not returned on receipt. It is held on the bank's transit account, and POST /ach-receipts/{id}/review decides it: approve, block or return. A return there takes any valid return_code and uses R16 when none is given.

Returning a posted debit as unauthorized

POST /ach-receipts/{id}/return takes a return_code and an operator. It needs payments:write, or the staff scope payments:operations:write.

  • The code must be R05, R07, R10, R11, R29 or R51.
  • The receipt must be a debit with outcome posted. A credit, or a receipt in another outcome, answers conflict.
  • The entry must have settled no more than sixty days before the current business date. Later than that answers payments.return_window_closed.

The receipt's journal is reversed first, so the account has its money back. The receipt becomes returned with reversal_journal_id, and payments.ach_receipt.returned is published. The return file is then sent. If the operator refuses it, the file is sent again by the scheduler and the return still stands.

to move to open esc to close