A unity user is created before initiating the loan application journey. The API accepts a bunch of optional values like contact & bank details, date of birth, etc. that can be passed at the time of Unity User creation. These values will be later pre-populated in the LAMF journey for the user and improve the user experience.
Create a Unity user before starting a loan application. One Unity user can hold both an LAMF (mutual fund) and an LAS (stocks) application — the same API is used for both, with different payloads.
Store theunityUserIdThe response returns a
unityUserId. Store it — you'll need it for Create Interaction and Update DLA Holdings, and it's the identifier you pass to Combined Credit Snapshot.
Authentication is the same as every other Unity backend API — see the Unity API authentication for the x-gateway-secret / x-gateway-authtoken headers.
Idempotency and repeated calls
Calling this API multiple times for the same user (same PAN or same auth contact) is safe:
- Existing user by PAN — returns the existing Unity user, lender, and referrer without creating a duplicate.
- Existing user by auth contact — returns an error if the phone is already linked to a different Unity user.
- Same-payload retries — no side effect — returns the existing user Id.
So you can call this whenever you need a Unity user ID (e.g. before starting the flow) without worrying about duplicates.
LAMF (Loan Against Mutual Funds)
Use this when the user will pledge mutual fund holdings.
| Field | Required | Notes |
|---|---|---|
pan | yes | User's PAN. |
authContact | yes | At least number; used for identity and linking. This is where the initial authentication OTP is triggered. |
productType | no | Defaults to lamf. |
assetType | no | Defaults to MUTUALFUND for LAMF. |
holdings | no | Array of MF holdings. If non-empty, holdingsLastFetchedAt is required. |
holdingsLastFetchedAt | conditional | Required when holdings is non-empty (ISO 8601 / RFC 3339). |
dob | no | DD-MM-YYYY or YYYY-MM-DD (normalised to DD-MM-YYYY). |
referrer | no | Defaults to your partner name. |
opaqueId | no | Your own identifier for this user. Stored only when a new Unity user is created — see Passing your own identifier. |
name, age, isNri, contacts, bankAccounts | no | Optional pre-fill attributes. |
Example request (LAMF):
{
"pan": "AIXOL9094G",
"authContact": { "number": "9876543210", "countryCode": "+91" },
"productType": "lamf",
"assetType": "MUTUALFUND",
"dob": "04-11-1999",
"name": "Vishal Pal",
"age": 35,
"isNri": false,
"opaqueId": "partner-ref-12345", // optional - your own identifier for this user, echoed back in webhooks and Get unity user details
"holdings": [ // pass all values as received from the user's CAS via RTAs/MFC
{
"repository": "CAMS",
"amcCode": "PP",
"folio": "16615967",
"schemeCode": "001ZG",
"schemeName": "Parag Parikh Flexi Cap Fund",
"isin": "INF879O01027",
"schemeType": "EQUITY",
"units": 131.57,
"lockInUnits": 13.157,
"isDemat": false,
"dpId": "1208160062733129", // mandatory if isDemat is true
"modeOfHolding": "", // optional - defaults to single holding if not passed
"lienEligibleUnits": 120.33, // optional - if not passed, eligible units = units - lockInUnits. If passed, these are considered the eligible units for the loan
"contact": {
"phone": { "number": "9876543210", "countryCode": "+91" }, // required
"email": "[email protected]"
}
}
],
"holdingsLastFetchedAt": "2023-05-07T00:00:00Z"
}MF holdings are optional at creation — you can seed them here via holdings[] (with holdingsLastFetchedAt), let them be fetched during the journey, or push them later via Update DLA Holdings.
LAS (Loan Against Stocks)
Use this when the user will pledge stock holdings.
| Field | Required | Notes |
|---|---|---|
pan | yes | User's PAN. |
authContact | yes | At least number. |
assetType | yes | Must be STOCKS for LAS. |
stockHoldings | yes | Array of stock holdings. For LAS, only stockHoldings are used for eligibility — MF holdings are not required. |
productType | no | Defaults to lamf. |
dob | no | Same format as LAMF. |
referrer | no | Defaults to your partner name. |
opaqueId | no | Same as LAMF — see Passing your own identifier. |
name, age, isNri, contacts | no | Optional pre-fill attributes. |
Example request (LAS):
{
"pan": "EAWPK9000N",
"authContact": { "number": "9919921000", "countryCode": "+91" },
"assetType": "STOCKS",
"stockHoldings": [
{
"name": "TATA STEEL LIMITED",
"isin": "INE081A01020",
"type": "EQUITY",
"units": 100,
"isDemat": true,
"dpId": "1208160010814163"
}
],
"productType": "lamf",
"opaqueId": "partner-ref-12345", // optional - your own identifier for this user, echoed back in webhooks and Get unity user details
"contacts": [
{ "type": "PHONE", "phone": { "number": "9919921000", "countryCode": "+91" } },
{ "type": "EMAIL", "email": "[email protected]" }
],
"name": "Vishal Pal",
"age": 55,
"isNri": false
}For STOCKS, every holding needs a dpId, and isDemat is always true.
Passing your own identifier
opaqueId is an optional free-form string you can attach to a Unity user to map it back to a user in your own system. It's supported in both the LAMF and LAS payloads.
- It's stored only when this call creates a new Unity user. If the call resolves to an existing user (see Idempotency and repeated calls), the
opaqueIdyou pass is ignored and the value stored at creation is kept. - Once set, it's echoed back on every webhook payload and in Get unity user details.
- If it was never set, those payloads carry
"opaqueId": "".
This is a separate field from config.opaqueId in Create interaction, which tags a single interaction rather than the user.
Success response (HTTP 200)
{
"code": 0,
"data": {
"lender": "sib",
"referrer": "gatewaydemo-stag",
"unityUserId": "69a960a8fd4c213259f9a609"
},
"message": "SUCCESS"
}data.unityUserId is the identifier to store and reuse across the rest of the integration.
Error responses
All errors follow the same shape:
{
"message": "<error_message>",
"code": "<error_code>",
"data": "<optional_data>"
}| HTTP status | code | message / scenario |
|---|---|---|
| 400 | 4000 | invalid_request — invalid JSON, invalid payload, invalid DOB format, or holdings present but holdingsLastFetchedAt missing. |
| 400 | 4000 | invalid_request:auth_contact_required — authContact missing or number empty. |
| 400 | 4303 | invalid_product_type — product type or asset type not allowed for the partner. |
| 400 | 4309 | invalid_asset_type — invalid asset type. |
| 400 | 4209 | invalid_pan — non-individual PAN. |
| 400 | 3003 | Name is required. |
| 400 | 3004 | Age or DOB is required. |
| 400 | 3006 | IsNRI is required. |
| 400 | 4406 | not_eligible_wrt_age_limit. |
| 400 | 4407 | not_eligible_wrt_nri_status. |
| 400 | 4408 | no_eligible_lender_found — user is not eligible for a loan (SIB eligibility check failed). |
| 401 | 4001 | partner_inactive. |
| 403 | 3002 | Phone already used — auth contact already linked to another Unity user. |
| 500 | 2000 | internal_server_error. |
| 200 | 0 | SUCCESS with an error key referrer_already_mapped — user already exists with a different referrer; data still contains unityUserId, referrer, lender (backward-compatible success with a warning). |
Exact message and code values are defined by the Unity API contract; the table above summarises the main scenarios partners may see.
Disabled Lien Marking (mock users) is not available for SIBThe Disabled Lien Marking (DLM) testing mode — where
isLienMarkingMocked: truecreates a mock user that skips real lien marking — is not available for SIB.isLienMarkingMockedstaysfalseregardless of what you pass.