API to Validate Routing Number 021000021

API to Validate Routing Number 021000021

You need to validate a US ABA routing number before releasing an ACH payment or onboarding a customer’s payout bank. By the end of this guide you will be able to programmatically verify routing number 021000021, confirm the bank and branch details, and incorporate the BankDataStack validation API into your payment or onboarding flow with production-ready code.

What you will validate for 021000021 (ACH routing for JPMorgan Chase Bank, NA)

Routing number 021000021 is widely used for ACH transfers with JPMorgan Chase Bank, NA. A correct real-time lookup helps you prevent misrouted credits, reduce return NOCs, and speed up KYC/KYB onboarding.

Illustration: API to Validate Routing Number 021000021

With one API call you will:

  • Verify the routing number’s checksum and active status for ACH.
  • Resolve the bank’s legal name and contact information.
  • Retrieve branch locality data (city, state, ZIP) to enrich your payment record or onboarding checks.

This article focuses on the specific identifier 021000021 and how to validate it via the routing validation endpoint. Links to the full API reference and key sign-up are here: Documentation and Register.

Endpoint and request model

Use the routing validation endpoint to check ABA numbers for ACH and related payments:

  • Method: POST
  • URL: https://www.bankdatastack.com/api/v1/routing/validate
  • Auth: X-API-Key header (get a key via Register)
  • Body: JSON with routing_number and payment_type

Below is the official, copy-pasteable cURL for 021000021 (ACH):

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":"021000021","payment_type":"ach"}'

Official JSON response for 021000021

When the routing number is found and valid, you receive a success payload. For 021000021, the live fixture returns:

{
"status": "success",
"data": {
"routingNumber": "021000021",
"paymentType": "ach",
"name": "Jpmorgan Chase Bank, Na",
"addressFull": "Tampa, FL",
"street": "3RD FLOOR",
"city": "Tampa",
"state": "FL",
"zip": "33610",
"type": "Main Office",
"phone": "813-432-3700",
"active": true,
"lastUpdated": "2026-10-03",
"address": "3RD FLOOR"
}
}

Field usage in your flow:

  • data.routingNumber and data.paymentType: Echoed inputs; log them to your audit trail.
  • data.name: The legal bank name to display/compare during onboarding or payment confirmation (“Jpmorgan Chase Bank, Na”).
  • data.city, data.state, data.zip and data.addressFull: Locality data for fraud/context checks or user-facing confirmation.
  • data.type and data.active: Use active=true to allow the payment; if not active, hold and request updated details.
  • data.phone: Optional human verification step for ops when resolving exceptions.
  • data.lastUpdated: A date string you can persist to decide when to refresh cached results.

Python example: validating 021000021 and hardening your workflow

The following Python sample calls the same routing validation endpoint, checks the response for active status, and demonstrates how to surface bank details to your UI or logs.

import json
import sys
import requests

API_URL = "https://www.bankdatastack.com/api/v1/routing/validate"
API_KEY = "YOUR_API_KEY"

def validate_routing(routing_number: str, payment_type: str = "ach") -> dict:
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"routing_number": routing_number,
"payment_type": payment_type
}
resp = requests.post(API_URL, headers=headers, json=payload, timeout=10)
resp.raise_for_status()
return resp.json()

def main():
routing = "021000021"
try:
result = validate_routing(routing, "ach")
except requests.HTTPError as e:
print(f"HTTP error calling BankDataStack: {e}", file=sys.stderr)
sys.exit(2)
except requests.RequestException as e:
print(f"Network error calling BankDataStack: {e}", file=sys.stderr)
sys.exit(3)

status = result.get("status")
if status != "success":
# Not found or invalid input cases are not 'success'
print(json.dumps({
"ok": False,
"routingNumber": routing,
"reason": "not_found_or_invalid"
}))
sys.exit(1)

data = result.get("data", {})
# Apply your go/no-go logic:
if not data.get("active", False):
print(json.dumps({
"ok": False,
"routingNumber": data.get("routingNumber"),
"bank": data.get("name"),
"reason": "inactive_routing"
}))
sys.exit(1)

# Minimal record to persist for audit and faster future validation lookups:
output = {
"ok": True,
"routingNumber": data.get("routingNumber"),
"paymentType": data.get("paymentType"),
"bank": data.get("name"),
"city": data.get("city"),
"state": data.get("state"),
"zip": data.get("zip"),
"phone": data.get("phone"),
"active": data.get("active"),
"lastUpdated": data.get("lastUpdated")
}
print(json.dumps(output))

if __name__ == "__main__":
main()

Integrate this function into your ACH payment flow:

  • On payee onboarding, call the API as the user enters their routing number; show the resolved bank name to reduce keying mistakes.
  • On payment confirmation, re-check active=true before queuing the ACH file.
  • Persist a compact subset (routingNumber, name, city/state/zip, active, lastUpdated) to support audit and reduce redundant calls via caching.

ABA routing format and checksum basics

US ABA routing numbers are nine digits. The checksum uses a weighted sum across the first eight digits with multipliers 3, 7, and 1 repeating. The ninth digit is a check digit that makes the total a multiple of 10. This quickly filters typos before you even hit an API.

