Returns¶
A Return is a Transaction on the network that reverses or rejects an earlier Transaction. Returns aren't a separate rail or service, they ride the same rail as the original entry (ACH return on ACH, ICL return on ICL) with a return reason code identifying why and a pointer back to the original. Every rail has its own return codes, return windows, and operational practices, but the structure is shared.
This page describes the return concept across all rails, including Automated Returns, GIB's mechanism for returning inbound entries on your behalf based on rules you configure. For the rail-specific operations to originate a return manually, see the relevant rail's service page (e.g. ACH).
What a Return is¶
A Return is itself a Transaction, with these characteristics:
- Same
typeas the original (an ACH return istype=ach) - Direction is the opposite of the original, a return on an outbound entry comes inbound, a return on an inbound entry goes outbound
- Carries a
return_codefield identifying the reason - Carries
trace_reference_originalpointing to the original Transaction'strace_reference - Has its own
trace_reference(the return is its own entry on the network)
When you receive a Return, GIB's webhook payload enriches the raw return record with a top-level return object that resolves the original Transaction (by trace), categorizes the return code, and flags whether it's a Dishonored Return.
Return windows¶
Each rail defines how long a Receiving Depository Financial Institution (RDFI) has to return an entry. Common windows:
| Rail | Standard | Consumer-authorization codes |
|---|---|---|
| ACH | 2 banking days | Up to 60 calendar days for R05, R07, R10, R11, R37, R38, R51 |
| ICL (Check) | 1–2 business days | Longer for forgery and other special cases |
| Domestic Wire | Wire returns are exceptional, not routine, the wire posted; reversal requires receiving-bank cooperation | |
| International Wire | Wire returns vary by destination |
Returns submitted past the window are typically dishonored, see Dishonored and contested returns.
Return code categories¶
While each rail has its own code list, return codes generally fall into a few operational categories:
| Category | Examples | Operational meaning |
|---|---|---|
| Administrative | R01 (insufficient funds), R03 (no account), R04 (invalid structure) | Data was wrong; can typically retry after correction |
| Account state | R02 (account closed), R16 (frozen / OFAC), R20 (not a transaction account) | Stop sending future entries to this receiver |
| Authorization revoked | R05, R07, R10, R11, R29, R37, R38 | Higher stakes, may arrive up to 60 days later. Don't re-present; re-confirm authorization |
| Death-related | R14, R15 | Beneficiary or rep payee deceased; for federal benefits, anticipate reclamation |
For the rail-specific code lists, see ACH, ICL, Domestic Wire, International Wire.
Originating a Return¶
When an inbound entry arrives that you choose not to accept, you can originate a return through the unified return endpoint:
- Create return on a Transaction:
createTransactionReturn
The endpoint accepts the original Transaction's ID and a return code; GIB constructs the appropriate return on the same rail as the original (ACH, ICL, etc.).
For situations where you'll repeatedly need to return inbound entries under defined conditions (account inactive, ACH debits over a threshold, etc.), configure Automated Returns instead. Automated returns are faster, can't miss windows, and don't require operations involvement.
Choosing a return code¶
The right code for the situation is the originator's responsibility. Wrong codes lead to Dishonored Returns or NACHA non-compliance. Two principles:
- Never substitute a code you "think will work" for the right one. R02 is for closed accounts; R29 is for corporate not authorized; R10 is for consumer unauthorized. Misuse has consequences.
- Authorization-related codes are terminal. Codes R05, R07, R10, R11, R29, R37, R38 indicate authorization issues. Don't re-present after one of these without re-confirming authorization with the receiver.
Automated Returns¶
ACH returns can come from two sources: the receiving bank (RDFI), or GIB itself based on rules you configure. The category below, automated returns, is the second: GIB returns an incoming ACH on your behalf because the receiving virtual account, core account, or program rules say so.
Automated returns use standard NACHA return codes, the same codes an external RDFI would use, and they appear to the originating bank identical to any other return. From your perspective, they're a programmatic operational tool that eliminates manual return handling for a defined set of conditions.
Summary table¶
| Feature | data_direction |
Auto-return reason | Trigger | Return code | Configured at |
|---|---|---|---|---|---|
| Inactive Virtual Account | Incoming (we are RDFI) | inactive |
Virtual Account marked inactive | R02 | updateSubclientAccount, set active=false |
| Block ACH Debits | Incoming | debit |
Incoming ACH debits, per-account file total >= $1.00 | R29 | updateSubclientAccount, incoming_behavior=return_debits |
| ACH Overdraft Protection | Incoming | overdraft |
Debit would cause NACHA-defined overdraft | R01 | Bank-set program flag |
| Virtual Account Overdraft Rejection | Outgoing (we are ODFI) | (rejection) | Outgoing transfer would overdraft virtual account | (rejected with HTTP 402 PaymentRequired, not a return) |
updateSubclientAccount, outgoing_va_overdraft_behavior=reject |
| Core Account Overdraft Rejection | Outgoing | (rejection) | Outgoing transfer would overdraft core account | (rejected with HTTP 402 PaymentRequired, not a return) |
Bank-set core-account flag |
The three valid auto-return reasons are: "overdraft", "debit", "inactive".
Originated from external bank¶
These automated returns apply when an external bank originates an ACH transaction toward an account at GIB and a configured condition triggers a return.
Inactive Virtual Account¶
If a Virtual Account is marked active=false, any incoming ACH transaction is automatically returned. The incoming Transaction is marked failed, and a return Transaction with code R02 (Account Closed) is automatically created and delivered to the originating bank.
Block ACH Debits¶
For each Virtual Account, set incoming_behavior=return_debits to automatically return incoming ACH debits originated from outside the bank (external "ACH pull" requests that draw funds out of the account), regardless of the account's balance. The only exception is the micro-deposit carve-out: if an account's incoming debits in a single ACH file total less than the $1.00 threshold, none of them are auto-returned, so account-verification "penny tests" still succeed. Configure via the incoming_behavior field on updateSubclientAccount.
The incoming Transaction is marked failed, and a return Transaction with code R29 (Corporate Customer Advises Not Authorized) is automatically created and delivered.
ACH Overdrafts¶
You can request that the bank turn on a program-level flag automatically returning ACH debits that would cause an overdraft, originating from outside the bank and greater than the debit threshold.
The incoming Transaction is marked failed, and a return Transaction with code R01 (Insufficient Funds) is automatically created and delivered.
NACHA defines overdraft as all pending debits totaling more than the current Available Balance. See Balances → Available Balance for the precise calculation.
ACH Debit Threshold¶
To support account verification flows such as micro-deposits ("penny tests"), the bank applies an automated-return threshold of $1.00 USD. Debits below this amount are excluded from automatic return decisioning (e.g. NSF returns).
This carve-out applies only to GIB's automated-return logic. Sub-dollar debits remain subject to the NACHA Operating Rules, the RDFI's return rights, and the bank's compliance and risk monitoring.
Originated from client¶
These rejections apply when you originate an outbound transaction that violates a program rule. They aren't ACH returns in the NACHA sense, they're pre-submission rejections that prevent a non-compliant transfer from leaving GIB.
Virtual Account Overdraft Rejection¶
For each Virtual Account, set a flag to automatically reject outbound Transactions that would cause an overdraft. Configure via the outgoing_va_overdraft_behavior field on updateSubclientAccount.
If an overdraft is detected, all outbound Transactions for that Virtual Account in the same Batch are rejected together (stored as failed, HTTP 402 PaymentRequired returned).
Core Account Overdraft Rejection¶
For each core account, the bank can set a flag to automatically reject outbound Transactions that would cause an overdraft. Same all-or-nothing behavior: all outbound Transactions for that account in the same Batch are rejected together.
Webhooks for automated returns¶
Automated returns fire the standard inbound transaction state-change webhooks (e.g. inbound_ach_transaction_created, inbound_ach_transaction_processed, inbound_ach_transaction_posted) with the return Transaction's transfer_type set to return and the appropriate return_code. See Webhooks for the full event-type catalog.
For overdraft rejections (HTTP 402 PaymentRequired at submission), no return Transaction is created; the failure surfaces in the original Transaction's state=failed and the API response.
Dishonored and contested returns¶
The original ODFI can reject a return as invalid (wrong code, untimely, malformed) by submitting a dishonored return with codes R61–R70. Common dishonor codes:
| Code | Meaning |
|---|---|
| R61 | Misrouted return |
| R67 | Duplicate return |
| R68 | Untimely return |
| R69 | Multiple errors |
| R70 | Permissible return entry not accepted (no ODFI consent) |
Dishonored returns are operations events, not automated ones. Route them to your operations team rather than retry logic.
The RDFI can in turn contest a dishonor with codes R71 or R72, the rare third bounce. Contested dishonors leave the automated network for resolution; coordinate with the contesting bank's operations team.
Lifecycle¶
Returns follow the standard Transaction state machine.
Webhook events for returns use the standard {direction}_{type}_transaction_{state} pattern; identify a return by the Transaction's transfer_type field (return, iat_return).
Related concepts¶
- Transactions, Returns are themselves Transactions
- ACH, ICL, Domestic Wire, International Wire, rail-specific return codes and operations
- Accounts, where most automated-return policies are configured
- Balances, how Available Balance is computed for overdraft logic
- Webhooks, return event delivery
- Errors, including
return_window_expired