Repository: moov-io/ach
Pull request #823 (2021-01-08 14:39:43)

fix: make addenda optional on CIE batches
This aligns with the spec, which stipulates that while CIE batches can
only have a maximum of one addenda record, including addenda is
optional.


Patch:
diff --git a/README.md b/README.md
index b2bd7f4c..6cb8d8f8 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ moov-io/ach
 
 ACH implements a reader, writer, and validator for Automated Clearing House ([ACH](https://en.wikipedia.org/wiki/Automated_Clearing_House)) files. ACH is the primary method of electronic money movement throughout the United States. The HTTP server is available in a [Docker image](#docker) and the Go package `github.com/moov-io/ach` is available.
 
-If you're looking for a complete implementation of ACH origination (file creation), OFAC checks, micro-deposits, SFTP uploading, and other features the [moov-io/paygate](https://github.com/moov-io/paygate) project aims to be a full system for ACH transfers. Otherwise check out our article on [How and When to use the Moov ACH Library](https://moov.io/blog/tutorials/how-and-when-to-use-the-moov-ach-library/).
+If you're looking for a complete implementation of ACH origination (file creation), OFAC checks, micro-deposits, SFTP uploading, and other features the [moov-io/paygate](https://github.com/moov-io/paygate) project aims to be a full system for ACH transfers. Otherwise, check out our article on [How and When to use the Moov ACH Library](https://moov.io/blog/tutorials/how-and-when-to-use-the-moov-ach-library/).
 
 Docs: [Project](https://moov-io.github.io/ach/) | [API Endpoints](https://moov-io.github.io/ach/api/)
 
@@ -18,11 +18,11 @@ Moov ACH is actively used in multiple production environments. Please star the p
 
 ## Usage
 
-The ACH project implements an HTTP server and Go library for creating and modifying ACH files. There are client libraries available for [Go](..) and [Node/JavaScript](https://github.com/moov-io/ach-node-sdk). The reader and writer are written in Go and [available as a library](https://pkg.go.dev/github.com/moov-io/ach) ([Examples](https://pkg.go.dev/github.com/moov-io/ach@v1.4.1/examples)).
+The ACH project implements an HTTP server and Go library for creating and modifying ACH files. There are client libraries available for [Go](..) and [Node/JavaScript](https://github.com/moov-io/ach-node-sdk). The reader and writer are written in Go and [available as a library](https://pkg.go.dev/github.com/moov-io/ach) ([Examples](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples)).
 
 ### Docker
 
-We publish a [public Docker image `moov/ach`](https://hub.docker.com/r/moov/ach/) from Docker Hub or use this repository. No configuration is required to serve on `:8080` and metrics at `:9090/metrics` in Prometheus format. We also have docker images for [OpenShift](https://quay.io/repository/moov/ach?tab=tags) published as `quay.io/moov/ach`.
+We publish a [public Docker image `moov/ach`](https://hub.docker.com/r/moov/ach/) from Docker Hub or use this repository. No configuration is required to serve on `:8080` and metrics at `:9090/metrics` in Prometheus format. We also have Docker images for [OpenShift](https://quay.io/repository/moov/ach?tab=tags) published as `quay.io/moov/ach`.
 
 Pull & start the Docker image:
 ```
@@ -30,7 +30,7 @@ docker pull moov/ach:latest
 docker run -p 8080:8080 -p 9090:9090 moov/ach:latest
 ```
 
-List files stored in-memory
+List files stored in-memory:
 ```
 curl localhost:8080/files
 ```
@@ -38,7 +38,7 @@ curl localhost:8080/files
 {"files":[],"error":null}
 ```
 
-Create a file on the HTTP server
+Create a file on the HTTP server:
 ```
 curl -XPOST --data-binary "@./test/testdata/ppd-debit.ach" http://localhost:8080/files/create
 ```
@@ -46,7 +46,7 @@ curl -XPOST --data-binary "@./test/testdata/ppd-debit.ach" http://localhost:8080
 {"id":"<YOUR-UNIQUE-FILE-ID>","error":null}
 ```
 
-Read the ACH file (in JSON form)
+Read the ACH file (in JSON form):
 ```
 curl http://localhost:8080/files/<YOUR-UNIQUE-FILE-ID>
 ```
@@ -57,12 +57,12 @@ curl http://localhost:8080/files/<YOUR-UNIQUE-FILE-ID>
 ### Google Cloud Run Button
 To get started in a hosted environment you can deploy this project to the Google Cloud Platform.
 
-From your [Google Cloud dashboard](https://console.cloud.google.com/home/dashboard) create a new project and call it
+From your [Google Cloud dashboard](https://console.cloud.google.com/home/dashboard) create a new project and call it:
 ```
 moov-ach-demo
 ```
 
-Click the button below to deploy this project to Google Cloud
+Click the button below to deploy this project to Google Cloud.
 
 [![Run on Google Cloud](https://deploy.cloud.run/button.svg)](https://deploy.cloud.run/?git_repo=https://github.com/moov-io/ach&revision=master)
 
@@ -106,12 +106,12 @@ Connect to the web preview (e.g. `https://YOUR-ACH-APP-URL.a.run.app:8080/files`
 </details>
 
 
-In the cloud shell you should be prompted with
+In the cloud shell you should be prompted with:
 ```
 Choose a project to deploy this application:
 ```
 
-Using the arrow keys select
+Using the arrow keys select:
 ```
 moov-ach-demo
 ```
@@ -129,65 +129,74 @@ Upon a successful build you will be given a URL where the API has been deployed:
 https://YOUR-ACH-APP-URL.a.run.app
 ```
 
-From the cloud shell you need to cd into the ```ach``` folder
+From the cloud shell you need to cd into the `ach` folder:
 ```
 cd ach
 ```
 
+Now you can list files stored in-memory:
+```
+curl https://YOUR-ACH-APP-URL.a.run.app/files
+```
+You should get this response:
+```
+{"files":[],"error":null}
+```
+
 
-Now you can create a file on the server:
+Create a file on the server:
 ```
 curl -XPOST --data-binary "@./test/testdata/ppd-debit.ach" https://YOUR-ACH-APP-URL.a.run.app/files/create
 ```
 You should get this response:
 ```
-{"id":"c58b75610ac-YOUR-UNIQUE-FILE-ID-9239bf06b93","error":null}
+{"id":"<YOUR-UNIQUE-FILE-ID>","error":null}
 ```
 
 
-Finally read the contents of the file you've just posted:
+Finally, read the contents of the file you've just posted:
 ```
-curl https://YOUR-ACH-APP-URL.a.run.app/files/c58b75610ac-YOUR-UNIQUE-FILE-ID-9239bf06b93
+curl https://YOUR-ACH-APP-URL.a.run.app/files/<YOUR-UNIQUE-FILE-ID>
 ```
 
 You should get this response:
 ```
-{"file":{"id":"c58b75610ac-YOUR-UNIQUE-FILE-ID-9239bf06b93","fileHeader":{"id":"...","immediateDestination":"231380104","immediateOrigin":"121042882", ...
+{"file":{"id":"<YOUR-UNIQUE-FILE-ID>","fileHeader":{"id":"...","immediateDestination":"231380104","immediateOrigin":"121042882", ...
 ```
 
 
-### Go library
+### Go Library
 
-The package [`github.com/moov-io/ach`](https://pkg.go.dev/github.com/moov-io/ach) offers a Go based ACH file reader and writer. To get started checkout a specific example:
+The package [`github.com/moov-io/ach`](https://pkg.go.dev/github.com/moov-io/ach) offers a Go-based ACH file reader and writer. To get started, check out a specific example:
 
 <details>
 <summary>Supported Standard Entry Class (SEC) codes</summary>
 
 | SEC Code | Description                                  | Example                                  | Read                | Write                                            |
 |----------|---------------------------------------|------------------------------------------|-----------------------------------|------------------------------------|
-| ACK      | Acknowledgment Entry for CCD          | [Credit](examples/testdata/ack-read.ach) | [ACK Read](examples/ach-ack-read/main.go) | [ACK Write](examples/ach-ack-write/main.go) |
-| ADV      | Automated Accounting Advice           | [Prenote Debit](test/ach-adv-read/adv-read.ach) | [ADV Read](examples/ach-adv-read/main.go) | [ADV Write](examples/ach-adv-write/main.go) |
-| ARC      | Accounts Receivable Entry             | [Debit](test/ach-arc-read/arc-debit.ach) | [ARC Read](examples/ach-arc-read/main.go) | [ARC Write](examples/ach-arc-write/main.go) |
-| ATX      | Acknowledgment Entry for CTX          | [Credit](test/ach-atx-read/atx-read.ach)  | [ATX Read](examples/ach-atx-read/main.go) | [ATX Write](examples/ach-atx-write/main.go) |
-| BOC      | Back Office Conversion                | [Debit](test/ach-boc-read/boc-debit.ach) | [BOC Read](examples/ach-boc-read/main.go) | [BOC Write](examples/ach-boc-write/main.go) |
-| CCD      | Corporate credit or debit             | [Debit](test/ach-ccd-read/ccd-debit.ach) | [CCD Read](examples/ach-ccd-read/main.go) | [CCD Write](examples/ach-ccd-write/main.go) |
-| CIE      | Customer-Initiated Entry              | [Credit](test/ach-cie-read/cie-credit.ach) | [CIE Read](examples/ach-cie-read/main.go) | [CIE Write](examples/ach-cie-write/main.go) |
-| COR      | Automated Notification of Change(NOC) | [NOC](test/ach-cor-read/cor-read.ach)   | [COR Read](examples/ach-cor-read/main.go) | [COR Write](examples/ach-cor-write/main.go) |
-| CTX      | Corporate Trade Exchange              | [Debit](test/ach-ctx-read/ctx-debit.ach) | [CTX Read](examples/ach-ctx-read/main.go) | [CTX Write](examples/ach-ctx-write/main.go) |
-| DNE      | Death Notification Entry              | [DNE](test/ach-dne-read/dne-read.ach)   | [DNE Read](examples/ach-dne-read/main.go) | [DNE Write](examples/ach-dne-write/main.go) |
-| ENR      | Automatic Enrollment Entry            | [ENR](test/ach-enr-read/enr-read.ach)   | [ENR Read](examples/ach-enr-read/main.go) | [ENR Write](examples/ach-enr-write/main.go) |
-| IAT      | International ACH Transactions        | [Credit](test/ach-iat-read/iat-credit.ach) | [IAT Read](examples/ach-iat-read/main.go) | [IAT Write](examples/ach-iat-write/main.go) |
-| MTE      | Machine Transfer Entry                | [Credit](test/ach-mte-read/mte-read.ach)   | [MTE Read](examples/ach-mte-read/main.go) | [MTE Write](examples/ach-mte-write/main.go) |
-| POP      | Point of Purchase                     | [Debit](test/ach-pop-read/pop-debit.ach) | [POP Read](examples/ach-pop-read/main.go) | [POP Write](examples/ach-pop-write/main.go) |
-| POS      | Point of Sale                         | [Debit](test/ach-pos-read/pos-debit.ach) | [POS Read](examples/ach-pos-read/main.go) | [POS Write](examples/ach-pos-write/main.go) |
-| PPD      | Prearranged payment and deposits      | [Debit](test/ach-ppd-read/ppd-debit.ach) [Credit](test/ach-ppd-read/ppd-credit.ach) | [PPD Read](examples/ach-ppd-read/main.go) | [PPD Write](examples/ach-ppd-write/main.go) |
-| RCK      | Represented Check Entries             | [Debit](test/ach-rck-read/rck-debit.ach) | [RCK Read](examples/ach-rck-read/main.go) | [RCK Write](examples/ach-rck-write/main.go) |
-| SHR      | Shared Network Entry                  | [Debit](test/ach-shr-read/shr-debit.ach) | [SHR Read](examples/ach-shr-read/main.go) | [SHR Write](examples/ach-shr-write/main.go) |
-| TEL      | Telephone-Initiated Entry             | [Debit](test/ach-tel-read/tel-debit.ach) | [TEL Read](examples/ach-tel-read/main.go) | [TEL Write](examples/ach-tel-write/main.go) |
-| TRC      | Truncated Check Entry                 | [Debit](test/ach-trc-read/trc-debit.ach) | [TRC Read](examples/ach-trc-read/main.go) | [TRC Write](examples/ach-trc-write/main.go) |
-| TRX      | Check Truncation Entries Exchange     | [Debit](test/ach-trx-read/trx-debit.ach) | [TRX Read](examples/ach-trx-read/main.go) | [TRX Write](examples/ach-trx-write/main.go) |
-| WEB      | Internet-initiated Entries            | [Credit](test/ach-web-read/web-credit.ach) | [WEB Read](examples/ach-web-read/main.go) | [WEB Write](examples/ach-web-write/main.go) |
-| XCK      | Destroyed Check Entry                 | [Debit](test/ach-xck-read/xck-debit.ach)  | [XCK Read](examples/ach-xck-read/main.go) | [XCK Write](examples/ach-xck-write/main.go) |
+| ACK      | Acknowledgment Entry for CCD          | [Credit](examples/testdata/ack-read.ach) | [ACK Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AckRead) | [ACK Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AckWrite) |
+| ADV      | Automated Accounting Advice           | [Prenote Debit](test/ach-adv-read/adv-read.ach) | [ADV Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AdvRead) | [ADV Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AdvWrite) |
+| ARC      | Accounts Receivable Entry             | [Debit](test/ach-arc-read/arc-debit.ach) | [ARC Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-ArcReadDebit) | [ARC Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-ArcWriteDebit) |
+| ATX      | Acknowledgment Entry for CTX          | [Credit](test/ach-atx-read/atx-read.ach)  | [ATX Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AtxRead) | [ATX Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-AtxWrite) |
+| BOC      | Back Office Conversion                | [Debit](test/ach-boc-read/boc-debit.ach) | [BOC Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-BocReadDebit) | [BOC Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-BocWriteDebit) |
+| CCD      | Corporate credit or debit             | [Debit](test/ach-ccd-read/ccd-debit.ach) | [CCD Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CcdReadDebit) | [CCD Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CcdWriteDebit) |
+| CIE      | Customer-Initiated Entry              | [Credit](test/ach-cie-read/cie-credit.ach) | [CIE Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CieRead) | [CIE Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CieWrite) |
+| COR      | Automated Notification of Change(NOC) | [NOC](test/ach-cor-read/cor-read.ach)   | [COR Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CorReadCredit) | [COR Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CorWriteCredit) |
+| CTX      | Corporate Trade Exchange              | [Debit](test/ach-ctx-read/ctx-debit.ach) | [CTX Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CtxReadDebit) | [CTX Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-CtxWriteDebit) |
+| DNE      | Death Notification Entry              | [DNE](test/ach-dne-read/dne-read.ach)   | [DNE Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-DneRead) | [DNE Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-DneWrite) |
+| ENR      | Automatic Enrollment Entry            | [ENR](test/ach-enr-read/enr-read.ach)   | [ENR Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-EnrRead) | [ENR Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-EnrWrite) |
+| IAT      | International ACH Transactions        | [Credit](test/ach-iat-read/iat-credit.ach) | [IAT Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-IatReadMixedCreditDebit) | [IAT Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-IatWriteMixedCreditDebit) |
+| MTE      | Machine Transfer Entry                | [Credit](test/ach-mte-read/mte-read.ach)   | [MTE Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-MteReadDebit) | [MTE Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-MteWriteDebit) |
+| POP      | Point of Purchase                     | [Debit](test/ach-pop-read/pop-debit.ach) | [POP Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PopReadDebit) | [POP Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PopWriteDebit) |
+| POS      | Point of Sale                         | [Debit](test/ach-pos-read/pos-debit.ach) | [POS Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PosReadDebit) | [POS Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PosWriteDebit) |
+| PPD      | Prearranged payment and deposits      | [Debit](test/ach-ppd-read/ppd-debit.ach) [Credit](test/ach-ppd-read/ppd-credit.ach) | [PPD Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PpdReadCredit) | [PPD Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PpdWriteCredit) |
+| RCK      | Represented Check Entries             | [Debit](test/ach-rck-read/rck-debit.ach) | [RCK Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-RckReadDebit) | [RCK Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-RckWriteDebit) |
+| SHR      | Shared Network Entry                  | [Debit](test/ach-shr-read/shr-debit.ach) | [SHR Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-ShrReadDebit) | [SHR Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-ShrWrite) |
+| TEL      | Telephone-Initiated Entry             | [Debit](test/ach-tel-read/tel-debit.ach) | [TEL Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TelReadDebit) | [TEL Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TelWriteDebit) |
+| TRC      | Truncated Check Entry                 | [Debit](test/ach-trc-read/trc-debit.ach) | [TRC Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TrcReadDebit) | [TRC Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TrcWriteDebit) |
+| TRX      | Check Truncation Entries Exchange     | [Debit](test/ach-trx-read/trx-debit.ach) | [TRX Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TrxReadDebit) | [TRX Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-TrxWriteDebit) |
+| WEB      | Internet-initiated Entries            | [Credit](test/ach-web-read/web-credit.ach) | [WEB Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-WebReadCredit) | [WEB Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-WebWriteCredit) |
+| XCK      | Destroyed Check Entry                 | [Debit](test/ach-xck-read/xck-debit.ach)  | [XCK Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-XckReadDebit) | [XCK Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-XckWriteDebit) |
 
 </details>
 
@@ -196,20 +205,21 @@ The package [`github.com/moov-io/ach`](https://pkg.go.dev/github.com/moov-io/ach
 
 | SEC Code | Name                                  | Example                                  | Read                | Write                                            |
 |----------|---------------------------------------|------------------------------------------|-----------------------------------|------------------------------------|
-| PPD      | Prearranged payment and deposits      | [Debit](test/ach-ppd-read-segmentFile/segmentFile-ppd-debit.ach) [Credit](test/ach-ppd-read-segmentFile/segmentFile-ppd-credit.ach) | [PPD Read](examples/ach-ppd-segmentFile-read/main.go) | [PPD Write](examples/ach-ppd-write-segmentFile/main.go) |
-| IAT      | International ACH Transactions        | [Debit](test/ach-iat-read-segmentFile/segmentFile-iat-debit.ach) [Credit](test/ach-iat-read-segmentFile/segmentFile-iat-credit.ach) | [IAT Read](examples/ach-iat-segmentFile-read/main.go) | [IAT Write](examples/ach-iat-write-segmentFile/main.go) |
+| IAT      | International ACH Transactions        | [Credit](test/ach-iat-read/iat-credit.ach) | [IAT Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-IatReadMixedCreditDebit) | [IAT Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-IatWriteMixedCreditDebit) |
+| PPD      | Prearranged payment and deposits      | [Debit](test/ach-ppd-read/ppd-debit.ach) [Credit](test/ach-ppd-read/ppd-credit.ach) | [PPD Read](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PpdReadSegmentFile) | [PPD Write](https://pkg.go.dev/github.com/moov-io/ach@v1.5.2/examples#example-package-PpdWriteSegmentFile) |
+
 
 </details>
 
 ### Other Languages
 
-Below are some SDK's generated from the API documentation:
+Below are some SDKs generated from the API documentation:
 
 - [Node SDK](https://www.npmjs.com/package/ach-node-sdk) | [GitHub](https://github.com/moov-io/ach-node-sdk)
 
 ### HTTP API
 
-The package [`github.com/moov-io/ach/server`](https://pkg.go.dev/github.com/moov-io/ach/server) offers a HTTP and JSON API for creating and editing files. If you're using Go the `ach.File` type can be used, otherwise just send properly formatted JSON. We have an [example JSON file](test/testdata/ppd-valid.json), but each SEC type will generate different JSON.
+The package [`github.com/moov-io/ach/server`](https://pkg.go.dev/github.com/moov-io/ach/server) offers an HTTP and JSON API for creating and editing files. If you're using Go the `ach.File` type can be used, otherwise just send properly formatted JSON. We have an [example JSON file](test/testdata/ppd-valid.json), but each SEC type will generate different JSON.
 
 Examples: [Go](examples/http/main.go) | [Ruby](https://github.com/moov-io/ruby-ach-demo)
 
@@ -250,13 +260,13 @@ Describing ACH file 'test/testdata/ppd-debit.ach'
 ## Guides
 
 - [ACH File Structure](./docs/file-structure.md)
-- [Balaced offset files](./docs/balanced-offset.md)
+- [Balanced offset files](./docs/balanced-offset.md)
 - [Merging ACH files](./docs/merging-files.md)
 - [ACH Server metrics](./docs/metrics.md)
 
 ### From Source
 
-This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) and uses Go 1.14 or higher. See [Golang's install instructions](https://golang.org/doc/install) for help setting up Go. You can download the source code and we offer [tagged and released versions](https://github.com/moov-io/ach/releases/latest) as well. We highly recommend you use a tagged release for production.
+This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) and Go 1.14 or higher. See [Golang's install instructions](https://golang.org/doc/install) for help in setting up Go. You can download the source code and we offer [tagged and released versions](https://github.com/moov-io/ach/releases/latest) as well. We highly recommend you use a tagged release for production.
 
 ```
 $ git@github.com:moov-io/ach.git
@@ -279,16 +289,15 @@ $ go doc github.com/moov-io/ach BatchHeader
 | `HTTPS_KEY_FILE`  | Filepath of a private key matching the leaf certificate from `HTTPS_CERT_FILE`. | Empty |
 
 
-Note: By design ACH **does not persist** (save) any data about the files, batches or entry details created. The only storage occurs in memory of the process and upon restart ACH will have no files, batches, or data saved. Also, no in memory encryption of the data is performed.
+Note: By design ACH **does not persist** (save) any data about the files, batches, or entry details created. The only storage occurs in memory of the process and upon restart ACH will have no files, batches, or data saved. Also, no in memory encryption of the data is performed.
 
 ## Getting Help
 
-If you have ACH specific questions NACHA (National Automated Clearing House Association) has their [complete specification](docs/2013-Corporate-Rules-and-Guidelines.pdf) for all file formats and message types.
+If you have ACH-specific questions, NACHA (National Automated Clearing House Association) has their [complete specification](docs/2013-Corporate-Rules-and-Guidelines.pdf) for all file formats and message types.
 
  channel | info
  ------- | -------
  [Project Documentation](./docs/#moov-ach) | Our project documentation available online.
- Google Group [moov-users](https://groups.google.com/forum/#!forum/moov-users)| The Moov users Google group is for contributors other people contributing to the Moov project. You can join them without a google account by sending an email to [moov-users+subscribe@googlegroups.com](mailto:moov-users+subscribe@googlegroups.com). After receiving the join-request message, you can simply reply to that to confirm the subscription.
 Twitter [@moov_io](https://twitter.com/moov_io)	| You can follow Moov.IO's Twitter feed to get updates on our project(s). You can also tweet us questions or just share blogs or stories.
 [GitHub Issue](https://github.com/moov-io/ach/issues/new) | If you are able to reproduce a problem please open a GitHub Issue under the specific project that caused the error.
 [moov-io slack](https://slack.moov.io/) | Join our slack channel to have an interactive discussion about the development of the project.
@@ -296,13 +305,13 @@ Twitter [@moov_io](https://twitter.com/moov_io)	| You can follow Moov.IO's Twitt
 ## Supported and Tested Platforms
 
 - 64-bit Linux (Ubuntu, Debian), macOS, and Windows
-- Rasberry Pi
+- Raspberry Pi
 
 Note: 32-bit platforms have known issues and are not supported.
 
 ## Contributing
 
-Yes please! Please review our [Contributing guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) to get started! Checkout our [issues for first time contributors](https://github.com/moov-io/ach/contribute) for something to help out with.
+Yes please! Please review our [Contributing guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) to get started! Check out our [issues for first time contributors](https://github.com/moov-io/ach/contribute) for something to help out with.
 
 This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) and uses Go 1.14 or higher. See [Golang's install instructions](https://golang.org/doc/install) for help setting up Go. You can download the source code and we offer [tagged and released versions](https://github.com/moov-io/ach/releases/latest) as well. We highly recommend you use a tagged release for production.
 
@@ -316,4 +325,4 @@ We currently run fuzzing over ACH in the form of a [`moov/achfuzz`](https://hub.
 
 ## License
 
-Apache License 2.0 See [LICENSE](LICENSE) for details.
+Apache License 2.0 - See [LICENSE](LICENSE) for details.
diff --git a/batchCIE.go b/batchCIE.go
index a20e5728..273ad465 100644
--- a/batchCIE.go
+++ b/batchCIE.go
@@ -66,9 +66,9 @@ func (batch *BatchCIE) Validate() error {
 		if entry.CreditOrDebit() != "C" {
 			return batch.Error("TransactionCode", ErrBatchDebitOnly, entry.TransactionCode)
 		}
-		// CIE must have one Addenda05 record
-		if len(entry.Addenda05) != 1 {
-			return batch.Error("AddendaCount", NewErrBatchRequiredAddendaCount(len(entry.Addenda05), 1))
+		// CIE must have a maximum of one Addenda05 record
+		if len(entry.Addenda05) > 1 {
+			return batch.Error("AddendaCount", NewErrBatchAddendaCount(len(entry.Addenda05), 1))
 		}
 		// Verify the TransactionCode is valid for a ServiceClassCode
 		if err := batch.ValidTranCodeForServiceClassCode(entry); err != nil {


Test patch:
diff --git a/batchCIE_test.go b/batchCIE_test.go
index e450cd6e..00381f0a 100644
--- a/batchCIE_test.go
+++ b/batchCIE_test.go
@@ -248,7 +248,7 @@ func testBatchCIEAddendaCount(t testing.TB) {
 	mockBatch := mockBatchCIE()
 	mockBatch.GetEntries()[0].AddAddenda05(mockAddenda05())
 	err := mockBatch.Create()
-	if !base.Match(err, NewErrBatchRequiredAddendaCount(2, 1)) {
+	if !base.Match(err, NewErrBatchAddendaCount(2, 1)) {
 		t.Errorf("%T: %s", err, err)
 	}
 }
@@ -271,7 +271,7 @@ func testBatchCIEAddendaCountZero(t testing.TB) {
 	mockBatch := NewBatchCIE(mockBatchCIEHeader())
 	mockBatch.AddEntry(mockCIEEntryDetail())
 	err := mockBatch.Create()
-	if !base.Match(err, NewErrBatchRequiredAddendaCount(0, 1)) {
+	if !base.Match(err, nil) {
 		t.Errorf("%T: %s", err, err)
 	}
 }
@@ -296,7 +296,7 @@ func testBatchCIEInvalidAddendum(t testing.TB) {
 	mockBatch.GetEntries()[0].Addenda02 = mockAddenda02()
 	mockBatch.Entries[0].AddendaRecordIndicator = 1
 	err := mockBatch.Create()
-	if !base.Match(err, NewErrBatchRequiredAddendaCount(0, 1)) {
+	if !base.Match(err, ErrBatchAddendaCategory) {
 		t.Errorf("%T: %s", err, err)
 	}
 }
@@ -422,7 +422,7 @@ func TestBatchCIEAddenda(t *testing.T) {
 	// mock batch already has one addenda. Creating two addenda should error
 	mockBatch.GetEntries()[0].AddAddenda05(mockAddenda05())
 	err := mockBatch.Create()
-	if !base.Match(err, NewErrBatchRequiredAddendaCount(2, 1)) {
+	if !base.Match(err, NewErrBatchAddendaCount(2, 1)) {
 		t.Errorf("%T: %s", err, err)
 	}
 }