Skip to main content

Overview

A journey has two parts: start it (Step 1), then drive it to a decision (Step 2). Step 2 differs by mode — Option A is headless, Option B is hosted.
Do not assume a fixed sequence of steps — the exact order depends on the lender. Always branch on currentNextAction.category, not on the step name.

Step 1 — Start a Loan Journey

POST /api/v1/partner/journey/initiate
Required scope: leads:create

Request Body

FieldTypeRequiredNotes
channelstringYes"API_HOSTED" or "API_HEADLESS" — chooses the mode
productCodestringYes"ONLINE_PERSONAL" or "ONLINE_GOLD"
mobilestringYesCustomer’s 10-digit mobile number
customerobjectYesApplicant details — see table below
goldLoanDetailsobjectConditionalRequired when productCode is ONLINE_GOLD

customer Object

FieldTypeRequiredValidation / Notes
panstringYesFormat ABCDE1234F
dobstringYesYYYY-MM-DD
genderstringYesMALE / FEMALE / TRANSGENDER / OTHER
personalEmailstringYesValid email address
employmentTypestringYessalaried or selfEmployed
pinCodestringYesExactly 6 digits
termsAcceptedbooleanYesMust be true
monthlyIncome / annualIncomenumberOne ofProvide at least one
firstName, lastName, addressL1, city, statestringNoOptional enrichment fields

goldLoanDetails Object (Gold Loan Only)

FieldTypeRequiredNotes
jewellaryListstring[]YesAt least one item, e.g. ["Gold chain 22K"]
gramsstringYesNumeric string, e.g. "35.5"

Responses

{
  "success": true,
  "data": {
    "journeyId": "jrn_<uuid>",
    "journeySession": "<JWT — send via X-Journey-Session on later calls>",
    "nextAction": {
      "type": "POLL_FOR_OFFERS",
      "category": "POLL",
      "pollIntervalSeconds": 10
    }
  }
}

Example — Start a Headless Personal Loan

BODY='{"channel":"API_HEADLESS","productCode":"ONLINE_PERSONAL","mobile":"9876543210","customer":{"pan":"ABCDE1234F","dob":"1990-01-15","gender":"MALE","personalEmail":"john@example.com","employmentType":"salaried","pinCode":"400001","monthlyIncome":75000,"termsAccepted":true}}'

curl -s -X POST https://api.easycred.in/api/v1/partner/journey/initiate \
  -H "Content-Type: application/json" \
  -H "x-api-key: ec_live_a1b2c3d4_<48-hex>" \
  -H "x-timestamp: 1749820800" \
  -H "x-nonce: 550e8400-e29b-41d4-a716-446655440000" \
  -H "x-signature: <computed-hex>" \
  -d "$BODY"

Step 2 (Option A) — Drive the Journey Yourself (Headless)

Poll the journey, then act on whatever it asks for.

Read Journey State

GET /api/v1/partner/journey/{journeyId}
Required scope: leads:status:read
Headers: x-api-key, x-timestamp, x-nonce, x-signature, X-Journey-Session
{
  "success": true,
  "data": {
    "journeyId": "jrn_abc123",
    "productCode": "ONLINE_PERSONAL",
    "channel": "API_HEADLESS",
    "currentNextAction": {
      "type": "POLL_FOR_OFFERS",
      "category": "POLL",
      "pollIntervalSeconds": 10
    },
    "offers": [],
    "outcome": null
  }
}

Branch on the Category

CategoryWhat it meansWhat you do
POLLEasyCred is working in the backgroundWait pollIntervalSeconds, then read state again
COLLECTA customer choice is neededGather it, then submit an action (below)
REDIRECTA verification step (KYC / e-sign / mandate)Open currentNextAction.url, then signal return
TERMINALThe journey is finishedRead outcome and stop polling

COLLECT — Submit a Customer Action

POST /api/v1/partner/journey/{journeyId}/action
Required scope: offers:select
Body: { "kind": "<ActionKind>", "payload": { ... } }
Action KindSent When Step IsPayload Fields
SELECT_OFFERSELECT_OFFERofferId (string), loanAmount (positive number)
SELECT_GOLD_LOAN_BRANCHSELECT_GOLD_LOAN_BRANCHofferId (string), branchLocationId (string)
SUBMIT_BANK_ACCOUNTSUBMIT_BANK_DETAILSaccHolderName, acctype (SAVING/CURRENT), accNo (≥6 digits), ifscCode
Naming note: For bank details the action kind is SUBMIT_BANK_ACCOUNT, but the journey step is reported as SUBMIT_BANK_DETAILS. Send the kind, match on the step.

Where Offer and Branch Values Come From

When the journey reaches an offer step, the offers[] array in the journey state is populated. For gold loans, each offer also carries a branchLocations[] array:
"offers": [
  {
    "offerId": "019edb74-...-722b8e",
    "branchLocations": [
      {
        "id": "019edb74-...-5aa5",
        "branchName": "Ahmedabad - Panchvati",
        "address": "CG Road, ..."
      }
    ]
  }
]
Send the chosen entry’s id as branchLocationId:
{
  "kind": "SELECT_GOLD_LOAN_BRANCH",
  "payload": {
    "offerId": "019edb74-...-722b8e",
    "branchLocationId": "019edb74-...-5aa5"
  }
}

Example — Select an Offer

curl -s -X POST https://api.easycred.in/api/v1/partner/journey/jrn_abc123/action \
  -H "Content-Type: application/json" \
  -H "x-api-key: ec_live_a1b2c3d4_<48-hex>" \
  -H "x-timestamp: 1749820850" \
  -H "x-nonce: 3d94e58c-1b47-4b9a-a9c3-af3b1e63e2f0" \
  -H "x-signature: <computed-hex>" \
  -H "X-Journey-Session: <journeySession>" \
  -d '{"kind":"SELECT_OFFER","payload":{"offerId":"offer_xyz","loanAmount":500000}}'
After any action, resume the GET poll loop immediately.

When the category is REDIRECT, open currentNextAction.url for the customer (new tab or WebView). It leads to a secure hosted page for KYC, e-sign, or e-NACH mandate. When the customer returns to your app, signal the return:
POST /api/v1/partner/journey/{journeyId}/redirect-returned
Required scope: offers:select
Body: { "kind": "KYC" } — one of KYC | ESIGN | MANDATE
When the step isSend kind
REDIRECT_TO_KYCKYC
REDIRECT_TO_ESIGNESIGN
REDIRECT_TO_MANDATEMANDATE
Then resume the GET poll loop.

Step 2 (Option B) — Hand Off to EasyCred (Hosted)

After starting an API_HOSTED journey, hand hostedUrl to the customer (deep-link, WebView, or browser redirect). EasyCred’s screens handle every step through to completion — your backend makes no further journey calls. To track progress:

Poll Application Status

GET /api/v1/partner/leads/{applicationId}/status
Requires only your API key — no journey session.

Subscribe to Webhooks

Subscribe with scope webhooks:manage to receive real-time push notifications as status changes happen.

Journey Outcomes (Terminal States)

When the category is TERMINAL, read data.outcome:
OutcomeMeaning
COMPLETEDLoan disbursed successfully
REJECTEDThe lender declined the application
NO_OFFERS_AVAILABLENo lender produced an offer in time
OFFLINE_PROCESSINGA non-retryable issue — EasyCred operations will follow up
ABANDONEDThe journey exceeded its maximum number of poll attempts
EXPIREDThe journey passed its time-to-live (72 hours by default)