Customers

Update customer by ID

Changed on

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}

Request

  • Base URL: https://api.lightspark.com/grid/2025-10-13
  • URL: https://api.lightspark.com/grid/2025-10-13/customers/{customerId}
  • Auth: HTTP basic

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"
  },
  "agreementConsents": [
    {
      "type": "LIGHTSPARK_END_USER_TERMS",
      "ipAddress": "198.51.100.24",
      "termsVersion": "2025-10-13",
      "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"
  },
  "agreementConsents": [
    {
      "type": "LIGHTSPARK_END_USER_TERMS",
      "ipAddress": "198.51.100.24",
      "termsVersion": "2025-10-13",
      "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

    • breaking

      added to the // request property allOf list

    • breaking

      added to the // request property allOf list

    • breaking

      the // request property type changed from object to no type

    • breaking

      the // request property type changed from object to no type

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • warning

      removed the request property ///

    • info

      added the new optional request property //

    • info

      added the new optional request property //

    • info

      request property // deprecated

    • info

      request property // deprecated

    • info

      added the optional property ///// to the response with the status

    • info

      added the optional property ///// to the response with the status

    • info

      the response optional property ///// became read-only for the status

    • info

      the response optional property ///// became read-only for the status

    • info

      added to the ///// response property allOf list for the response status

    • info

      added to the ///// response property allOf list for the response status

    • info

      removed from the ///// response property allOf list for the response status

    • info

      removed from the ///// response property allOf list for the response status

    • info

      response property oneOf[subschema #1: Individual Customer]/allOf[Customer]/endUserTermsConsent deprecated

    • info

      response property oneOf[subschema #2: Business Customer]/allOf[Customer]/endUserTermsConsent deprecated

    • breaking

      the ///////// request property's minItems was increased to 1

    • breaking

      the ///////// request property's minItems was increased to 1

    • warning

      the ///////// request property's maxLength was set to 500

    • warning

      the ///////// request property's maxLength was set to 500

    • warning

      the ///////// request property's maxLength was set to 500

    • warning

      the ////// request property's maxLength was set to 250

    • warning

      the ////// request property's maxLength was set to 100

    • warning

      the // request property's maxLength was set to 255

    • warning

      the /// request property's maxLength was set to 64

    • warning

      the ////// request property's maxLength was set to 250

    • warning

      the ////// request property's maxLength was set to 250

    • warning

      the ////// request property's maxLength was set to 100

    • warning

      the ////// request property's maxLength was set to 500

    • warning

      the ////// request property's maxLength was set to 100

    • warning

      the // request property's maxLength was set to 255

    • warning

      the /// request property's maxLength was set to 64