# Update an identity Identity Management v3 This topic describes the v3 identity model. **Identity Management v3** is recommended for new integrations. Identity Management v3 is an **upcoming feature**. For information on availability, early access, or migration, please contact your Ripple representative. The supported payment corridors will be: - US • USD - EU • EUR - MX • MXN - BR • BRL - CO • COP - CA • CAD - GB • GBP - Africa • GHS, NGN, RWF, UGX, ZAR, ZMW This tutorial shows how to use `PUT /v3/identities/{identity-id}` to update an existing identity in **Identity Management v3**. It covers updating metadata, PII fields, and payout rail validation, and explains how identity versioning works and what it means for your integration. ## Before you begin To follow these examples, you need: - Base URL for Identity Management (for example, `https://{base-url}`) - An access token with `participants:update` scope - An `identityId` from a previously created identity In all examples below, replace: - `{base-url}` with your actual PII base URL - `` with a valid OAuth2 access token - `{identity-id}` with a real `identityId` returned by the API ## How identity updates work ### Immutable versioning Every successful call to `PUT /v3/identities/{identity-id}` creates a **new version** of the identity. The previous version is preserved and remains available for retrieval and audit. The `identityId` never changes. For example, if an identity is currently at `version: 2`, a successful update produces `version: 3`. The version 2 record remains accessible via `GET /v3/identities/{identity-id}?version=2`. ### Partial updates The PUT request body supports partial updates. You only need to include the fields you want to change. Fields you omit retain their current values. For example, to update only the `nickName`, you only need to send `nickName` in the request body. All other PII and metadata is preserved unchanged. ### Effect on payments Payments are tied to a specific `identityId` and `version` at the time of creation. Updating an identity creates a new version, but **does not affect payments that were already created** using an earlier version. Those payments continue to reference the identity version they were created with. ### What you can and cannot change | Field(s) | Can update? | Notes | | --- | --- | --- | | `nickName` | Yes | — | | `tags` | Yes | Replaces the existing tags array entirely | | `internalId` | Yes | Must remain unique across all ACTIVE identities in your organization | | `validatePayoutRails` | Yes | Re-validates the identity PII against the specified rails | | `individual` fields | Yes | Any field within the `individual` object (address, contact, documents, etc.) | | `business` fields | Yes | Any field within the `business` object (name, address, contact, registration, etc.) | | `identityType` | **No** | Set at creation (INDIVIDUAL or BUSINESS). Cannot be changed. | | `paymentRole` | **No** | Set at creation (ORIGINATOR or BENEFICIARY). Cannot be changed. | DEACTIVATED identities Updating a DEACTIVATED identity is not supported. Deactivation is permanent. If you need to resume activity for a deactivated party, create a new identity. ## Update identity metadata Metadata fields (`nickName`, `tags`) are the simplest update. No PII validation is triggered. **Example: Update nickname and tags** ```bash curl -X PUT "https://{base-url}/v3/identities/99254c4f-f207-4792-a846-06928825018c" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "nickName": "Alice Chen - Primary USD", "tags": ["usd", "high-value", "verified"] }' ``` **Response (200 OK)** ```json { "identityId": "99254c4f-f207-4792-a846-06928825018c", "identityState": "ACTIVE", "version": "2", "schemaVersion": "1.0.0", "identityType": "INDIVIDUAL", "paymentRole": "ORIGINATOR", "internalId": "customer-12345", "nickName": "Alice Chen - Primary USD", "tags": ["usd", "high-value", "verified"], "createdAt": "2025-10-01T18:46:41.833Z", "updatedAt": "2026-03-10T09:15:10.000Z", "individual": { "firstName": "Alice", "lastName": "Chen", "dateOfBirth": "1990-05-14", "citizenship": "US", "address": { "streetAddress": ["123 Main Street"], "city": "San Francisco", "stateOrProvince": "CA", "postalCode": "94105", "country": "US" } } } ``` Notice that `version` has incremented from `1` to `2`, and `updatedAt` reflects the time of the update. All other fields are unchanged. Tags are replaced, not merged The `tags` field is replaced in full on each update. If you send `"tags": ["usd"]`, all previous tags are removed and replaced with the new value. Fetch the current identity first if you need to preserve existing tags. ## Update PII fields ### Update an INDIVIDUAL identity Use this to correct or update personal details such as address, contact information, or identity documents. **Example: Update address** ```bash curl -X PUT "https://{base-url}/v3/identities/99254c4f-f207-4792-a846-06928825018c" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "individual": { "address": { "streetAddress": ["500 Market Street", "Suite 200"], "city": "San Francisco", "stateOrProvince": "CA", "postalCode": "94103", "country": "US" } } }' ``` **Response (200 OK)** ```json { "identityId": "99254c4f-f207-4792-a846-06928825018c", "identityState": "ACTIVE", "version": "3", "schemaVersion": "1.0.0", "identityType": "INDIVIDUAL", "paymentRole": "ORIGINATOR", "internalId": "customer-12345", "nickName": "Alice Chen - Primary USD", "tags": ["usd", "high-value", "verified"], "createdAt": "2025-10-01T18:46:41.833Z", "updatedAt": "2026-03-10T10:22:05.000Z", "individual": { "firstName": "Alice", "lastName": "Chen", "dateOfBirth": "1990-05-14", "citizenship": "US", "address": { "streetAddress": ["500 Market Street", "Suite 200"], "city": "San Francisco", "stateOrProvince": "CA", "postalCode": "94103", "country": "US" } } } ``` ### Update a BUSINESS identity **Example: Update email and phone** ```bash curl -X PUT "https://{base-url}/v3/identities/0116bacc-ffbf-4fa2-a29c-ecd9ea346806" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "business": { "email": "ops@widgetsorg.com", "phone": "+14155550199" } }' ``` **Response (200 OK)** ```json { "identityId": "0116bacc-ffbf-4fa2-a29c-ecd9ea346806", "identityState": "ACTIVE", "version": "2", "schemaVersion": "1.0.0", "identityType": "BUSINESS", "paymentRole": "BENEFICIARY", "internalId": "counterparty-7890", "nickName": "Widgets Org MX", "tags": ["beneficiary", "mx"], "createdAt": "2025-10-01T16:14:13.200Z", "updatedAt": "2026-03-10T11:05:30.000Z", "business": { "businessName": "Widgets Org", "incorporationCountry": "US", "email": "ops@widgetsorg.com", "phone": "+14155550199", "registration": [ { "number": "123ABC", "type": "INCORPORATION_CERTIFICATE" } ], "address": { "streetAddress": ["123 Example MA"], "city": "Boston", "stateOrProvince": "MS", "postalCode": "12345", "country": "US" } } } ``` ## Add or change payout rail validation Use `validatePayoutRails` to validate an identity's PII against additional payout rails. This is useful when you are onboarding a beneficiary to a new corridor that requires specific PII fields. **Example: Add EU SEPA and GB FPS validation** ```bash curl -X PUT "https://{base-url}/v3/identities/99254c4f-f207-4792-a846-06928825018c" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "validatePayoutRails": ["US_ACH", "EU_SEPA", "GB_FPS"] }' ``` If the identity's current PII satisfies all requirements for the specified rails, the update succeeds and returns the new version. If any required fields are missing for any of the specified rails, the request returns **400 Bad Request** with field-level details: ```json { "code": "VALIDATION_ERROR", "title": "Identity validation failed", "description": "The identity is missing required fields for the specified payout rails.", "details": [ { "field": "individual.dateOfBirth", "message": "Date of birth is required for EU_SEPA beneficiary identities" } ] } ``` To resolve this, add the missing PII fields to the same update request: ```bash curl -X PUT "https://{base-url}/v3/identities/99254c4f-f207-4792-a846-06928825018c" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "validatePayoutRails": ["US_ACH", "EU_SEPA", "GB_FPS"], "individual": { "dateOfBirth": "1990-05-14" } }' ``` validatePayoutRails is advisory Including a rail in `validatePayoutRails` does not prevent you from adding financial instruments for other rails, and omitting a rail does not block you from using it later. Validation is performed at the point of financial instrument creation and payment initiation regardless. ## Update internalId You can change an identity's `internalId` using a PUT request. The new value must not already be in use by another ACTIVE identity in your organization. **Example: Rename an internalId** ```bash curl -X PUT "https://{base-url}/v3/identities/99254c4f-f207-4792-a846-06928825018c" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "internalId": "customer-12345-v2" }' ``` If the requested `internalId` is already used by a different ACTIVE identity, the request returns **409 Conflict**: ```json { "code": "CONFLICT", "title": "Identity conflict", "description": "The provided internalId already exists on a different identity.", "details": [ { "field": "internalId", "message": "An ACTIVE identity with internalId 'customer-12345-v2' already exists (identityId: 7ea3399c-1234-5678-8d8f-d320ea406630)" } ] } ``` For guidance on handling 409 conflicts, see [Create and manage identities](/products/payments-direct-2/api-docs/tutorials/create-and-manage-identities#handling-internalid-conflicts-409-conflict). ## Updating a BLOCKED identity An identity may be in `BLOCKED` state if it was flagged for compliance review or was imported from a previous version of the API. BLOCKED identities cannot be used to create new payments. Calling `PUT /v3/identities/{identity-id}` on a BLOCKED identity updates the identity details **and** transitions the identity state from `BLOCKED` back to `ACTIVE`. BLOCKED state and reactivation A successful PUT on a BLOCKED identity sets `identityState` to `ACTIVE`. Confirm with your compliance team that reactivation is appropriate before submitting an update to a BLOCKED identity. **Example: Update a BLOCKED identity** ```bash curl -X PUT "https://{base-url}/v3/identities/{identity-id}" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "nickName": "Reviewed and cleared" }' ``` **Response (200 OK)** ```json { "identityId": "{identity-id}", "identityState": "ACTIVE", "version": "3", ... } ``` The `identityState` in the response is `ACTIVE`, confirming the identity has been reactivated as part of the update. ## Error reference | HTTP status | When it occurs | What to do | | --- | --- | --- | | `400 Bad Request` | Missing or invalid fields, or PII fails validation for specified `validatePayoutRails` | Check the `details[]` array for field-level messages. Correct the request and retry. | | `404 Not Found` | The `identity-id` does not exist | Verify the `identityId` and retry. | | `409 Conflict` | The `internalId` in the request is already used by a different ACTIVE identity | Use the existing identity, or choose a different `internalId`. | | `500 Internal Server Error` | Processing error on the Ripple side | Retry after a short delay. Contact support if the error persists. | ## Next steps - To understand the full identity data model and versioning behavior, see [Payment identities](/products/payments-direct-2/api-docs/concepts/payment-identities). - To create identities and manage the full lifecycle including deactivation, see [Create and manage identities](/products/payments-direct-2/api-docs/tutorials/create-and-manage-identities). - To add or update bank account and payout details for an identity, see [Create and manage financial instruments](/products/payments-direct-2/api-docs/tutorials/create-and-manage-financial-instruments).