Customers

Update customer by ID

Update a customer's metadata by their system-generated ID.

Most customer updates complete synchronously and return 200 with the updated customer. If the request changes email for a customer that has one or more tied Embedded Wallet internal accounts with EMAIL_OTP credentials, or changes phoneNumber for a customer that has one or more tied Embedded Wallet internal accounts with SMS_OTP credentials, the contact update uses the two-step signed-retry flow so the customer's wallet session authorizes the authentication credential update. On the signed retry, Grid updates the customer contact field and every tied matching OTP credential across all tied Embedded Wallets as one logical operation. If any tied credential cannot be updated, the customer contact field is not changed.

Update email and phoneNumber in separate PATCH calls. A request that includes both fields is rejected.

For an Embedded Wallet email or SMS auth phone update:

  1. Call PATCH /customers/{customerId} with the full update body and no signature headers. Grid returns 202 with payloadToSign, requestId, and expiresAt. The pending challenge binds the submitted update fields and the set of tied Embedded Wallet OTP credentials that must be updated.

  2. Use the session API keypair of a verified authentication credential on one of the customer's tied Embedded Wallets to build an API-key stamp over payloadToSign, then retry the same request with that full stamp as the Grid-Wallet-Signature header and the requestId echoed back as the Request-Id header. The retry body must carry the same update fields submitted in step 1. The signed retry returns 200 with the updated customer.

patch/customers/{customerId}

Headers

Grid-Wallet-Signaturestring

Full API-key stamp built over the prior payloadToSign with the session API keypair of a verified authentication credential on one of the customer's tied Embedded Wallets. Required on the signed retry for Embedded Wallet email or SMS auth phone updates; ignored on the initial call and on customer updates that complete synchronously.

Request-Idstring

The requestId returned in a prior 202 response, echoed back on the signed retry so the server can correlate it with the issued challenge. Required on the signed retry for Embedded Wallet email or SMS auth phone updates; must be paired with Grid-Wallet-Signature.

Request body

OR

Example request

{
  "customerType": "INDIVIDUAL",
  "currencies": [
    "USD",
    "EUR",
    "USDC"
  ],
  "email": "john.doe@example.com",
  "phoneNumber": "+14155551234",
  "umaAddress": "$john.doe@uma.domain.com",
  "endUserTermsConsent": {
    "ipAddress": "198.51.100.24",
    "termsVersion": "V1",
    "acceptanceMethod": "CHECKBOX"
  },
  "kycStatus": "APPROVED",
  "fullName": "John Michael Doe",
  "birthDate": "1990-01-15",
  "nationality": "US",
  "address": {
    "line1": "123 Main Street",
    "line2": "Apt 4B",
    "city": "San Francisco",
    "state": "CA",
    "postalCode": "94105",
    "country": "US"
  },
  "idType": "SSN",
  "identifier": "123-45-6789",
  "countryOfIssuance": "US",
  "sourceOfFundsCategories": [
    "SALARY"
  ],
  "sourceOfFundsOtherDescription": "Contest winnings",
  "sourceOfWealthCategories": [
    "SALARY",
    "INVESTMENTS"
  ],
  "sourceOfWealthOtherDescription": "Royalty income from published works",
  "purposeOfAccount": "CONTRACTOR_PAYOUTS",
  "purposeOfAccountOtherDescription": "Household budgeting between spouses",
  "expectedMonthlyTransactionCount": "COUNT_100_TO_500",
  "expectedMonthlyTransactionVolume": "VOLUME_100K_TO_1M",
  "annualIncomeRange": "RANGE_100K_250K",
  "netWorthRange": "RANGE_500K_1M",
  "pepStatus": "NONE"
}

Response

Customer updated successfully. For Embedded Wallet email or SMS auth phone updates, this is returned only on the signed retry after the customer contact field and all tied matching OTP credentials have been updated.

OR

Example response

{
  "id": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "platformCustomerId": "9f84e0c2a72c4fa",
  "customerType": "INDIVIDUAL",
  "endUserTermsConsent": {
    "ipAddress": "198.51.100.24",
    "termsVersion": "V1",
    "acceptanceMethod": "CHECKBOX"
  },
  "region": "US",
  "currencies": [
    "USD",
    "USDC"
  ],
  "email": "john.doe@example.com",
  "phoneNumber": "+14155551234",
  "umaAddress": "$john.doe@uma.domain.com",
  "createdAt": "2025-07-21T17:32:28Z",
  "updatedAt": "2025-07-21T17:32:28Z",
  "contactVerification": {
    "email": "VERIFIED",
    "phone": "VERIFIED"
  },
  "kycStatus": "APPROVED",
  "fullName": "John Michael Doe",
  "birthDate": "1990-01-15",
  "nationality": "US",
  "address": {
    "line1": "123 Main Street",
    "line2": "Apt 4B",
    "city": "San Francisco",
    "state": "CA",
    "postalCode": "94105",
    "country": "US"
  },
  "idType": "SSN",
  "identifier": "123-45-6789",
  "countryOfIssuance": "US",
  "sourceOfFundsCategories": [
    "SALARY"
  ],
  "sourceOfFundsOtherDescription": "Contest winnings",
  "sourceOfWealthCategories": [
    "SALARY",
    "INVESTMENTS"
  ],
  "sourceOfWealthOtherDescription": "Royalty income from published works",
  "purposeOfAccount": "CONTRACTOR_PAYOUTS",
  "purposeOfAccountOtherDescription": "Household budgeting between spouses",
  "expectedMonthlyTransactionCount": "COUNT_100_TO_500",
  "expectedMonthlyTransactionVolume": "VOLUME_100K_TO_1M",
  "annualIncomeRange": "RANGE_100K_250K",
  "netWorthRange": "RANGE_500K_1M",
  "pepStatus": "NONE"
}

