Money is integer paise — ₹15,000 = 1500000. Follow GET /application/journey. Skipping a step returns 409 step_not_ready.
409 / 422 or a screen that still shows the previous action.1500000. Never send rupees as a decimal.cust_1735…, app_1735… — not UUID-shaped. Screen reference PME-XXXXXXXX.{ "code": "snake_case", "message": "plain English" }.revision from the last screen. Stale → 409 revision_conflict. Refresh GET /applications before a write.isNewUser is true./applications/{id}.| Who | How | What to use |
|---|---|---|
| Anyone | no login | Health, Products, OTP, token refresh |
| Customer | Bearer accessToken | Profile, Applications, Journey, email verify |
| Staff | staff actor (local hatch) | Evaluate, verify-bureau, cancel |
| Ops | X-Internal-Secret | dispatch-due, poll-timers, redrive |
| Vendor | signed webhook | /webhooks/* |
GET /health.GET /products before OTP.product_id. The session stays on that product. Unknown id → invalid_product.products[n].id into product_id (first product is saved automatically).POST /auth/otp/request with phone + product_id.123456 unless QA says otherwise.POST /auth/otp/verify with the same phone, same product_id, and the code.phoneSessionToken always. One account also gets accessToken / refreshToken / customerId and application (auto-started when isNewUser is true). Two family accounts → pick with POST /auth/accounts/select. From here every customer URL needs Bearer.POST /auth/token/refresh. Sign out → POST /auth/logout.POST /auth/email/verify/start → customer taps the mail → POST /auth/email/verify/confirm with token + Bearer.emailVerified: true. Poll GET /auth/email/verify/status while waiting.GET /application/profile as soon as you have a token.null means unknown, not “field missing”.update_profile, call POST /application/profile (fullName, dob as dd-mm-yyyy, address string, employment type, employer name, monthlyIncomePaise).GET /applications (status, youCanNow, revision) and/or GET /application/journey (current.step, upcoming).youCanNow[].submitTo or current.path.started, call POST /applications/begin-verification.started → verifying. KYC is not allowed before this.POST /application/kyc/pan (or POST /applications/verify-pan).redirectUrl, finish consent, then poll GET /application/kyc/pan/status until resolved + verified. If PAN is not in the locker, status stays pending and returns redirectUrl again.GET /application/bureau.score. Acknowledge too early → credit_score_not_ready.POST /applications/acknowledge-credit-score.POST /application/kyc/aadhaar/start → open redirectUrl → poll GET /application/kyc/aadhaar/status.POST /application/kyc/aadhaar/address if they want a different communication address.under_verification.POST /applications/{id}/evaluate with bureauClaimId, amount in paise, and the rule-set fields.offer_ready (or rejects). A customer token here is 403.GET /application/eligibility. If eligible: true, show amountPaise and call POST /applications/accept-offer.POST /application/kyc/bank then POST /application/esign/start (poll GET /application/esign/status).POST /applications/create-loan → POST /applications/request-payout.202 on payout means “request accepted”, not “money sent”.POST /ops/dispatch-due so payout actually runs.GET /application/journey → call current.method + current.path.GET /applications → youCanNow.| Now | Call this | Why |
|---|---|---|
| no token | products → OTP request → verify | Login + auto-start |
started | POST /applications/begin-verification | Unlock KYC |
update_profile | POST /application/profile | Name/DOB/income before PAN |
kyc_pan | PAN start + status poll | DigiLocker PAN |
bureau | GET /application/bureau | Score for the next screen |
acknowledge_credit_score | POST /applications/acknowledge-credit-score | Customer saw the score |
kyc_aadhaar | Aadhaar start + status poll | Identity vs PAN |
under_verification | wait; staff evaluate | Underwriting |
eligibility / offer_ready | eligibility GET, then accept-offer | Show amount, take consent |
accepted | bank → esign → create-loan | After the offer |
| loan exists | request-payout, then ops dispatch | Disbursal |
GET /applications before a write that needs revision.POST /applications/{id}/cancel from sanctioned. Terminal.POST /webhooks/bureau|kyc|esign|income with a signature. claimId is in the body.POST /ops/redrive/{handlerRowId} then dispatch-due again.| Value | Comes from | Used for |
|---|---|---|
product_id | GET /products, OTP verify | OTP body |
accessToken / refreshToken / customerId | OTP verify, refresh | login |
applicationId / revision | screens, journey, verify | staff path, writes |
redirectUrl | KYC start/status | open DigiLocker |
claimId | staff verify-bureau, webhooks | evaluate |
loanId / payoutRequestId | create-loan, request-payout | payout |
journeyCurrent / journeyUpcoming | GET /application/journey | next step |
lastErrorCode | any error JSON | debug |