API and MCP server
The same generator and validator that power the web app are available as a versioned HTTP API and as an MCP server, so payroll and AP automations — or an AI assistant — can produce bank-ready NACHA files directly.
Authentication
Create a key on your account page. The secret is shown once and stored only as a SHA-256 hash. Send it as a bearer token:
Authorization: Bearer ach_live_xxxxxxxxxxxxxxxxxxxxxxxx
Every key is limited to 60 requests per minute. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; a breach returns HTTP 429 with Retry-After.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/ach/validate | Runs every field rule the web generator runs and returns issues indexed by payment. Free. |
| POST | /api/v1/ach/generate | Validates, then returns the NACHA file. Spends one export credit; invalid input never does. |
| POST | /api/v1/ach/inspect | Parses an existing ACH file and reports record errors, control totals, and a masked preview. Free. |
| GET | /api/v1/account | Plan, remaining export credits, monthly usage, and rate-limit state. |
| GET | /api/v1/openapi | The OpenAPI 3.1 description of every endpoint on this page. |
| POST | /api/mcp | MCP Streamable HTTP endpoint exposing the same operations as tools. |
Generating a file
Send the file configuration your bank gave you plus the payment rows. Amounts are strings or numbers in dollars; the response reports cents as strings so large totals survive JSON.
curl https://achfilegenerator.com/api/v1/ach/generate \
-H "Authorization: Bearer $ACH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"configuration": {
"immediateDestination": "021000021",
"immediateDestinationName": "BANK NAME",
"immediateOrigin": "1234567890",
"immediateOriginName": "ACME INC",
"companyName": "ACME INC",
"companyIdentification": "1234567890",
"originatingDfiIdentification": "02100002",
"companyEntryDescription": "PAYROLL",
"effectiveEntryDate": "2026-09-21",
"secCode": "PPD"
},
"payments": [
{
"recipientName": "JANE DOE",
"routingNumber": "021000021",
"accountNumber": "123456789",
"accountType": "checking",
"amount": "1250.00"
}
]
}'{
"file": {
"content": "101 021000021 1234567890...\r\n",
"fileName": "ppd-credit.ach",
"summary": {
"entryCount": 1,
"addendaCount": 0,
"recordCount": 10,
"blockCount": 1,
"entryHash": "2100002",
"totalCreditCents": "125000"
},
"warnings": []
},
"allowance": { "source": "single-run", "remaining": 4 }
}Instead of payments you can post {"csv": {"text": "..."}} with the same CSV a spreadsheet exports; columns are detected by header name and can be overridden with csv.columns. Set "purpose": "prenote" for zero-dollar prenotes and skipBlankAmounts to drop unpaid rows deliberately.
Errors
Every failure uses one envelope. type maps to the HTTP status, code is stable and machine-readable, details points at the offending payment index or field, and requestId is echoed in the X-Request-Id header.
{
"error": {
"type": "invalid_request",
"code": "validation_failed",
"message": "The submitted payments or configuration contain errors.",
"details": [
{
"code": "routing.checkDigit",
"message": "Routing number has an invalid ABA check digit.",
"index": 0,
"field": "routingNumber"
}
],
"requestId": "req_5f2c1c9a1c0f4f1e9b2b6a1d5c7e8f90"
}
}MCP server
The endpoint speaks JSON-RPC 2.0 over the MCP Streamable HTTP transport. Point any MCP client at it with your API key:
{
"mcpServers": {
"ach-file-generator": {
"type": "http",
"url": "https://achfilegenerator.com/api/mcp",
"headers": { "Authorization": "Bearer ach_live_..." }
}
}
}| Tool | What it does |
|---|---|
ach_validate_payments | Validate payment rows or CSV text against NACHA rules. |
ach_generate_file | Generate a NACHA credit or prenote file. Spends one credit. |
ach_inspect_file | Inspect an existing ACH file for structural errors. |
ach_account_usage | Read the account's plan and remaining credits. |
Credits
Validation and inspection are free. Each generated file spends one export credit from the same balance as the browser app: the free first export, a Pro monthly allowance, or an Export Pack credit. When the balance is empty the API answers HTTP 402 with no_export_credit. See pricing.