Workflow tip:

  • Perform client-side length and checksum validation to provide instant feedback.
  • Always follow up with authoritative lookup via the API to confirm the bank assignment and “active” status for the intended payment type (ACH in this case).

How to use the validation in onboarding and payments

Onboarding (KYB/KYC account capture)

  • As soon as a user types a 9-digit routing number, run a checksum check locally.
  • If it passes, call the routing validation endpoint with payment_type="ach".
  • Display the bank’s name (“Jpmorgan Chase Bank, Na”) and locality (“Tampa, FL”) for user confirmation.
  • If the number is not found or inactive, prompt the user to verify with their bank or supply an alternate routing.

Payment execution (ACH credits/debits)

  • For new or edited beneficiaries, re-validate 021000021 before sending the ACH file to minimize returns.
  • Log the returned data fields with your payment ID to support later dispute resolution.
  • If active=false, fail validation in your UI and mark the beneficiary record for review.

Handling not found or mismatches

If the routing number does not exist for the requested payment_type or fails authoritative checks, the API will not return a “success” status. In your code, treat any non-success status as a hard stop and provide a clear message to the user or ops team.

  • Common reasons: mistyped digits, outdated routing, mismatched payment_type.
  • Next steps: ask the user for a voided check or bank letter, or try another verified routing number from the same bank.

Caching and data freshness

The response includes lastUpdated, which indicates when the reference record was last refreshed in the dataset. For routing numbers like 021000021 that rarely change, caching is reasonable to reduce latency and costs.

  • Cache successful validations keyed by routingNumber and paymentType.
  • Set your TTL according to risk tolerance; refresh on user edits, failed payments, or after a meaningful interval. Use lastUpdated to decide when to refresh a stale record.
  • Always re-validate when you detect contradictory user inputs or if payments are failing at downstream clearing.

Comparing payment identifiers used with routing validation

Routing numbers are only one piece of the finance identifier landscape. Here is how they compare to other identifiers you may handle in your stack. Remember: the USA does not use IBAN for domestic transfers.

Identifier Scope Primary Use Example Validation Endpoint Family Notes
ABA Routing Number United States ACH/Wire bank identification 021000021 /api/v1/routing/validate 9 digits, checksum; confirms bank, location, activity
SWIFT/BIC Global International wires CHASUS33 /api/v1/swift/validate 8 or 11 characters; identifies bank and country
IBAN EMEA/other regions Cross-border and domestic (non-US) GB82WEST12345698765432 /api/v1/iban/validate Country-specific length; includes checksum; not used in the USA
Card BIN Global Card issuing bank identification 424242 /api/v1/bin/validate First 6–8 digits only; never store full PANs

Security and PII considerations

  • Do not store full card numbers; BIN lookups should only ever see the first digits (e.g., 424242).
  • For routing validations, storing the returned metadata (bank name, city/state, lastUpdated) is generally low risk; still, apply your data retention policy and access controls.
  • Protect the X-API-Key in server-side code and secret managers; do not expose it in front-end clients.

Error handling and resilience patterns

  • Network and HTTP errors: retry with backoff when safe, but never duplicate a payment purely on retries. Limit retries to the validation call only.
  • Timeouts: set a reasonable client timeout (e.g., 10 seconds in the sample). If a timeout occurs, fail closed (do not send the ACH) until validation succeeds.
  • Input hygiene: strip spaces, ensure exactly 9 digits for ABA, and check checksum locally before calling the API.
  • Auditability: log the response status and the minimal fields you use for decisioning.

Plan and trial details

You can start with the Starter plan at $49.99/mo and a 7-day trial to integrate validations in staging and move to production once your tests are stable. Get your key here: Register. For endpoint specifics and field definitions, see the Documentation.

Putting it all together for 021000021

To validate routing number 021000021 for an ACH payment:

  1. Run local checks: ensure 9 digits and pass the ABA checksum.
  2. POST to /api/v1/routing/validate with routing_number: "021000021" and payment_type: "ach".
  3. Require status == "success" and data.active == true.
  4. Read data.name (“Jpmorgan Chase Bank, Na”) and locality (Tampa, FL) to confirm with the user or display in your UI.
  5. Cache the result with lastUpdated for your defined TTL; re-validate on edits or before large disbursement runs.

FAQ

Does the USA use IBAN for bank transfers?
No. The USA does not use IBAN. Use ABA routing numbers for ACH and domestic wires; use SWIFT/BIC for international transfers.

What does it mean if the routing number is “active”: false?
Treat it as not acceptable for payments. Ask the customer for a current routing number or confirm the payment type (ACH vs. wire) with their bank.

How often should I refresh cached routing info?
Base this on your risk tolerance. Consider refreshing when lastUpdated is stale for your policy, when users edit banking details, or after returned payments.

Can I send multiple payment types?
Validate per payment type. For ACH, pass payment_type="ach". If you support another payment rail, validate it specifically before use.

Where do I get an API key?
Create an account and start the 7-day trial here: Register.

Ready to get started?

Get your API key and start validating bank data in minutes.

Get API Key

Related posts