{
  "openapi": "3.1.1",
  "info": {
    "title": "NACHA File Generator API",
    "version": "1.0.0",
    "description": "Generate and validate NACHA (ACH) files from JSON. Free to use: no API key and no account.\n\n- **Limits:** about 30 requests per minute per IP address (per /64 network for IPv6); beyond that, 429 with Retry-After: 60. Request bodies up to 128 KB of JSON, about 500 entries; larger ones get 413. The body must be sent as application/json (or another application/*+json type); anything else gets 415.\n- **Privacy:** requests are processed in memory. Request bodies and generated files are never stored or logged; the only records kept are an anonymous count of files generated and, when a request fails, an error log line with its method and path.\n- **Scope:** the API builds files from JSON. It does not read existing .ach, X9 or BAI2 files: the browser tools at https://nacha-navigator.com do that, without uploading them.\n- **Checks:** both operations run the same checks in this order: the body must be JSON, then its structure (every required key present, no unknown keys, every value a string of the right shape), then the NACHA rules. validateNachaFile also reports warnings that do not block the file.\n- **Browsers:** the API sends no CORS headers. Call it from a server or a script.\n- NACHA Navigator is independent and not affiliated with or endorsed by Nacha. Check generated files against the current Nacha Operating Rules and your bank's requirements before relying on them.",
    "contact": {
      "name": "NACHA Navigator",
      "url": "https://nacha-navigator.com/about"
    }
  },
  "externalDocs": {
    "description": "API reference with examples and every error message",
    "url": "https://nacha-navigator.com/nacha-generator/api"
  },
  "servers": [
    {
      "url": "https://nacha-navigator.com/api/v1/nacha"
    }
  ],
  "security": [],
  "paths": {
    "/generate": {
      "post": {
        "operationId": "generateNachaFile",
        "summary": "Generate a NACHA file",
        "description": "Validates the request and returns the NACHA file as text/plain, with Content-Disposition: attachment; filename=nacha_file.txt: 94-character records in uppercase ASCII, each ending in a line feed, padded with all-9 records to a multiple of ten. Optional fields left out get the defaults their descriptions give (dates and times in America/New_York). A request that fails a check gets a JSON error instead.",
        "requestBody": {
          "required": true,
          "description": "The file to build, as JSON. The same body works for both operations.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NachaFileRequest"
              },
              "examples": {
                "quickStart": {
                  "summary": "Quick start: one PPD credit",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "200",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_name": "JOHN DOE"
                          }
                        ]
                      }
                    ]
                  }
                },
                "basic": {
                  "summary": "One batch, one entry, with names",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890",
                      "immediate_destination_name": "DESTINATION BANK",
                      "immediate_origin_name": "ORIGIN COMPANY"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "220",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_id": "EMP123",
                            "individual_name": "JOHN DOE"
                          }
                        ]
                      }
                    ]
                  }
                },
                "complex": {
                  "summary": "Two batches, several entries and an addenda record",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890",
                      "file_id_modifier": "A",
                      "immediate_destination_name": "DESTINATION BANK",
                      "immediate_origin_name": "ORIGIN COMPANY",
                      "reference_code": "SEP2026"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "220",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_id": "EMP123",
                            "individual_name": "JOHN DOE",
                            "addenda": [
                              {
                                "payment_related_info": "EMPLOYEE ID 12345, PAY PERIOD 09/01/2026-09/15/2026"
                              }
                            ]
                          },
                          {
                            "transaction_code": "32",
                            "receiving_dfi_id": "011000138",
                            "dfi_account_number": "987654321",
                            "amount": "150000",
                            "individual_id": "EMP456",
                            "individual_name": "JANE SMITH"
                          }
                        ]
                      },
                      {
                        "batch_header": {
                          "service_class_code": "225",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "CCD",
                          "company_entry_description": "INVOICE",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "27",
                            "receiving_dfi_id": "121000248",
                            "dfi_account_number": "543210987",
                            "amount": "250000",
                            "individual_id": "INV-7731",
                            "individual_name": "ACME SUPPLIES"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The NACHA file.",
            "headers": {
              "Content-Disposition": {
                "description": "Always this value.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "attachment; filename=nacha_file.txt"
                  ]
                }
              }
            },
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON, has the wrong structure, or breaks a NACHA rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestError"
                },
                "examples": {
                  "badJson": {
                    "summary": "Not valid JSON",
                    "value": {
                      "error": "Bad request",
                      "message": "Failed to decode JSON object"
                    }
                  },
                  "structure": {
                    "summary": "Structure error",
                    "description": "The basic example without immediate_origin, and with the amount written as \"1000.00\".",
                    "value": {
                      "details": {
                        "batches": {
                          "0": {
                            "entries": {
                              "0": {
                                "amount": [
                                  "String does not match expected pattern."
                                ]
                              }
                            }
                          }
                        },
                        "file_header": {
                          "immediate_origin": [
                            "Missing data for required field."
                          ]
                        }
                      },
                      "error": "Invalid input data"
                    }
                  },
                  "rules": {
                    "summary": "NACHA rule error",
                    "description": "The basic example with an empty company_name.",
                    "value": {
                      "details": [
                        "Batch 1: Missing required field: company_name"
                      ],
                      "error": "NACHA validation failed"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 128 KB (about 500 entries).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "tooLarge": {
                    "summary": "Body too large",
                    "value": {
                      "error": "Payload too large",
                      "message": "The request body must be 128 KB or less: about 500 entries. Send a larger payment run as several files."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The Content-Type is not application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notJson": {
                    "summary": "Not JSON",
                    "value": {
                      "error": "Request must be JSON"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "More than about 30 requests a minute from one IP address (one /64 network for IPv6).",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before trying again.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "60"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rateLimited": {
                    "summary": "Rate limited",
                    "value": {
                      "error": "Rate limit exceeded"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected failure on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal": {
                    "summary": "Internal error",
                    "value": {
                      "error": "Internal server error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/validate": {
      "post": {
        "operationId": "validateNachaFile",
        "summary": "Validate NACHA file data",
        "description": "Runs the same checks as generateNachaFile without writing a file, and reports warnings: findings that do not block the file but may get it rejected, such as a routing number that fails its check digit. A 200 means the request passes the checks; it doesn't mean a bank will accept the file.",
        "requestBody": {
          "required": true,
          "description": "The file to build, as JSON. The same body works for both operations.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NachaFileRequest"
              },
              "examples": {
                "quickStart": {
                  "summary": "Quick start: one PPD credit",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "200",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_name": "JOHN DOE"
                          }
                        ]
                      }
                    ]
                  }
                },
                "basic": {
                  "summary": "One batch, one entry, with names",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890",
                      "immediate_destination_name": "DESTINATION BANK",
                      "immediate_origin_name": "ORIGIN COMPANY"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "220",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_id": "EMP123",
                            "individual_name": "JOHN DOE"
                          }
                        ]
                      }
                    ]
                  }
                },
                "complex": {
                  "summary": "Two batches, several entries and an addenda record",
                  "value": {
                    "file_header": {
                      "immediate_destination": "123456780",
                      "immediate_origin": "1234567890",
                      "file_id_modifier": "A",
                      "immediate_destination_name": "DESTINATION BANK",
                      "immediate_origin_name": "ORIGIN COMPANY",
                      "reference_code": "SEP2026"
                    },
                    "batches": [
                      {
                        "batch_header": {
                          "service_class_code": "220",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "PPD",
                          "company_entry_description": "PAYROLL",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "22",
                            "receiving_dfi_id": "021000021",
                            "dfi_account_number": "123456789",
                            "amount": "100000",
                            "individual_id": "EMP123",
                            "individual_name": "JOHN DOE",
                            "addenda": [
                              {
                                "payment_related_info": "EMPLOYEE ID 12345, PAY PERIOD 09/01/2026-09/15/2026"
                              }
                            ]
                          },
                          {
                            "transaction_code": "32",
                            "receiving_dfi_id": "011000138",
                            "dfi_account_number": "987654321",
                            "amount": "150000",
                            "individual_id": "EMP456",
                            "individual_name": "JANE SMITH"
                          }
                        ]
                      },
                      {
                        "batch_header": {
                          "service_class_code": "225",
                          "company_name": "COMPANY ABC",
                          "company_id": "1234567890",
                          "standard_entry_class": "CCD",
                          "company_entry_description": "INVOICE",
                          "originating_dfi_id": "123456780"
                        },
                        "entries": [
                          {
                            "transaction_code": "27",
                            "receiving_dfi_id": "121000248",
                            "dfi_account_number": "543210987",
                            "amount": "250000",
                            "individual_id": "INV-7731",
                            "individual_name": "ACME SUPPLIES"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request passes every check.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationResult"
                },
                "examples": {
                  "valid": {
                    "summary": "Valid",
                    "value": {
                      "message": "NACHA data validation successful",
                      "valid": true
                    }
                  },
                  "withWarning": {
                    "summary": "Valid, with a warning",
                    "description": "The basic example with receiving_dfi_id 021000022.",
                    "value": {
                      "message": "NACHA data validation successful",
                      "valid": true,
                      "warnings": [
                        {
                          "code": "aba-check-digit",
                          "message": "Batch 1: Entry 1: receiving_dfi_id 021000022 fails the ABA routing number check digit test",
                          "path": "batches.0.entries.0.receiving_dfi_id",
                          "severity": "warning"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON, has the wrong structure, or breaks a NACHA rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestError"
                },
                "examples": {
                  "badJson": {
                    "summary": "Not valid JSON",
                    "value": {
                      "error": "Bad request",
                      "message": "Failed to decode JSON object",
                      "valid": false
                    }
                  },
                  "structure": {
                    "summary": "Structure error",
                    "description": "The basic example without immediate_origin, and with the amount written as \"1000.00\".",
                    "value": {
                      "details": {
                        "batches": {
                          "0": {
                            "entries": {
                              "0": {
                                "amount": [
                                  "String does not match expected pattern."
                                ]
                              }
                            }
                          }
                        },
                        "file_header": {
                          "immediate_origin": [
                            "Missing data for required field."
                          ]
                        }
                      },
                      "error": "Invalid input data structure",
                      "valid": false
                    }
                  },
                  "rules": {
                    "summary": "NACHA rule error",
                    "description": "The basic example with an empty company_name.",
                    "value": {
                      "details": [
                        "Batch 1: Missing required field: company_name"
                      ],
                      "error": "NACHA validation failed",
                      "valid": false
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 128 KB (about 500 entries).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "tooLarge": {
                    "summary": "Body too large",
                    "value": {
                      "error": "Payload too large",
                      "message": "The request body must be 128 KB or less: about 500 entries. Send a larger payment run as several files."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The Content-Type is not application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notJson": {
                    "summary": "Not JSON",
                    "value": {
                      "error": "Request must be JSON",
                      "valid": false
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "More than about 30 requests a minute from one IP address (one /64 network for IPv6).",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before trying again.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "60"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rateLimited": {
                    "summary": "Rate limited",
                    "value": {
                      "error": "Rate limit exceeded"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected failure on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal": {
                    "summary": "Internal error",
                    "value": {
                      "error": "Internal server error",
                      "valid": false
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "NachaFileRequest": {
        "type": "object",
        "description": "A NACHA file to generate or validate: a file header and at least one batch. Every value is a JSON string, amounts and codes included (\"100000\", not 100000). Leave optional keys out rather than sending null; unknown keys are rejected. Control records, totals, the entry hash and block padding are computed.",
        "required": [
          "file_header",
          "batches"
        ],
        "properties": {
          "file_header": {
            "$ref": "#/components/schemas/FileHeader"
          },
          "batches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Batch"
            },
            "minItems": 1
          }
        },
        "additionalProperties": false
      },
      "FileHeader": {
        "type": "object",
        "description": "The file header record (type 1).",
        "required": [
          "immediate_destination",
          "immediate_origin"
        ],
        "properties": {
          "priority_code": {
            "type": "string",
            "pattern": "^[0-9]{2}$",
            "description": "Priority of the file. 2 digits (defaults to '01', the only value in use). Written at positions 2-3 of the file header record."
          },
          "immediate_destination": {
            "type": "string",
            "maxLength": 10,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Routing number of the ACH Operator or receiving point. 9 digits, can have a leading space. Written at positions 4-13 of the file header record."
          },
          "immediate_origin": {
            "type": "string",
            "maxLength": 10,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Routing number or other identifier of the originating institution. 9 digits, can have a leading space; or a 10-character identifier agreed with your ODFI. Written at positions 14-23 of the file header record."
          },
          "file_creation_date": {
            "type": "string",
            "pattern": "^[0-9]{6}$",
            "description": "Date the file was created. YYMMDD format (defaults to current date, America/New_York). Written at positions 24-29 of the file header record."
          },
          "file_creation_time": {
            "type": "string",
            "pattern": "^[0-9]{4}$",
            "description": "Time the file was created. HHMM format, 24-hour (defaults to current time, America/New_York). Written at positions 30-33 of the file header record."
          },
          "file_id_modifier": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Distinguishes between multiple files created on same date. A-Z, 0-9 (defaults to 'A'). Written at positions 34 of the file header record."
          },
          "record_size": {
            "type": "string",
            "pattern": "^[0-9]{3}$",
            "description": "Size of each record. 094 (default; no other value is valid). Written at positions 35-37 of the file header record."
          },
          "blocking_factor": {
            "type": "string",
            "pattern": "^[0-9]{2}$",
            "description": "Number of records in a block. 10 (default; no other value is valid). Written at positions 38-39 of the file header record."
          },
          "format_code": {
            "type": "string",
            "enum": [
              "1"
            ],
            "description": "Format code. 1 (default). Written at positions 40 of the file header record."
          },
          "immediate_destination_name": {
            "type": "string",
            "maxLength": 23,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Name of the destination institution. Up to 23 characters. Written at positions 41-63 of the file header record."
          },
          "immediate_origin_name": {
            "type": "string",
            "maxLength": 23,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Name of the originating institution. Up to 23 characters. Written at positions 64-86 of the file header record."
          },
          "reference_code": {
            "type": "string",
            "maxLength": 8,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Reference code for the file. Up to 8 characters. Written at positions 87-94 of the file header record."
          }
        },
        "additionalProperties": false
      },
      "Batch": {
        "type": "object",
        "description": "A batch: its header and at least one entry. The batch control record is computed.",
        "required": [
          "batch_header",
          "entries"
        ],
        "properties": {
          "batch_header": {
            "$ref": "#/components/schemas/BatchHeader"
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Entry"
            },
            "minItems": 1
          }
        },
        "additionalProperties": false
      },
      "BatchHeader": {
        "type": "object",
        "description": "The batch header record (type 5).",
        "required": [
          "service_class_code",
          "company_name",
          "company_id",
          "standard_entry_class",
          "company_entry_description",
          "originating_dfi_id"
        ],
        "properties": {
          "service_class_code": {
            "type": "string",
            "enum": [
              "200",
              "220",
              "225"
            ],
            "description": "Code indicating the type of entries in the batch. 200 (mixed debits and credits), 220 (credits only) or 225 (debits only). Written at positions 2-4 of the batch header record."
          },
          "company_name": {
            "type": "string",
            "maxLength": 16,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Name of the company/organization. Up to 16 characters. Written at positions 5-20 of the batch header record."
          },
          "company_discretionary_data": {
            "type": "string",
            "maxLength": 20,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "For discretionary use. Up to 20 characters. Written at positions 21-40 of the batch header record."
          },
          "company_id": {
            "type": "string",
            "maxLength": 10,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Company identification number. Up to 10 characters. Written at positions 41-50 of the batch header record."
          },
          "standard_entry_class": {
            "type": "string",
            "enum": [
              "PPD",
              "CCD",
              "CTX",
              "WEB",
              "TEL",
              "ARC",
              "BOC",
              "POP"
            ],
            "description": "Code identifying the type of entries. PPD, CCD, CTX, WEB, TEL, ARC, BOC or POP. Written at positions 51-53 of the batch header record."
          },
          "company_entry_description": {
            "type": "string",
            "maxLength": 10,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Description of the entries. Up to 10 characters. Written at positions 54-63 of the batch header record."
          },
          "company_descriptive_date": {
            "type": "string",
            "pattern": "^[0-9]{6}$",
            "description": "Descriptive date for the company. YYMMDD format (defaults to current date). Written at positions 64-69 of the batch header record."
          },
          "effective_entry_date": {
            "type": "string",
            "pattern": "^[0-9]{6}$",
            "description": "Date the entries should be settled. YYMMDD format (defaults to the next banking day: weekdays except Federal Reserve holidays). Written at positions 70-75 of the batch header record."
          },
          "settlement_date": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Settlement date filled by ACH Operator. 3 characters (leave it out; defaults to blanks). Written at positions 76-78 of the batch header record."
          },
          "originator_status_code": {
            "type": "string",
            "enum": [
              "1",
              "2"
            ],
            "description": "Code identifying the status of the originator. 1 (default) or 2. Written at positions 79 of the batch header record."
          },
          "originating_dfi_id": {
            "type": "string",
            "pattern": "^[0-9]{9}$",
            "description": "Routing number of the originating institution. 9 digits (the first 8 are written; the 9th is the check digit). Written at positions 80-87 of the batch header record."
          },
          "batch_number": {
            "type": "string",
            "pattern": "^[0-9]{1,7}$",
            "description": "Batch sequence number. Up to 7 digits, ascending through the file (defaults to the previous batch number plus 1, starting at 1). Written at positions 88-94 of the batch header record."
          }
        },
        "additionalProperties": false
      },
      "Entry": {
        "type": "object",
        "description": "An entry detail record (type 6) and its addenda records.",
        "required": [
          "transaction_code",
          "receiving_dfi_id",
          "dfi_account_number",
          "amount",
          "individual_name"
        ],
        "properties": {
          "transaction_code": {
            "type": "string",
            "enum": [
              "22",
              "23",
              "27",
              "28",
              "32",
              "33",
              "37",
              "38"
            ],
            "description": "Code identifying the type of transaction. 22 (checking credit), 23 (checking credit prenote), 27 (checking debit), 28 (checking debit prenote), 32 (savings credit), 33 (savings credit prenote), 37 (savings debit) or 38 (savings debit prenote). Written at positions 2-3 of the entry detail record (PPD/CCD layout)."
          },
          "receiving_dfi_id": {
            "type": "string",
            "pattern": "^[0-9]{9}$",
            "description": "Routing number of the receiving institution (including check digit). 9 digits (complete routing number). Written at positions 4-12 of the entry detail record (PPD/CCD layout)."
          },
          "dfi_account_number": {
            "type": "string",
            "maxLength": 17,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Account number at the receiving institution. Up to 17 characters. Written at positions 13-29 of the entry detail record (PPD/CCD layout)."
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,10}$",
            "description": "Amount of the transaction in cents. Up to 10 digits (e.g., 100000 = $1,000.00); 0 for prenotes. Written at positions 30-39 of the entry detail record (PPD/CCD layout)."
          },
          "individual_id": {
            "type": "string",
            "maxLength": 15,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Identification number for the individual. Up to 15 characters (ARC/BOC: the check serial number; POP: check serial number in characters 1-9, terminal city 10-13, terminal state 14-15). Written at positions 40-54 of the entry detail record (PPD/CCD layout)."
          },
          "individual_name": {
            "type": "string",
            "maxLength": 22,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Name of the individual. Up to 22 characters (CTX: up to 16, written at positions 59-74). Written at positions 55-76 of the entry detail record (PPD/CCD layout)."
          },
          "discretionary_data": {
            "type": "string",
            "maxLength": 2,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "For discretionary use. Up to 2 characters (WEB/TEL: the optional payment type code, usually R or S). Written at positions 77-78 of the entry detail record (PPD/CCD layout)."
          },
          "trace_number": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "Unique identifier for the transaction. Up to 15 digits, unique within the file (defaults to the ODFI routing prefix plus a 7-digit sequence number). Written at positions 80-94 of the entry detail record (PPD/CCD layout). Duplicates are rejected, compared as 15 digits (\"1\" equals \"000000000000001\")."
          },
          "addenda": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Addenda"
            },
            "description": "Addenda records (type 7) for the entry. PPD, CCD and WEB entries carry at most one and CTX entries up to 9,999; TEL, ARC, BOC and POP entries carry none (validateNachaFile warns otherwise). More than 9,999 is an error."
          }
        },
        "additionalProperties": false
      },
      "Addenda": {
        "type": "object",
        "description": "An addenda record (type 7).",
        "required": [
          "payment_related_info"
        ],
        "properties": {
          "addenda_type_code": {
            "type": "string",
            "enum": [
              "05"
            ],
            "description": "Type of addenda record. 05 (default). Written at positions 2-3 of the addenda record."
          },
          "payment_related_info": {
            "type": "string",
            "maxLength": 80,
            "pattern": "^[\\x20-\\x7E]*$",
            "description": "Additional information about the payment. Up to 80 characters. Written at positions 4-83 of the addenda record."
          },
          "addenda_sequence_number": {
            "type": "string",
            "pattern": "^[0-9]{1,4}$",
            "description": "Sequence number for multiple addenda records. Up to 4 digits (defaults to the record's position: 1, 2, 3 and so on). Written at positions 84-87 of the addenda record."
          }
        },
        "additionalProperties": false
      },
      "ValidationResult": {
        "type": "object",
        "required": [
          "message",
          "valid"
        ],
        "properties": {
          "message": {
            "type": "string",
            "enum": [
              "NACHA data validation successful"
            ]
          },
          "valid": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "warnings": {
            "type": "array",
            "description": "Present only when there is something to report.",
            "items": {
              "$ref": "#/components/schemas/Warning"
            }
          }
        }
      },
      "Warning": {
        "type": "object",
        "description": "A finding that doesn't block the file. The codes and their meanings are listed at https://nacha-navigator.com/nacha-generator/api#warnings.",
        "required": [
          "code",
          "message",
          "path",
          "severity"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable code, such as \"aba-check-digit\"."
          },
          "message": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Dot path of the field in the request, such as \"batches.0.entries.0.receiving_dfi_id\"."
          },
          "severity": {
            "type": "string",
            "enum": [
              "warning",
              "info"
            ]
          }
        }
      },
      "RequestError": {
        "type": "object",
        "description": "A request that fails a check. \"details\" is keyed by field for a structure error and a list of messages for a NACHA rule error; a body that is not valid JSON gets \"message\" instead. On /validate, \"valid\" is false.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "Bad request",
              "Invalid input data",
              "Invalid input data structure",
              "NACHA validation failed"
            ]
          },
          "message": {
            "type": "string"
          },
          "details": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SchemaErrors"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "valid": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "SchemaErrors": {
        "type": "object",
        "description": "Structure errors keyed by field name; list items are keyed by their index as a string (\"0\"), and messages about an object itself are under \"_schema\".",
        "additionalProperties": {
          "oneOf": [
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            {
              "$ref": "#/components/schemas/SchemaErrors"
            }
          ]
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "valid": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Sent by /validate on 415 and 500."
          }
        }
      }
    }
  }
}