Document control
- Title
- Modifications — Changing an existing subscriber's details
- Version
- 1.0
- Status
- Issued
- Date of issue
- 12 October 2026
- Owner
- NPS Central Engineering
- Classification
- Confidential — for registered partners
1About this document
This document describes how a partner changes an existing subscriber's details: the change types, the payload for each, and the request lifecycle from submission to completion. These are the same changes a subscriber can make on their own NPS Central dashboard, through the same endpoints.
1.1Notation
In field tables, the presence column shows M for mandatory, O for optional, and C for conditional — mandatory only in the situation the description gives. Money means a decimal string with exactly two places, such as "5000.00".
2Before you begin
- Credential
- A subscriber session: an OTP session opened with a subject link, or a session opened on your own subject assertion.
- Scope
- modification
- Idempotency
- Submitting a request requires an Idempotency-Key header (section 4.1).
- Status reads
- GET /v1/modification-requests/{referenceId} also accepts your partner token, for requests you created.
3How a modification works
A modification is addressed to the subscriber, not to one account. NPS Central works out which of the subscriber's accounts the change applies to (they may be at different CRAs) and sends it to each. Each account is a leg of the request and has its own status; the request's overall status summarises its legs.
- Submit the change. You receive 202 Accepted and a referenceId (section 4).
- Acknowledge if the request is held because some accounts cannot take it (section 7).
- Follow the request by polling until it reaches a terminal status (section 6).
- Cancel if needed, only before anything has been sent to a CRA (section 8).
3.1Change types
| type | Changes | Applies to | Fresh OTP |
|---|---|---|---|
| CONTACT_UPDATE | Mobile, email, landline, alert preferences | Person | Yes — OTP at the new channel (OTP_NEW_CHANNEL) |
| ADDRESS_UPDATE | Permanent and/or correspondence address | Person | No — address from KYC source or checked against proof |
| BANK_UPDATE | Bank account, per tier | Account / tier | Yes — OTP at registered mobile, plus a penny drop of each new account |
| NOMINEE_UPDATE | Nominees, per tier | Tier | — |
| MARITAL_SPOUSE_UPDATE | Marital status and spouse name | Person | — |
| FATCA_UPDATE | FATCA / CRS tax-residency declaration | Person | — |
| TIER2_ACTIVATION | Opens a Tier II account | Account | Yes — OTP at registered mobile, plus a penny drop if a new Tier II bank account is given |
3.2Person-level and account-level changes
A person-level change has one value for the subscriber, such as their mobile number. It is all-or-nothing: if any account cannot take it, the whole request is refused. On a session narrowed with pop that left any account out, person-level changes are refused with 422 MODIFICATION_NEEDS_EVERY_ACCOUNT.
Account- and tier-level changes (bank, nominee, Tier II) can go to some accounts and not others. Where some accounts cannot take such a change, the request may be held until the subscriber agrees to go ahead without them (section 7); the status resource reports which policy applied in admissionPolicy.
3.3Yearly limits
Some changes may be made only a limited number of times in a financial year, counted across all of the subscriber's accounts. A request over the limit is refused with 409 CHANGE_FREQUENCY_EXHAUSTED; the error carries limit, used, period (for example FY2026-27) and resetsOn, so you can tell the subscriber when they can try again.
3.4Your fresh OTP
CONTACT_UPDATE, BANK_UPDATE and TIER2_ACTIVATION each need an OTP that you send and the subscriber answers immediately before you file the change. status must be VERIFIED and verifiedAt the time the subscriber answered, no more than 5 minutes before the request reaches NPS Central. Anything else is refused with 422 PARTNER_VERIFICATION_REQUIRED.
| Type | verification.method | The OTP was answered at |
|---|---|---|
| CONTACT_UPDATE | OTP_NEW_CHANNEL | The new mobile number or email address |
| BANK_UPDATE, TIER2_ACTIVATION | OTP_REGISTERED_CHANNEL | The subscriber's registered mobile number |
3.5Your verifications are your assertion
Where a change requires a verification — a penny drop, an OTP to a new mobile number, an address taken from CKYC — you carry it out and state the result in the request. NPS Central records that statement against your partner account. Keep the evidence on your side; verification.evidenceRef lets you record your own reference for it.
4Submitting a request
/v1/subjects/{subjectRef}/modification-requestsSubmit modification request- Credential
- Subscriber session
- Headers
- Idempotency-Key (required), Authorization
- Response
- 202 Accepted (section 4.4)
4.1Idempotency
Generate a new Idempotency-Key (up to 128 characters, e.g. a UUID) for each change the subscriber makes. If a request times out or you are unsure whether it arrived, resend it with the same key and the same body; you will get the original response rather than a second request. After a validation error, correct the body and submit with a new key.
4.2Common fields
Common fields
typeenumRequiredOne of the types in section 3.1. Decides the shape of payload.
subjectIdstringRequiredThe subjectRef, the same value as in the path.
scope.modeenumRequiredALL_LINKED: every account the session holds. SELECTED: only the PRANs in scope.prans. Person-level types always use ALL_LINKED.
scope.pransstring[]ConditionalWith SELECTED: up to 10 PRANs, from the session's accounts.
scope.tiersenum[]ConditionalBANK_UPDATE and NOMINEE_UPDATE only, and required for them: TIER_1 and/or TIER_2.
payloadobjectRequiredThe new values; see section 5.
verificationobjectConditionalYour verification for the request as a whole (section 4.3). Send it for CONTACT_UPDATE and ADDRESS_UPDATE.
documents[]arrayOptionalUp to 5 references to documents agreed for the change. Normally omitted.
remarksstringOptionalFree text, up to 200 characters.
4.3The verification object
verification
methodenumRequiredOTP_NEW_CHANNEL, OTP_REGISTERED_CHANNEL, KYC_SOURCE, DOCUMENT, BANK_ACCOUNT_VERIFICATION (inside a bank block only), or NONE.
statusenumRequiredVERIFIED, FAILED or NOT_REQUIRED.
verifiedAtdatetimeConditionalWhen you verified. Required with the OTP methods (section 3.4).
evidenceRefstringOptionalYour own reference for the evidence (vfy_…).
4.4Response — 202 Accepted
{
"referenceId": "ref_01JA6Z3KQ8M4N7P2R5S9T1V0X7",
"type": "MODIFICATION",
"statusUrl": "/api/v1/modification-requests/ref_01JA6Z3KQ8M4N7P2R5S9T1V0X7",
"acceptedAt": "2026-10-09T10:42:00.000Z",
"estimatedCompletion": "2026-10-09T10:47:00.000Z"
}referenceId is the only identifier you need to follow, acknowledge or cancel the request; store it against the subscriber's change in your system. A warnings[] array (code, field, message) is included when a CRA cannot carry a field you sent: the request is still accepted and the value kept in the NPS Central record.
5Payloads
Several shared structures (name, address, nominee, bank account) are reused by the change types below. Where a tier block may be the same as Tier I, you can send { "sameAsTier1": true } instead of repeating the details.
5.1Address and name
Address
line1String 1–30Requiredline2, line3, street, landmarkStringOptionalUp to 30 characters each.
cityString 1–40RequiredCity, town or district.
stateCodeStringRequiredThe two-digit state code, not the state name used at registration.
countryStringRequiredISO 3166-1 alpha-2, IN.
pincodeString 6RequiredSix digits, no leading zero.
5.2Bank account and nominee
Bank account
accountTypeEnumRequiredSAVINGS, CURRENT, NRE or NRO. NRE and NRO need non-resident status and are Tier I only.
accountNumberString 9–18Required9–18 digits.
ifscString 11Required11 characters; the fifth is always zero.
accountHolderNameString 1–60RequiredAs the bank holds it.
verificationobjectRequiredYour penny drop: { method: BANK_ACCOUNT_VERIFICATION, status: VERIFIED, verifiedAt }. Anything other than VERIFIED is refused with 422 BANK_ACCOUNT_NOT_VERIFIED.
A nominee list holds one to three nominees and always replaces the current list for that tier. Send every nominee, not only the one that changed. Each has ordinal (1–3), name, relationship, age, isMinor, sharePercentage (shares in a tier total 100), and guardian when isMinor is true.
5.3CONTACT_UPDATE
Send only what is changing, and at least one field: mobile, email, landline, smsAlerts, emailAlerts.
{
"type": "CONTACT_UPDATE",
"subjectId": "sub_01JA6Z3KQ8M4N7P2R5S9T1V0WZ",
"scope": { "mode": "ALL_LINKED" },
"payload": { "mobile": "+919812300000", "email": "ananya.new@example.com" },
"verification": { "method": "OTP_NEW_CHANNEL", "status": "VERIFIED",
"verifiedAt": "2026-10-09T10:41:00.000Z" }
}5.4ADDRESS, BANK, NOMINEE, MARITAL, FATCA and TIER II
- ADDRESS_UPDATE — usage (PERMANENT, CORRESPONDENCE or BOTH), permanent and/or correspondence address, optional proof. Verification KYC_SOURCE or DOCUMENT. No fresh OTP is needed.
- BANK_UPDATE — payload.tier1 and/or payload.tier2, each a bank account, matching scope.tiers. Each new account carries its own penny-drop verification.
- NOMINEE_UPDATE — payload.tier1 and/or payload.tier2, each { nominees: [ … ] } with the complete new list.
- MARITAL_SPOUSE_UPDATE — maritalStatus (MARRIED, UNMARRIED, WIDOWED or DIVORCED) and spouse name with MARRIED.
- FATCA_UPDATE — declared, isUsPerson, taxResidentOfIndiaOnly (set it explicitly), optional countryOfBirth / countryOfCitizenship, and residencies[] when not India-only.
- TIER2_ACTIVATION — schemePreference, bank, nominees (each may be { sameAsTier1: true }), optional opening contribution, and inline documents one CRA requires. Use scope.mode SELECTED with scope.prans to open it on particular accounts only.
6Following a request
/v1/modification-requests/{referenceId}Follow modification request- Credential
- Subscriber session, or your partner token for requests you created
Poll every 5 to 15 seconds until status is terminal. Once the subscriber session has ended, continue with your partner token.
6.1Status values
| Status | Meaning |
|---|---|
| ACCEPTED | Received. While held for acknowledgement, the request stays ACCEPTED with pendingAcknowledgement present. |
| VALIDATED, PENDING_AUTHORIZATION, AUTHORIZED, SUBMITTING, SUBMITTED_TO_CRA, PENDING_CRA | In progress. Treat any of these as "processing". |
| PENDING_EXTERNAL_ACTION | Waiting for a step in the CRA's own workflow; see externalAction. |
| COMPLETED | Terminal. Every leg completed. |
| PARTIALLY_COMPLETED | Terminal. Some legs completed and some did not; check legs[]. |
| REJECTED, FAILED | Terminal. The change was not made; see errors[] and legs[]. |
| CANCELLED | Terminal. Withdrawn before dispatch. |
| EXPIRED | Part of the shared status vocabulary. Treat it as terminal if it appears. |
6.2Response fields
| Field | Description |
|---|---|
| referenceId, type, subtype | The request, and the change type (e.g. BANK_UPDATE) in subtype. |
| status, statusDetail | Overall status (section 6.1) and any detail. |
| legs[] | One per account: the account reference, status, statusDetail, errors[], acknowledgedAt, and where relevant authorization and externalAction. |
| pendingAcknowledgement[] | While held: pran and reason for each account that cannot take the change (section 7). |
| errors[] | Field-level errors: field, code, message, and value where safe to echo. |
| history[] | Status changes, oldest first: status, at, detail. |
7Acknowledging a held request
/v1/modification-requests/{referenceId}:acknowledgeAcknowledge held request- Credential
- Subscriber session
When the admission policy is REQUIRE_ACKNOWLEDGEMENT and some accounts cannot take the change, the request is held and nothing is sent to any CRA. Show the subscriber the accounts in pendingAcknowledgement and why, and if they agree to go ahead without them, acknowledge.
{ "acknowledgedPrans": ["400011506418"] }acknowledgedPrans must list every PRAN in pendingAcknowledgement. The response is 200 with the request, and the change is then sent to the accounts that can take it. If the subscriber does not agree, cancel the request instead.
8Cancelling a request
/v1/modification-requests/{referenceId}:cancelCancel request- Credential
- Subscriber session
No request body. A request can be cancelled only while no leg has reached SUBMITTED_TO_CRA. The response is 200 with the request in status CANCELLED; after that point it is 409 CANCEL_NOT_PERMITTED and the request must be followed to its end.
9Errors
Errors are problem documents (application/problem+json); errors[] names each field at fault.
| HTTP | code | Cause |
|---|---|---|
| 400 | IDEMPOTENCY_KEY_REQUIRED | No Idempotency-Key on submit. |
| 401 | AUTH_FAILED | No session or an ended one, or a session without the modification scope. |
| 404 | NOT_FOUND, SUBJECT_NOT_FOUND | subjectRef, a PRAN in scope.prans, or a referenceId that is not yours. |
| 409 | CHANGE_FREQUENCY_EXHAUSTED | The year's allowance is spent; limit, used, period and resetsOn are in the error. |
| 409 | CANCEL_NOT_PERMITTED | Cancel after a leg reached the CRA. |
| 422 | PARTNER_VERIFICATION_REQUIRED | A contact, bank or Tier II change without your OTP in verification, with the wrong method, or with a verifiedAt older than 5 minutes. |
| 422 | BANK_ACCOUNT_NOT_VERIFIED | A new bank account without verification.status: VERIFIED. |
| 422 | MODIFICATION_NOMINEE_INVALID | Shares do not total 100, age and date of birth disagree, or a minor has no guardian. |
| 422 | MODIFICATION_NEEDS_EVERY_ACCOUNT | A person-level change on a pop-narrowed session that left accounts out. |
| 500 | MODIFICATION_UNROUTABLE | A destination cannot be reached right now. Retry with the same Idempotency-Key. |
| 501 | capability unsupported | The change is not available for the subscriber's CRA. |