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

MethodPathPurpose
POST/api/v1/ach/validateRuns every field rule the web generator runs and returns issues indexed by payment. Free.
POST/api/v1/ach/generateValidates, then returns the NACHA file. Spends one export credit; invalid input never does.
POST/api/v1/ach/inspectParses an existing ACH file and reports record errors, control totals, and a masked preview. Free.
GET/api/v1/accountPlan, remaining export credits, monthly usage, and rate-limit state.
GET/api/v1/openapiThe OpenAPI 3.1 description of every endpoint on this page.
POST/api/mcpMCP 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_..." }
    }
  }
}
ToolWhat it does
ach_validate_paymentsValidate payment rows or CSV text against NACHA rules.
ach_generate_fileGenerate a NACHA credit or prenote file. Spends one credit.
ach_inspect_fileInspect an existing ACH file for structural errors.
ach_account_usageRead 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.