Skip to main content

Before You Start

You will need:
  • Sandbox API credentials: A client_id and client_secret provided by your Lead Technical Account Manager during kickoff.
  • curl: Installed on macOS by default; curl --version should print something. Any HTTP client works.
  • Optional: jq— for cleaner JSON output. Pipe responses through | jq . if you have it installed.
Sandbox OnlyEvery example uses api.sandbox.lead.bank. The same calls work against api.lead.bank in production once your program is approved for go-live, but you should never run this guide against production credentials.

Steps

15 minutes We’ll go through a simple flow to authenticate against Lead, create an entity, assign an account number, simulate an incoming ACH credit, and send an outgoing ACH.
Lead uses OAuth2 client credentials. You exchange your client_id and client_secret for a short-lived access token (24-hour expiry by default) and pass that token as a Bearer header on every subsequent request.Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the values from your Technical Account Manager.
You should see a response like this:
Save the access_token value as a shell variable so the next steps are easy to copy:
ScopesAccess tokens are scoped. Request only the scopes you need — and you can request a narrower set later for production.
Every transaction at Lead starts with creating a representation for your customer in Lead’s system. For illustrative purposes, the request below creates an example Individual Entity with minimal information provided.
A successful response includes an id that starts with entity_. Save it for the next step:
IdempotencyEvery write endpoint requires an Idempotency-Key header. If you retry the same request with the same key (e.g. after a network blip), Lead returns the original response instead of creating a duplicate. Use a fresh key per logical operation.
Confirm the entity is queryable. You can fetch by Lead’s entity ID you supplied.
You should get back the same entity object you just created, with timestamps populated.
Before you can receive or send money, you need an Account Number assigned to your account. Lead provides an account_id during onboarding — this is your FBO account, not a per-user account. Use it directly to create an Account Number for each customer.Create the account number:
Replace YOUR_ACCOUNT_ID with the account_id provided by your Technical Account Manager.A successful response includes an id that starts with account_number_xyz and the 10-digit DDA number alongside Lead’s routing number. Save the ID — you’ll use it in the next two steps:
Account Numbers and RoutingLead assigns a real account number and routing number to every Account Number object. This is what counterparties use to send money to your customer. Multiple Account Numbers can map to a single Account — for example, one for ACH and one for wire.
The sandbox provides simulation endpoints that are not available in production. They let you trigger inbound transactions so you can test the full lifecycle of a payment. The example below is for ACH, but wires, and instant payments are similar.
The response includes an id that starts with ach_. Copy it and substitute it for {ach_id} in the retrieve call below. Amounts are in cents — 12500 is $125.00.
SandboxACH transactions don’t advance through their lifecycle on real network timing in sandbox. Use POST /v1/simulate/ach/{ach_id}/advance to move the transfer through its states manually.
Now send money out from your account. An outgoing ACH requires an Account Number on the sending side and a destination routing number and account number on the receiving side.
A successful response returns an id that starts with ach_ and an initial status of created. Save it:
Retrieve the transfer to confirm its status:
Effective Entry DateSetting delivery_type to next_business_day schedules the ACH for the next valid settlement date. Use same_business_day for same-day ACH if your program supports it. Lead derives the effective date automatically — see ACH → Processing Windows for cutoff times and valid date rules.
SandboxOutgoing ACH transfers don’t submit to the real network. Use POST /v1/simulate/ach/{ach_id}/advance to move the transfer through its lifecycle states manually.

What’s Next

  • Webhooks: Receive events instead of polling. Configure your endpoint and start listening for ach.created, ach.posted, and lifecycle events for every other object.
  • Idempotency & Errors: Error envelope, retry semantics, and the canonical error codes you’ll handle.
  • Move Money Guides: Full per-rail walkthroughs for ACH, Wire, Instant Payments, Blockchain, and Internal Transfers.

Troubleshooting