You need to confirm whether ABA routing number 121000358 is valid, which bank it belongs to, and whether it can be used for an ACH payment before you send or accept a transfer. By the end of this guide, you’ll be able to validate routing number 121000358 in code, interpret the returned metadata (bank name, address, status), and integrate routing checks into your onboarding or payout flows using the BankDataStack API.
What 121000358 Identifies and When to Use It
ABA routing number 121000358 is a nine‑digit U.S. bank identifier used to route domestic payments. In the sample response below, it resolves to Bank Of America, N.A., and the API confirms it as active for ACH payments. Use a routing number when:
- Setting up ACH debits/credits (e.g., payroll, vendor payouts, customer debits).
- Collecting bank details during onboarding (KYC/KYB) to prevent misrouted funds.
- Reconciling returns by validating that a routing number is active and belongs to the expected institution.
Routing numbers include an internal checksum that helps catch typos. However, checksum alone cannot tell you the bank name, address, or whether the number is currently active for a payment rail—use the API to verify those details in real time.
Validate 121000358 via API
BankDataStack provides a single POST endpoint for U.S. routing numbers. You’ll send the routing number and optionally the payment type (such as “ach”) to receive the bank identity and operational status.
cURL example (copy/paste)
curl -X POST "https://www.bankdatastack.com/api/v1/routing/validate" -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" -d '{"routing_number":"121000358","payment_type":"ach"}'
Official JSON response
{
"status": "success",
"data": {
"routingNumber": "121000358",
"paymentType": "ach",
"name": "Bank Of America, N.a.",
"addressFull": "8001 Villa Park Drive, Henrico, VA 23228",
"street": "8001 Villa Park Drive",
"city": "Henrico",
"state": "VA",
"zip": "23228",
"type": "Main Office",
"phone": "800-446-0135",
"active": true,
"lastUpdated": "2026-10-17",
"address": "8001 VILLA PARK DRIVE"
}
}
Key fields you’ll use:
- data.routingNumber: Echoed input to confirm what the API validated (121000358).
- data.name: Bank legal name resolving from the routing number.
- data.paymentType: Echoed payment type (“ach”) so you can branch logic by rail if needed.
- data.active: Boolean that indicates whether the routing number is currently active.
- data.type: Facility classification, often “Main Office” or “Branch.”
- data.address/addressFull/city/state/zip: Location metadata—useful for risk checks and user-facing confirmation.
- data.phone: Institution contact number for escalations.
- data.lastUpdated: Reference data freshness indicator you can log or use for cache invalidation.
Python code to validate and enforce ACH readiness
This example calls the same endpoint, reads the response, and shows how to gate an ACH setup on a verified, active routing number that matches the user’s declared bank.
import json
import requests
API_KEY = "YOUR_API_KEY"
URL = "https://www.bankdatastack.com/api/v1/routing/validate"
def validate_routing_for_ach(routing_number: str, expected_bank_name: str | None = None) -> dict:
payload = {
"routing_number": routing_number,
"payment_type": "ach"
}
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
resp = requests.post(URL, headers=headers, data=json.dumps(payload), timeout=10)
# Handle non-2xx as operational failures; retry or surface error to ops.
resp.raise_for_status()
body = resp.json()
if body.get("status") != "success" or "data" not in body:
raise ValueError("Routing validation failed or not found")
data = body["data"]
# Basic checks you might apply in onboarding or payouts
if not data.get("active", False):
raise ValueError(f"Routing number {routing_number} is not active for ACH")
if expected_bank_name:
# Simple containment check; consider stricter normalization in production.
if expected_bank_name.lower() not in data.get("name", "").lower():
raise ValueError(
f"Bank mismatch: provided '{expected_bank_name}' vs lookup '{data.get('name')}'"
)
# Return normalized record to upstream services for audit and caching
return {
"routingNumber": data.get("routingNumber"),
"bankName": data.get("name"),
"addressFull": data.get("addressFull"),
"city": data.get("city"),
"state": data.get("state"),
"zip": data.get("zip"),
"type": data.get("type"),
"phone": data.get("phone"),
"active": data.get("active"),
"lastUpdated": data.get("lastUpdated"),
"paymentType": data.get("paymentType")
}
if __name__ == "__main__":
record = validate_routing_for_ach("121000358", expected_bank_name="Bank of America")
print(json.dumps(record, indent=2))
How to embed routing checks into your flow
Most teams place routing validation in two spots: during account collection (to prevent bad data from entering the system) and right before initiating a transfer (to catch late-breaking deactivations). Here’s a pragmatic approach:
- Onboarding UI: As soon as a user finishes entering a routing number, send it to the validation endpoint. Show the resolved bank name and city/state back to the user for confirmation. If active is false, block submission and request a corrected number.
- Backend normalization: Store the normalized bank name and address fields returned by the API alongside the user’s payment method profile for audits and support.
- Pre‑transfer check: Before scheduling an ACH, revalidate the routing number if your cached record is older than your chosen TTL (see caching section below) or if lastUpdated in your record is older than what you expect.
- Mismatch handling: If the resolved bank name differs from what the user typed, prompt for confirmation or require documentary evidence (this reduces misroutes and social‑engineering attempts).
Understanding routing number format and checksum
ABA routing numbers have nine digits. The first eight digits encode the Federal Reserve routing symbol and the institution identifier; the ninth is a checksum. A common integrity check uses a weighted sum of the first eight digits (weights 3, 7, and 1 repeating) and verifies that the total modulo 10 yields zero when including the checksum digit. This detects most single‑digit errors and some transpositions.
Checksum validity does not guarantee that a routing number is active for ACH or that it belongs to the institution you expect. The API augments the checksum with authoritative bank identity and status indicators so that you can make informed payment decisions.
ACH vs. other identifiers (what to use and when)
Teams often conflate multiple identifiers during integration. Use this quick comparison to keep them straight when building finance workflows:
| Identifier | Region / Usage | Length & Structure | Checksum | What It Identifies | BankDataStack Endpoint |
|---|---|---|---|---|---|
| ABA Routing Number | United States (domestic ACH/wire) | 9 digits | Yes (weighted mod 10) | US depository institution and location | /api/v1/routing/validate |
| SWIFT/BIC | Global (cross‑border) | 8 or 11 characters | Not a numeric checksum | Bank and branch internationally | /api/v1/swift/validate |
| IBAN | Many countries outside the US | Country‑specific length | Yes (mod 97) | Account number routed via country code and bank code | /api/v1/iban/validate |
| Card BIN | Global card payments | First 6–8 digits of PAN | N/A (BIN is not a full PAN) | Issuer and product type (card networks) | /api/v1/bin/validate |
Note: The United States does not use IBAN; domestic bank transfers rely on routing numbers plus account numbers for ACH or wire. For cross‑border wires, you’ll commonly use a SWIFT/BIC in addition to local details.
Operational behaviors: not found, mismatches, and revalidation
Plan for the following outcomes in production:
- Not found: Treat a non‑success status or missing data object as a hard failure. Prompt the user to recheck their number, or route the case to manual review.
- Inactive: An inactive routing number should block new ACH setups or payments. Consider providing the bank’s phone field to your ops team for follow‑up if necessary.
- Bank mismatch: If your user selects “Bank of America” but the response name differs materially, require an explicit confirmation or escalate. This simple step stops many misroutes.
- Payment rail differences: Different rails (e.g., ACH vs. wire) can use different operational endpoints or status flags at a bank. Use paymentType in the request and response to keep your logic specific to the rail you are sending on.
Caching and data freshness
Routing metadata changes infrequently, but it does change. A pragmatic approach is:
- Cache successful lookups keyed by routingNumber and paymentType.
- Use data.lastUpdated to inform your cache invalidation. If your cached record’s lastUpdated is older than what you consider acceptable for compliance, refresh it.
- Revalidate before first use (e.g., just before the first ACH debit/credit) and on a periodic basis thereafter.
Because BankDataStack returns address and contact fields, consider storing them in your audit logs together with lastUpdated and the full JSON payload you received. This helps support teams and auditors reconstruct decisions.
Security and data handling guidelines
- Do not store full card numbers; BINs are the first digits only and are not sufficient for a payment by themselves.
- Limit routing/account number exposure to the services that need them. Mask them in logs.
- Keep your API key in a secure secret store. In CI/CD, inject it via environment variables rather than hard‑coding.
- Validate only what you need and prune sensitive fields before persisting.
Testing and fixtures
During development, you can test your integration with known identifiers to verify correctness end‑to‑end. For example, besides routing number 121000358 used in this article, other official fixtures exist for different identifier types (such as IBAN or SWIFT) to help verify your request/response handling logic. The same POST pattern applies across identifiers, just change the path segment to /routing, /swift, /iban, or /bin and adjust the payload accordingly. Refer to the API fields in the Documentation for details.
Pricing, signup, and going live
BankDataStack offers a Starter plan at $49.99/month with a 7‑day trial so you can validate routing numbers like 121000358 in staging and move to production with minimal friction. To obtain your API key and start testing, create an account here: Register. Your API key authenticates calls via the X-API-Key header shown in the examples above.
Putting it together: a minimal ACH onboarding flow with 121000358
- User enters routing number 121000358 and account number in your onboarding form.
- Your frontend or backend calls /api/v1/routing/validate with routing_number=121000358 and payment_type=ach.
- Display the returned bank name (Bank Of America, N.A.) and city/state (Henrico, VA) to the user for confirmation.
- If active is true and the user confirms the match, proceed to store the bank details. Otherwise, ask for a corrected routing number or route to manual review.
- Before the first ACH transaction, revalidate the routing number if your cached record is older than your TTL or if internal policy requires a fresh check.
Common pitfalls and how to avoid them
- Relying on checksum alone: A checksum passes even for stale or reassigned routing numbers. Always verify activity and bank identity via the API.
- Assuming IBAN in the U.S.: The U.S. does not use IBAN. For domestic transfers, collect routing and account numbers; for cross‑border, use SWIFT/BIC plus local details.
- Skipping user confirmation: Showing the resolved institution and city/state back to the user reduces data entry mistakes and fraud.
- Forgetting to specify paymentType: Include payment_type in requests so you can track and enforce rail‑specific readiness.
FAQ
Does 121000358 belong to Bank Of America?
Yes. The validation response maps 121000358 to Bank Of America, N.A., with an address in Henrico, VA, and indicates it is active for ACH.
Can I use 121000358 for ACH credits and debits?
The example shows paymentType "ach" and active true. Use the API response to gate both credits and debits; if active is false, block the transfer.
What does “not found” mean?
If the API doesn’t return a success status with a data object, treat the routing number as invalid or unsupported for the given rail and request a corrected number.
How often should I revalidate routing numbers?
Cache successful lookups, but revalidate before first use and periodically thereafter. Use lastUpdated from the response to decide when the cache is stale per your policy.
Do I need to store the entire response?
Store enough to audit your decisions: routingNumber, bank name, address, active, paymentType, lastUpdated, and the timestamp of your lookup. Avoid storing extraneous PII unnecessarily.
Get your API key and start validating routing number 121000358 and other banking identifiers today: Register. For field-level details and more examples, see the Documentation.