NACHA transaction codes
The Transaction Code (positions 2-3 of the Entry Detail Record, type-6) is a 2-digit number that tells the RDFI two things at once: which type of account the entry should hit (checking, savings, GL, or loan), and what kind of entry it is (live debit, live credit, prenote, zero-dollar with remittance, or return/NOC). Get this wrong and the entry posts to the wrong account or gets bounced as R03 / R04 / NOC C05.
Section 1 · The full map Every transaction code in one matrix
The transaction code space is small and orthogonal: 4 account types × roughly 5 entry purposes. The two tables below split it the way you'll actually consume it — the primary matrix covers checking and savings (which is essentially all production traffic), and a separate specialized matrix covers GL and loan codes that exist in the spec but you'll likely never generate.
| Entry purpose | Checking | Savings |
|---|---|---|
| ▾ Credits — money TO receiver | ||
| Live credit (deposit) | 22 | 32 |
| Credit prenote | 23 | 33 |
| Credit zero-$ remit CCD/CTX only | 24 | 34 |
| Credit return / NOC inbound only | 21 | 31 |
| ▾ Debits — money FROM receiver | ||
| Live debit (payment) | 27 | 37 |
| Debit prenote | 28 | 38 |
| Debit zero-$ remit CCD/CTX only | 29 | 39 |
| Debit return / NOC inbound only | 26 | 36 |
| Entry purpose | GL | Loan |
|---|---|---|
| ▾ Credits | ||
| Live credit | 42 | 52 |
| Credit prenote | 43 | 53 |
| Credit zero-$ remit | 44 | 54 |
| Credit return / NOC | 41 | 51 |
| ▾ Debits | ||
| Live debit | 47 | — |
| Debit prenote | 48 | — |
| Debit zero-$ remit | 49 | — |
| Debit return / NOC | 46 | 55 |
account type
entry purpose
(SaaS billing, recurring autopay, etc.)
First digit — what kind of account?
Second digit — what kind of entry?
Read it like an address. "32" = 3 (savings) + 2 (live credit) = automated savings deposit. "27" = 2 (checking) + 7 (live debit) = automated checking payment. "38" = 3 (savings) + 8 (debit prenote). The pattern never breaks.
Reality check on the primary matrix: ~99% of production traffic uses just 4 codes — 22, 27, 32, 37 (the live credit/debit pair for checking + savings). Prenotes (23/28, 33/38) come up only when validating new account info before live entries. Zero-dollar codes (24/29, 34/39) are restricted to CCD/CTX remittance-only entries. Returns/NOCs (21/26, 31/36) appear in your inbound feed from the ODFI, not in files you build. So even within the "primary" set, your day-to-day attention is really 4 codes.
Section 2 · Each code in detail What each transaction code actually does
Below: the codes you'll actually generate or process, grouped by account type. The 4 workhorses (22 / 27 / 32 / 37) get full deep-dives. The supporting codes (prenotes, zero-dollar, returns) get tight summaries because their behavior is identical across account types — the patterns memorize once.
The single most-used transaction code in the entire ACH network. Any time money is being credited (deposited) into a consumer or business checking account, this is the code. Direct deposit payroll, vendor AP runs, government benefits, refunds, P2P transfers in — all 22.
- Receiver's account is a checking / demand deposit account
- The entry is a live, dollar-amount credit (money flowing TO the receiver)
- Examples: payroll, AP vendor payment, tax refund, P2P credit, government benefit deposit
- Receiver's account is a savings / share account → use 32
- You're collecting money from the receiver → that's a debit, use 27
- It's a prenote (zero-dollar account validation) → use 23
- It's a zero-dollar remittance entry alongside CCD/CTX → use 24
Format and pairing
Position in Entry Detail: 2-3 (right after the record type code "6").
Compatible SEC codes: All consumer and business credit-capable SEC codes — PPD, CCD, CTX, WEB (credit), CIE, IAT (when crediting a U.S. checking account). Most batches of 22 entries are PPD (payroll) or CCD (vendor payments).
Service Class Code in Batch Header: Usually 220 (credit-only) when the batch is all 22s, or 200 (mixed) when 22s share a batch with debits.
Amount field: Right-justified, zero-filled, in cents (no decimal). $1,250.00 = 0000125000.
Real file example
The debit equivalent of 22. Any time money is being pulled from a checking account, this is the code. SaaS subscription billing, mortgage payments, utility bills, recurring B2B AR collections — all 27.
- Receiver's account is a checking / demand deposit account
- The entry is a live, dollar-amount debit (money flowing FROM the receiver)
- Examples: subscription billing, utility autopay, mortgage debit, B2B invoice collection
- Receiver's account is savings → use 37
- You're sending money to the receiver → use 22 (credit)
- It's a prenote for a debit → use 28
- You're trying to re-present a bounced check → use 27 BUT under SEC code RCK (not PPD/WEB)
Format and pairing
Compatible SEC codes: All debit-capable SEC codes — PPD, CCD, CTX, WEB (debit), TEL, ARC, POP, BOC, RCK, IAT (debit). Most production volume is PPD/WEB/CCD.
Service Class Code: Usually 225 (debit-only) when the batch is all 27s, or 200 (mixed).
Same-Day eligibility: 27 entries are eligible for Same-Day ACH (subject to the per-entry $1M cap and ODFI cutoffs).
Same as 22 but the receiver's account is a savings (or, at credit unions, a "share") account instead of checking. Functionally identical processing, just routed to a different account type at the RDFI. Common for direct deposits to savings accounts (some employees split their direct deposit into checking + savings) and for member dividend payouts at credit unions.
Use when: Receiver gave you a savings or share account number for credit deposit.
Compatible SEC codes: Same set as 22 — PPD, CCD, CTX, WEB credit, IAT, etc.
Common confusion: Money market accounts at most banks count as savings for ACH purposes (TC 32 / 37), but some institutions treat them as checking (TC 22 / 27). When the RDFI's records disagree with the originator, the result is a C05 NOC asking you to switch the transaction code — not a hard return.
Same as 27 but on a savings account. Less common in practice than 27 because most consumers don't pay bills out of savings — but it's the right code when they do.
Use when: Receiver authorized a debit pulled from a savings or share account.
Compatible SEC codes: Same as 27 — PPD, CCD, WEB debit, TEL, ARC, POP, BOC, RCK, IAT.
Zero-dollar entries used to validate that an account number and routing number combination is real and accepts ACH before sending live entries. Same format as a normal entry, but the amount field is all zeros and the transaction code is one of the prenote variants (one-digit higher than the live equivalent).
23 = prenote of a checking credit (will become 22)
28 = prenote of a checking debit (will become 27)
33 = prenote of a savings credit (will become 32)
38 = prenote of a savings debit (will become 37)
Zero-dollar entries that exist solely to carry remittance information (invoice numbers, EDI segments) when the dollar settlement happens through a separate channel — typically a wire or a bulk ACH. Used in high-volume B2B and healthcare contexts where the remittance and the money are decoupled. Restricted to CCD and CTX SEC codes only.
24 = zero-dollar credit-side remittance, checking
29 = zero-dollar debit-side remittance, checking
34 = zero-dollar credit-side remittance, savings
39 = zero-dollar debit-side remittance, savings
Codes you'll see in your inbound ACH feed from the ODFI, not in files you build. When an RDFI returns one of your entries (because the account doesn't exist, NSF, customer disputed, etc.) or sends a Notification of Change (because account info needs updating), the returned/NOC entry comes back with one of these transaction codes — keyed off whether the original was a credit or debit, and whether it was checking or savings.
21 = return or NOC for an original credit to checking (i.e., reversing a 22, 23, or 24)
26 = return or NOC for an original debit to checking (reversing a 27, 28, or 29)
31 = return or NOC for an original credit to savings (reversing a 32, 33, or 34)
36 = return or NOC for an original debit to savings (reversing a 37, 38, or 39)
Reserved for entries hitting a financial institution's own internal General Ledger account, not a customer-facing checking or savings account. Used between banks or by a bank's internal treasury operations to settle inter-bank obligations, shift money between branches, or post to suspense accounts via ACH. The 4x decade follows the same one's-digit pattern as the 2x and 3x: 42/47 are the live credit/debit pair, 43/48 are prenotes, 44/49 are zero-dollar remittance, 41/46 are returns/NOCs.
You'll generate these if: You work inside a financial institution's payment operations team, or you're building software for one (core banking, treasury management). Otherwise, no.
You'll receive these if: Almost never. GL entries are bank-to-bank, not bank-to-customer, so they don't appear in normal originator inbound feeds.
Origination access: Most ODFIs do not give corporate originator clients permission to send 4x entries. If you try to submit one and your platform allows it, your ODFI's risk team will likely intervene.
Used when the receiver's "account" is a loan balance rather than a depository account. The 5x decade is the only one that's not symmetric across debit and credit — there's no "debit a loan account" entry, because loan disbursement (giving the borrower money) is conceptually a credit to a checking account, not a debit on the loan. Only codes 51-56 exist; the matrix's debit-side, debit-prenote, and debit-zero-$ cells are intentionally empty for loans.
52 = automated deposit to a loan account (i.e., loan payment received, paying down the balance)
53 = prenote of a loan-account credit
54 = zero-dollar with remittance to a loan account (CCD / CTX only)
51 = return / NOC of an original 52, 53, or 54
55 = reversal of a loan transaction (debit-side reverse)
Section 3 · Codes that look alike Side-by-side comparisons of the easy-to-confuse pairs
Transaction codes follow a clean grid pattern, but a few cross-comparisons trip people up in production. The three below cover the questions that actually come up.
| Dimension | 22 (Checking) | 32 (Savings) |
|---|---|---|
| Entry direction | Credit (deposit) | Credit (deposit) |
| Account type at RDFI | Checking / DDA | Savings / share |
| Compatible SEC codes | PPD, CCD, CTX, WEB credit, IAT, etc. | Same set |
| Service Class typically | 220 or 200 | 220 or 200 |
| Common mismatch reaction | C05 NOC ("change to 32") or R03 | C05 NOC ("change to 22") or R03 |
| Best for | Payroll, AP, refunds — primary deposit account | Splits to savings, credit-union member dividends |
| Dimension | 22 (Credit) | 27 (Debit) |
|---|---|---|
| Direction of money | Originator → Receiver | Receiver → Originator |
| Account type | Checking | Checking |
| Service Class typical | 220 (credit-only) | 225 (debit-only) |
| Authorization burden | Light — receiver wants the money | Heavy — receiver must explicitly authorize the pull |
| Unauthorized return window (consumer) | Limited — receiver welcomes credit; not really an "unauthorized" scenario in normal flow | 60 days (R10/R11) — the big risk surface for ACH |
| Common SEC pairings | PPD payroll, CCD AP | WEB SaaS billing, PPD recurring debits, TEL phone-pay, ARC/POP/BOC check conversion |
| What goes wrong if you flip them | You pay the customer when you meant to charge them. Hard to recover via ACH — usually requires a reversal entry within 5 banking days, otherwise it's a manual collections problem | You charge the customer when you meant to pay them. Triggers immediate dispute, potential R10 unauthorized return, and customer-relationship damage |
| Dimension | 22 (Live credit) | 23 (Prenote) |
|---|---|---|
| Direction | Credit | Credit (testing) |
| Amount field | Real dollar amount | All zeros (0000000000) |
| Purpose | Move actual money | Validate account / routing without moving money |
| Wait period before sending live entry | — | 3 banking days minimum after settlement |
| Possible RDFI responses | Posts entry, or returns (R01, R03, R04, R10, etc.) | Returns (R03 No Account, R04 Invalid Account) or NOC (C01-C09 with corrections), or silently posts and accepts |
| WEB account validation compliance | — | Yes — a successfully-posted prenote satisfies the WEB Account Validation Rule for the receiver's account |
| When to skip prenotes | — | Same-day signup flows where 3-day wait is too long; use Plaid / GIACT / Finicity API instead |
Section 4 · Cases where only one code fits Scenarios where the transaction code is forced
Unlike SEC codes — where there's often "wiggle room" between similar codes — transaction codes are mostly forced once you know the receiver's account type and the entry direction. Below are the production scenarios where only one code is correct, and using anything else means a NOC, a return, or worse.