When you create an INR recipient via the Wise API, we automatically run a series of validations (format checks) and verifications (Confirmation of Payee, or CoP) before returning the response.
This guide provides details specific to the verification that occurs when creating INR recipients.
INR supports two recipient types:
| Recipient types | API value | Description |
|---|---|---|
| Bank account | indian | IFSC code + bank account number. |
| UPI | indian_upi | UPI Virtual Payment Address (VPA). A unique ID (for example, name@bankprovider) that maps to a bank account and lets recipients receive payments instantly via India's Unified Payments Interface. |
Field-level validation checks the format and correctness of input fields. If any fail, the recipient is not created and the API returns a validation error.
The following validations occur when the recipient type is indian:
| Field | Rules | Error if invalid |
|---|---|---|
| Account number | 5–20 alphanumeric characters | ACCOUNT_NUMBER_NOT_VALID |
| IFSC Code | 11 characters, format XXXX0XXXXXX (4 letters, 0, 6 alphanumeric) | NOT_VALID |
| IFSC Bank Code | First 4 characters must map to a known bank | INDIA_LOCAL_IFSC_UNKNOWN_BANK_DISALLOWED |
| Name | At least first name + last name (two words separated by a space); max 140 characters | NOT_VALID |
The following validations occur when the recipient type is indian_upi:
| Field | Rules | Error if invalid |
|---|---|---|
| VPA (accountNumber) | 5–255 characters, format username@provider | NOT_VALID |
| Name | At least first name + last name (two words separated by a space); max 140 characters | NOT_VALID |
If you provide a single-word name like "Rajesh" instead of "Rajesh Kumar":
{
"errors": [
{
"code": "NOT_VALID",
"path": "name/fullName",
"message": "The name provided is not valid."
}
]
}Verification runs only after all field validations pass. The result is reported in the confirmations object of the response.
For INR, verification confirms both account existence (type ACCOUNT_EXISTENCE) and name matching (type NAME_MATCHING) in a single call. These happen sequentially — account existence is verified first, and if the account exists, then name matching runs.
- Wise calls the external verification provider with the recipient's account details.
- The provider first verifies the account exists.
- If not, the outcome is
FAILURE(account doesn't exist) and name matching is skipped. - If the account exists, the provider returns the registered name on the account.
- Wise compares the registered name with the name you provided using our name-matching algorithm.
The comparison produces one of three confidence levels:
| Confidence | What it means | Outcome | Requires acceptance? |
|---|---|---|---|
| GREEN | Names match | SUCCESS | No. Proceed to transfer. |
| YELLOW | Close match (partial name overlap) | PARTIAL_FAILURE | Yes. Show result to user, make PATCH request to accept. |
| RED | Names don't match | FAILURE | Yes. Show result to user, make PATCH request to accept. |
If the verification provider returns an error or times out, the outcome is COULD_NOT_CHECK. In this case, the recipient is still created, but you should inform the user that verification wasn't possible.
| Recipient type | Fields checked (V1) | Fields checked (V2) |
|---|---|---|
| Bank account |
|
|
| UPI |
|
|
In some cases, verification discovers the account details are invalid at the provider level. These are blocking outcomes, meaning they cause recipient creation to fail, even though field-level validation passed.
| Blocking outcome | Account type | When it happens |
|---|---|---|
INVALID_ACCOUNT_NUMBER | Bank account | Bank says the account number is invalid. |
INVALID_ACCOUNT_DETAILS | Bank account | Bank says the account number or IFSC is invalid |
INVALID_IFSC_CODE | Bank account | Bank says the IFSC is invalid or disallowed |
INVALID_UPI_ID | UPI | UPI provider says the VPA is invalid |
| Outcome | Blocking? | When it happens |
|---|---|---|
SUCCESS | No | Name matches |
PARTIAL_FAILURE | No | Name partially matches |
FAILURE | No | Name doesn't match |
FAILURE | No | Account not found at the bank |
COULD_NOT_CHECK | No | Error during name comparison |
COULD_NOT_CHECK | No | Internal service error |
COULD_NOT_CHECK | No | Internal timeout |
COULD_NOT_CHECK | No | Bank provider returned an error |
COULD_NOT_CHECK | No | Bank provider timed out |
| (blocks creation) | Yes | Bank says account number is invalid |
| (blocks creation) | Yes | Bank says account number or IFSC is invalid |
| (blocks creation) | Yes | Bank says IFSC is invalid |
| Outcome | Blocking? | When it happens |
|---|---|---|
SUCCESS | No | Name matches |
PARTIAL_FAILURE | No | Name partially matches |
FAILURE | No | Name doesn't match |
FAILURE | No | VPA not found |
COULD_NOT_CHECK | No | Error during name comparison |
COULD_NOT_CHECK | No | Internal service error |
COULD_NOT_CHECK | No | Internal timeout |
COULD_NOT_CHECK | No | UPI provider returned an error |
COULD_NOT_CHECK | No | UPI provider timed out |
| (blocks creation) | Yes | UPI says VPA is invalid |
| Outcome | Recipient created? | What to do |
|---|---|---|
SUCCESS | Yes | Proceed with the transfer. No additional action needed. |
PARTIAL_FAILURE | Yes | Show the verification result to the user. If they accept, call PATCH /v1/accounts/{id}/confirmations (or V2 equivalent). |
FAILURE | Yes | Show warning to the end user. If they choose to proceed anyway, make PATCH request to accept the risk. |
COULD_NOT_CHECK | Yes | Inform the user that verification wasn't possible. If they accept, make PATCH request to proceed. |
| (blocking error) | No | Fix the invalid input and retry recipient creation |
Both V1 and V2 endpoints run the same validations and verifications. The difference is the field naming and how the confirmation result is returned.
| Aspect | /v1/accounts/ | /v2/accounts/ |
|---|---|---|
| Confirmations in response | Always included in the recipient response (if available) | Only included if you request them via responseConfiguration.additionalInformation |
| Name field path in confirmations | accountHolderName | name/fullName |
| Recommended update path | accountHolderName | name/fullName |
| Accept confirmation | PATCH /v1/accounts/{id}/confirmations | PATCH /v2/accounts/{id}/confirmations |
When creating a recipient with V2, include the following in your request to receive the confirmations field:
{
"type": "indian",
"details": { ... },
"responseConfiguration": {
"additionalInformation": ["CONFIRMATION_RESULT"]
}
}Without this, V2 will create the recipient and run all checks, but will not include the confirmations field in the response. You would then need to fetch it separately via GET /v2/accounts/{id}.
All payloads below show the confirmations field as it appears in the response after creating a recipient.
The resolvedName and providedName fields are null in production responses.
{
"id": 123456,
"type": "indian",
"accountHolderName": "Rajesh Kumar",
"details": {
"accountNumber": "1234567890",
"ifscCode": "SBIN0001234"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "SUCCESS",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": false,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": null,
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}{
"id": 123456,
"type": "indian",
"accountHolderName": "Rajesh Kumar",
"details": {
"accountNumber": "1234567890",
"ifscCode": "SBIN0001234"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "PARTIAL_FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": "The name you entered doesn't match the account holder's name. Please check and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}{
"id": 123456,
"type": "indian",
"accountHolderName": "Rajesh Kumar",
"details": {
"accountNumber": "1234567890",
"ifscCode": "SBIN0001234"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": "The name you entered doesn't match the account holder's name. Please check and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}V1 response (V2 uses name/fullName instead of accountHolderName in fieldsChecked):
{
"id": 123456,
"type": "indian",
"accountHolderName": "Rajesh Kumar",
"details": {
"accountNumber": "1234567890",
"ifscCode": "SBIN0001234"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": "We couldn't verify this account. Please check the details and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}For a service error or timeout.
V1 response (V2 uses name/fullName instead of accountHolderName in fieldsChecked):
{
"id": 123456,
"type": "indian",
"accountHolderName": "Rajesh Kumar",
"details": {
"accountNumber": "1234567890",
"ifscCode": "SBIN0001234"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "COULD_NOT_CHECK",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": "We couldn't verify the account holder's name right now. You can still proceed.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}UPI payloads have the same structure as Bank Account, but fieldsChecked contains only 2 fields (no IFSC):
- V1: [
"accountHolderName","details/accountNumber"] - V2: [
"name/fullName","details/accountNumber"]
{
"id": 789012,
"type": "indian_upi",
"accountHolderName": "Priya Sharma",
"details": {
"accountNumber": "priya.sharma@okicici"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "SUCCESS",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": false,
"fieldsChecked": ["accountHolderName", "details/accountNumber"],
"message": null,
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}{
"id": 789012,
"type": "indian_upi",
"accountHolderName": "Priya Sharma",
"details": {
"accountNumber": "priya.sharma@okicici"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "PARTIAL_FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber"],
"message": "The name you entered doesn't match the account holder's name. Please check and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}V1 response (V2 uses name/fullName in fieldsChecked):
{
"id": 789012,
"type": "indian_upi",
"accountHolderName": "Priya Sharma",
"details": {
"accountNumber": "priya.sharma@okicici"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber"],
"message": "The name you entered doesn't match the account holder's name. Please check and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}V1 response (V2 uses name/fullName in fieldsChecked):
{
"id": 789012,
"type": "indian_upi",
"accountHolderName": "Priya Sharma",
"details": {
"accountNumber": "invalid.vpa@okicici"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber"],
"message": "We couldn't verify this account. Please check the details and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}V1 response (V2 uses name/fullName instead of accountHolderName in fieldsChecked):
{
"id": 789012,
"type": "indian_upi",
"accountHolderName": "Priya Sharma",
"details": {
"accountNumber": "priya.sharma@okicici"
},
"confirmations": {
"acceptedOutcomes": false,
"acceptedAt": null,
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "COULD_NOT_CHECK",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber"],
"message": "We couldn't verify the account holder's name right now. You can still proceed.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}The requiresCustomerAcceptance field is true when the outcome value is PARTIAL_FAILURE, FAILURE, or COULD_NOT_CHECK.
Before you can use the recipient for a transfer, you must make a PATCH request to confirm the user has acknowledged the result.
Endpoint: PATCH /v1/accounts/{accountId}/confirmations or PATCH /v2/accounts/{accountId}/confirmations
Body:
{
"acceptedOutcomes": true
}The response mirrors the original confirmations object, but now acceptedOutcomes is true and acceptedAt contains a timestamp:
{
"confirmations": {
"acceptedOutcomes": true,
"acceptedAt": "2026-03-07T10:35:00Z",
"quoteId": null,
"outcomes": [
{
"type": "NAME_MATCHING",
"outcome": "FAILURE",
"timestamp": "2026-03-07T10:30:00Z",
"requiresCustomerAcceptance": true,
"fieldsChecked": ["accountHolderName", "details/accountNumber", "details/ifscCode"],
"message": "The name you entered doesn't match the account holder's name. Please check and try again.",
"resolvedName": null,
"providedName": null,
"recommendedUpdates": []
}
]
}
}- Create a recipient via
POST /v1/accounts/(or V2) with valid details. - Inspect the response. Check the
confirmations.outcomes.outcomefield. - If outcome requires acceptance (
requiresCustomerAcceptance: true), callPATCH /v1/accounts/{id}/confirmationswith{"acceptedOutcomes": true}. - Create a transfer using the accepted recipient.
The verification result depends on the relationship between the name you provide when creating the recipient and the registered name on the actual bank account or UPI.
| Registered name at bank | Name you provide | Expected outcome |
|---|---|---|
Rajesh Kumar Singh | Rajesh Kumar Singh | SUCCESS — exact match |
Rajesh Kumar Singh | Rajesh Kumar | PARTIAL_FAILURE — partial overlap |
Rajesh Kumar Singh | Rajesh Singh | PARTIAL_FAILURE — partial overlap |
Rajesh Kumar Singh | John Doe | FAILURE — no match |
| Registered name at bank | Name you provide | Expected outcome |
|---|---|---|
ACME Technologies Private Limited | ACME Technologies Private Limited | SUCCESS |
ACME Technologies Private Limited | Acme Technologies Pvt Ltd | SUCCESS — abbreviation understood |
ACME Technologies Private Limited | Acme Pvt Ltd | PARTIAL_FAILURE — missing key words |
ACME Technologies Private Limited | Totally Different Company Ltd | FAILURE |
You don't control the registered name. It comes from the bank/UPI provider. To trigger PARTIAL_FAILURE, you need to know the actual registered name and provide a partial match. An exact match gives SUCCESS. A completely different name gives FAILURE.
| Test scenario | Expected outcome |
|---|---|
| Valid account, matching name | SUCCESS |
| Valid account, close name | PARTIAL_FAILURE |
| Valid account, completely wrong name | FAILURE (NO_MATCH_NAME) |
| Non-existent account number / VPA | FAILURE (DOES_NOT_EXIST) |
| Invalid account number + IFSC combination (bank) | Blocking error: ACCOUNT_NUMBER_NOT_VALID on details/accountNumber |
| Invalid VPA format (UPI) | Blocking error: INDIAN_UPI_NOT_VALID |
| Invalid account number format (bank) | Blocking error: ACCOUNT_NUMBER_NOT_VALID |
| Invalid or disallowed IFSC (bank) | Blocking error: INDIA_LOCAL_IFSC_UNKNOWN_BANK_DISALLOWED |
| Single-word name (for example, "Rajesh") | Blocking error: NOT_VALID on name/fullName |
| Provider timeout/error | COULD_NOT_CHECK |