Changes

Changed in 8 of the 24 revisions of this API.43622

  • 27ff0fdca01c66See the full diff
    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdCountryOfIssuance

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdType

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdentifier

      request-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdCountryOfIssuance from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdType from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/taxIdentifier from the response with the 200 status

      response-optional-property-removed

    • added the new optional request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/countryOfIssuance

      new-optional-request-property

    • added the new optional request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/idType

      new-optional-request-property

    • added the new optional request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/allOf[subschema #1]/identifier

      new-optional-request-property

    • added the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/countryOfIssuance to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/idType to the response with the 200 status

      response-optional-property-added

    • added the optional write-only property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/allOf[subschema #1]/identifier to the response with the 200 status

      response-optional-write-only-property-added

    • added the new EXTERNAL_ACCOUNT_VERIFICATION_REQUIRED enum value to the code response property for the response status 400

      response-property-enum-value-added

    This revision also has 1 change that name no endpoint, such as unreferenced schemas being removed. See the revision's changelog

    • added the new TRANSACTION_SIZE_LIMIT_EXCEEDED enum value to the code response property for the response status 400

      response-property-enum-value-added

    • added the new CARDHOLDER_KYC_NOT_APPROVED enum value to the code response property for the response status 400

      response-property-enum-value-added

    • added the new CARD_ALREADY_CLOSED enum value to the code response property for the response status 409

      response-property-enum-value-added

    • added the new CARD_NOT_MUTABLE enum value to the code response property for the response status 409

      response-property-enum-value-added

    • added the new INVALID_STATE_TRANSITION enum value to the code response property for the response status 409

      response-property-enum-value-added

  • 526036c12609110See the full diff
    • added the new END_USER_TERMS_VERSION_NOT_FOUND enum value to the code response property for the response status 400

      response-property-enum-value-added

    • added the new optional request property oneOf[subschema #1: Individual Customer Update Request]/allOf[subschema #1: Customer Update Request]/endUserTermsConsent

      new-optional-request-property

    • added the new optional request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/primaryContactFirstName

      new-optional-request-property

    • added the new optional request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/primaryContactLastName

      new-optional-request-property

    • added the new optional request property oneOf[subschema #2: Business Customer Update Request]/allOf[subschema #1: Customer Update Request]/endUserTermsConsent

      new-optional-request-property

    • added the optional property oneOf[subschema #1: Individual Customer]/allOf[Customer]/endUserTermsConsent to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/primaryContactFirstName to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/primaryContactLastName to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #2: Business Customer]/allOf[Customer]/endUserTermsConsent to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/primaryContactFirstName to the response with the 200 status

      response-optional-property-added

    • added the optional property oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/primaryContactLastName to the response with the 200 status

      response-optional-property-added

  • b21ed434ee6e4216See the full diff
    • added CustomerEdd subschema #1 to the oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/ request property allOf list

      request-property-all-of-added

    • the oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/ request property type/format changed from object/ to /

      request-property-type-changed

    • the oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/ response's property type/format changed from object/ to / for status 200

      response-property-type-changed

    • removed the required property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/customerType from the response with the 200 status

      response-required-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/address

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/birthDate

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/customerType

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/fullName

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/kycStatus

      request-property-removed

    • removed the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[IndividualCustomerFields]/nationality

      request-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/address from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/birthDate from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/fullName from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/kycStatus from the response with the 200 status

      response-optional-property-removed

    • removed the optional property oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/nationality from the response with the 200 status

      response-optional-property-removed

    • added the new BENEFICIARY_TRUSTED enum value to the code response property for the response status 409

      response-property-enum-value-added

    • added the new CHARITY enum value to the oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new CHARITY enum value to the oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new PRIVATE_FOUNDATION enum value to the oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new PRIVATE_FOUNDATION enum value to the oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new PUBLICLY_LISTED_COMPANY enum value to the oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new PUBLICLY_LISTED_COMPANY enum value to the oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new SCA_SESSION_REQUIRED enum value to the code response property for the response status 409

      response-property-enum-value-added

    • added the new TRUST enum value to the oneOf[subschema #2: Business Customer]/allOf[BusinessCustomerFields]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new TRUST enum value to the oneOf[subschema #2: Business Customer]/allOf[subschema #3]/businessInfo/entityType response property for the response status 200

      response-property-enum-value-added

    • added the new CHARITY enum value to the request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/entityType

      request-property-enum-value-added

    • added the new PRIVATE_FOUNDATION enum value to the request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/entityType

      request-property-enum-value-added

    • added the new PUBLICLY_LISTED_COMPANY enum value to the request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/entityType

      request-property-enum-value-added

    • added the new TRUST enum value to the request property oneOf[subschema #2: Business Customer Update Request]/allOf[BusinessCustomerFields]/businessInfo/entityType

      request-property-enum-value-added

    • added the optional property details/errors to the response with the 400 status

      response-optional-property-added

    • added CustomerEdd subschema #1 to the oneOf[subschema #1: Individual Customer]/allOf[IndividualCustomerFields]/ response property allOf list for the response status 200

      response-property-all-of-added

    • added the new TRANSACTION_NOT_CANCELLABLE enum value to the code response property for the response status 409

      response-property-enum-value-added

    This revision also has 1 change that name no endpoint, such as unreferenced schemas being removed. See the revision's changelog

    • added the new PASSKEY_ALREADY_ENROLLED enum value to the code response property for the response status 409

      response-property-enum-value-added

    This revision also has 1 change that name no endpoint, such as unreferenced schemas being removed. See the revision's changelog