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.
  • A Funding FBO provisioned for your program: Lead opens this during onboarding. The Funding API moves money into your Funding FBO when the Funding object posts.
  • 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.
If you have not already done Make Your First Payment API Call, start there — it covers authentication, idempotency, and the Entity API in more depth.

Steps

25 minutes We’ll walk through originating a simple $5,000 personal term loan to an individual borrower, repaid monthly over 24 months.
Same OAuth2 client credentials flow as the Payment Quickstart. Exchange your client_id and client_secret for a short-lived access token and pass it as a Bearer header on every subsequent request.
Save the access_token value as a shell variable:
ScopesLending workflows need broader scopes than payments. The scope list above covers everything in this guide.
Every loan starts with an Entity for the borrower. We’ll create an Individual with placeholder KYC and OFAC results so the sandbox accepts it.
Save the returned id (starts with entity_):
The Application is your record of the underwriting decision. Lead relies on this data to fulfill critical compliance requirements — including Fair Lending audits and adverse action tracking under Regulation B (ECOA) and Regulation V (FCRA), Military Lending Act (MLA) status verification, and BSA/AML recordkeeping. Applications are always created in a terminal status (approved, declined, or canceled). Lead does not track in-flight applications; you finalize the underwriting decision on your side, then create the API object when you have a definitive result.For our approved $5,000 loan:
Save the returned id (starts with application_):
DocumentsDocument IDs reference filenames in your /documents SFTP directory. For this quickstart you can use any string — sandbox does not verify the file exists. In production, the file must be delivered to SFTP before referencing it.
The Account is the legal account the borrower holds with Lead. For credit products, the Account is required and must reference an application_id. Capabilities tell Lead what type(s) of Balances the Account will hold — credit_with_underwriting for products requiring a credit Balance with an underwriting component (e.g., a loan with an application) and credit_without_underwriting for products requiring a credit Balance but do not have an underwriting component (e.g., courtesy overdraft).
Save the returned id (starts with account_):
This is where the loan actually comes into existence. The Subledger Balance defines all the terms — amount, maturity, repayment schedule, interest — and is what Lead’s ledger tracks throughout the life of the loan. When you create it, every outstanding amount (principal, interest, fees) is zero because no draw has happened yet.For a term loan, use structure: non_revolving — there’s a fixed loan amount and repayments do not restore available credit. Use structure: revolving instead if you’re opening a line of credit or credit card where the borrower can re-draw after repayment.
Save the returned id (starts with subledger_balance_):
Why Balance and Funding are DecoupledYou define loan terms once (Balance) but can draw funds against them many times (Funding). For a term loan this usually means one draw at origination, but for a line of credit you’ll create multiple Funding objects against the same Balance throughout its life.
The Funding object instructs Lead to move principal from a Lead GL into your Funding FBO. Once posted, you can disburse those funds externally via ACH, wire, or instant payment — but that’s a separate step on a payment rail.For this term loan, the borrower is taking the full $5,000 as a single draw. There is no merchant origination fee (this isn’t a BNPL product) and nothing is withheld for later disbursement.
The response returns an id that starts with funding_ and an initial status of processing. Save it:
Principal ComponentsFor a simple personal term loan, the entire principal goes to external_disbursement_amount. The other two fields cover other use cases: withheld_amount is for funds you’ll disburse later and merchant_origination_fee_amount is for merchant fees (typically in BNPL loans).
Funding objects move asynchronously from processing to posted (or rejected). Poll the Funding endpoint — or listen for the funding.posted webhook event — to confirm.
When status flips to posted, the $5,000 is sitting in your Funding FBO and ready to be disbursed externally.
SandboxFunding does not auto-advance in sandbox. Use POST /v0/fundings/{id}/advance to move the Funding from processing → posted (or processing → rejected) so you can test your webhook handlers and downstream disbursement logic.

What’s Next

  • Disburse Funds Externally Now that $5,000 is in your Funding FBO, send it to the borrower via ACH, wire, or instant payment.
  • Webhooks Listen for funding.posted and funding.rejected instead of polling. Configure your endpoint per Webhooks & Events.
  • Service the Loan Report ongoing activity — interest accrual, principal repayments, fees — against the Subledger Balance via the Balance and Transaction files. See Balance Reconciliation.
  • Multi-Draw Use Cases For multi-draw term loans or lines of credit, create additional Funding objects against the same Subledger Balance over its life. The sum of all principal.* amounts across posted and processing Fundings cannot exceed the Balance’s max_funding_amount (for non_revolving) or the available credit (for revolving).
  • Closing the Loan Once the balance is paid off and the loan is in a terminal status, update the Subledger Balance to closed via the Balance file. Closure requires all outstanding amounts to be zero.

Troubleshooting