Skip to main content
3 partners awaiting approval
Open full feed →

Lender adapter documentation

The full contract: schemas, signing, error model, replay, SLAs, audit-trail handoff, and the bank-partner-of-record handshake.

Six endpoints to integrate. Every lender adapter on the rail talks to the same six routes under https://api.eazepay.com. Sandbox traffic is unsigned-friendly so you can curl the endpoints before key exchange, then flip on HMAC verification for staging + prod.

API endpoint reference

Click any row to jump to its sample payload.

POST/api/v1/applications
POST/api/v1/applications/{id}/submit
GET/api/v1/applications/{id}/offers
POST/api/v1/orchestration/evaluate
POST/api/v1/orchestration/route
POST/api/v1/offers/{id}/accept
POST/api/v1/lenders/{lender_id}/quote
POST/api/v1/webhooks/lenders/{lender}
GET/api/v1/lenders
GET/api/v1/sample

Try it from your terminal

No auth required in demo mode — these endpoints are mounted on this hostname.

curlbash
1# 1. List every lender on the rail
2curl -s $HOSTNAME/api/v1/lenders | jq
3
4# 2. Filter to MedPay lenders
5curl -s "$HOSTNAME/api/v1/lenders?brand=medpay" | jq
6
7# 3. Eligibility check (no bureau hit)
8curl -s $HOSTNAME/api/v1/orchestration/evaluate \
9 -X POST -H "Content-Type: application/json" \
10 -d '{
11 "application_id":"app_demo_001",
12 "brand":"tradepay",
13 "amount_cents":1850000,
14 "tier":"prime"
15 }' | jq
16
17# 4. Full waterfall — returns ranked offers
18curl -s $HOSTNAME/api/v1/orchestration/route \
19 -X POST -H "Content-Type: application/json" \
20 -d '{
21 "application_id":"app_demo_001",
22 "brand":"tradepay",
23 "amount_cents":1850000,
24 "term_months":60,
25 "tier":"prime"
26 }' | jq
27
28# 5. Sample payload bundle (application + offer + webhook events)
29curl -s $HOSTNAME/api/v1/sample | jq

HMAC-SHA256 signing

Required on prod traffic; optional on sandbox. Body is the raw JSON bytes EazePay sent.

signing.jsjs
1// Outbound (we → you) and inbound (you → us) use the same scheme.
2// signature = hex(hmac_sha256(secret, timestamp + '.' + nonce + '.' + body))
3
4import crypto from 'node:crypto';
5
6const timestamp = String(Math.floor(Date.now() / 1000));
7const nonce = crypto.randomBytes(8).toString('hex');
8const body = JSON.stringify(payload);
9const signature = crypto
10 .createHmac('sha256', LENDER_SECRET)
11 .update(`${timestamp}.${nonce}.${body}`)
12 .digest('hex');
13
14await fetch('https://api.eazepay.com/api/v1/lenders/lp_buzzpay_prime/quote', {
15 method: 'POST',
16 headers: {
17 'Content-Type': 'application/json',
18 'X-EazePay-Timestamp': timestamp,
19 'X-EazePay-Nonce': nonce,
20 'X-EazePay-Signature': signature,
21 },
22 body,
23});

Lifecycle (server-to-server)

EazePay drives the orchestration; you respond on quote, accept on bind, and disburse via the partner-bank rail.

  1. 1. /v1/partner/applications
    EazePay POSTs a normalized applicant + bureau + bank snapshot. Respond with offer / decline / ineligible / counter within your SLA.
  2. 2. /v1/partner/offers/:id/bind
    Applicant accepted your offer. Confirm + return contract metadata (lender of record, servicer, disclosures).
  3. 3. /v1/partner/loans/:id/fund
    EazePay signals the bank-of-record disbursement window. Confirm rail (RTP / ACH same-day / wire) and amount.
  4. 4. Webhook (you → us)
    Status changes (servicing, default, hardship, payoff) flow back via your webhook URL. Same HMAC scheme as inbound.

Request schema · POST /v1/partner/applications

application.request.jsonjson
1{
2 "application_id": "app_4nqLkR2vTjW",
3 "policy_version": "orch_v_2026_05_a",
4 "applicant": {
5 "state": "TX",
6 "fico_band": "740-779",
7 "income_monthly_cents": 684000,
8 "stability": { "residence_years": 4.2, "employer_years": 5.1 },
9 "cashflow_score": 0.84,
10 "dti_pct": 28.4,
11 "mla_covered": false,
12 "scra_active": false
13 },
14 "request": {
15 "amount_cents": 1850000,
16 "term_months": 60,
17 "category": "home_improvement",
18 "purpose_detail": "Solar PV + battery (Pacific Solar Co.)"
19 },
20 "channel": {
21 "type": "merchant",
22 "merchant_ref": "mer_pacificsolar_001"
23 },
24 "snapshot_hash": "sha256:f4e9…",
25 "permissible_purpose": "604(a)(3)(A)"
26}

Response schema · 200 OK

application.response.jsonjson
1{
2 "decision": "approved",
3 "offer": {
4 "amount_cents": 1850000,
5 "term_months": 60,
6 "apr_bps": 1099,
7 "fee_cents": 0,
8 "monthly_payment_cents": 40142,
9 "lender_of_record": "Cross River Bank"
10 },
11 "reason_codes": ["approved_within_policy"],
12 "valid_until": "2026-05-11T18:42:00Z"
13}

Error model

RFC 7807 problem details. Stable codes. Never leak internal errors.

json
1{
2 "type": "about:blank",
3 "title": "Unprocessable Entity",
4 "status": 422,
5 "code": "snapshot_hash_mismatch",
6 "detail": "snapshot_hash does not match the inputs the orchestrator captured at submit-time",
7 "instance": "/v1/partner/applications"
8}

SLA targets

P50 response≤ 400 ms
P95 response≤ 1.2 s
P99 response≤ 3 s
Error rate≤ 0.5%
Circuit-breaker window50% errors / 1 min over ≥20 calls

Bank-partner handshake

Loans you originate via EazePay are made by the chartered bank-of-record and either serviced by us or purchased by you under your warehouse / forward-flow.

EazePay carries the true-lender attribute structurally on every Loan record. The bank retains credit-policy ownership in form and substance, and we surface that in disclosures + audit artifacts.

Read the bank-partner whitepaper