---
title: "Confirm a customer's phone verification code"
method: POST
path: "/customers/{customerId}/verify-phone/confirm"
tags: ["Contact Verification"]
---

# Confirm a customer's phone verification code

`POST /customers/{customerId}/verify-phone/confirm`

## Request

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

Submit the one-time code the customer received via SMS to mark their phone
as `VERIFIED`. On success, `contactVerification.phone` becomes `VERIFIED`.

Both email and phone must be `VERIFIED` before the customer can begin KYC.

In sandbox, the code is always `000000`.

## Request body

- ContactVerificationConfirmRequest: Request body for confirming an email or phone verification challenge.
  - `code` string, required: The one-time verification code the customer received via email or SMS. In sandbox, the code is always `000000`.

## Response `200`

Phone verified.

- union
  - IndividualCustomer: Enhanced-due-diligence (EDD) fields available as optional patchable attributes on an individual customer. Referenced via `allOf` from `IndividualCustomerFields`, so these appear as top-level optional fields on the customer resource itself; there is no separate EDD resource. The specific set required for a given customer is driven by the KYC provider's per-jurisdiction / per-flow / per-volume-tier rules (surfaced through `MISSING_FIELD` errors on `POST /verifications`).
    - `id` string: System-generated unique identifier
    - `platformCustomerId` string, required: Platform-specific customer identifier
    - `customerType` 'INDIVIDUAL', required: Whether the customer is an individual or a business entity
    - `endUserTermsConsent` EndUserTermsConsent: Deprecated; use `agreementConsents` instead, which records acceptance of each agreement separately. Reported only for a customer whose acceptance predates that field, and always as the `LIGHTSPARK_END_USER_TERMS` agreement.
      - `acceptedAt` string, date-time, required: Date and time when the customer accepted the End User Terms.
      - `ipAddress` string, required: IP address of the device the customer used when accepting the terms.
      - `termsVersion` string, required: Version identifier of the accepted Grid End User Terms.
      - `acceptanceMethod` 'CHECKBOX' | 'CLICK_TO_ACCEPT', required: Method the customer used to affirmatively accept an agreement.
    - `agreementConsents` AgreementConsent[]: The customer's recorded agreement acceptances, one entry per accepted type holding that type's most recent acceptance. Omitted when the customer has not accepted any agreement yet.
      - `type` 'LIGHTSPARK_END_USER_TERMS' | 'LIGHTSPARK_E_SIGN_CONSENT' | 'LIGHTSPARK_PRIVACY_POLICY' | 'LEAD_E_SIGN_CONSENT' | 'LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT' | 'LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT' | 'LEAD_PRIVACY_POLICY' | 'LEAD_CARDHOLDER_CONSUMER_AGREEMENT' | 'LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT', required: Identifies which Grid agreement a consent record or document refers to. Values are stable identifiers: a document's hosted URL or version may change, but its type does not. Accepting one agreement never implies acceptance of another, even when two agreements share a hosted page. The cardholder and accountholder agreements differ by customer kind: an `INDIVIDUAL` customer accepts the `_CONSUMER_` variant, and a `BUSINESS` customer accepts the `_COMMERCIAL_` one.
      - `acceptedAt` string, date-time, required: Date and time when the customer accepted this agreement. Must include a timezone offset and must not be in the future.
      - `ipAddress` string, required: IP address of the device the customer used when accepting this agreement.
      - `termsVersion` string, required: Version identifier of the accepted agreement, as returned for this type by the agreement documents endpoint. A version is scoped to its type; a version valid for one agreement is not valid for another.
      - `acceptanceMethod` 'CHECKBOX' | 'CLICK_TO_ACCEPT', required: Method the customer used to affirmatively accept an agreement.
    - `region` string: Country code (ISO 3166-1 alpha-2) representing the customer's regional identity and regulatory jurisdiction.
    - `currencies` string[]: List of currency codes enabled for this customer.
    - `email` string, email: Email address for the customer.
    - `phoneNumber` string: Phone number for the customer in strict E.164 format.
    - `umaAddress` string, required: Full UMA address (always present in responses, even if system-generated). This is an optional identifier to route payments to the customer.
    - `createdAt` string, date-time: Creation timestamp
    - `updatedAt` string, date-time: Last update timestamp
    - `isDeleted` boolean: Whether the customer is marked as deleted
    - `contactVerification` ContactVerification: Email and/or phone verification state for the customer. This object is **only present when the customer's regulatory jurisdiction requires contact verification** (e.g. EU customers). For customers who have no such requirement, this object is omitted entirely — no action is needed. Each channel is reported independently: only the channels the customer's provider actually requires are present. A provider may require both email and phone, just one of them, or — when the object is absent — neither. Every channel that **is** present must reach `VERIFIED` before the customer can begin KYC. Drive each present channel with `POST /customers/{customerId}/verify-email` and/or `POST /customers/{customerId}/verify-phone` (and their `/confirm` sub-routes).
      - `email` 'PENDING' | 'VERIFIED': Status of an individual contact-verification channel (email or phone). `PENDING` means verification is required but not yet completed; `VERIFIED` means the channel has been confirmed.
      - `phone` 'PENDING' | 'VERIFIED': Status of an individual contact-verification channel (email or phone). `PENDING` means verification is required but not yet completed; `VERIFIED` means the channel has been confirmed.
    - `kycStatus` 'UNVERIFIED' | 'PENDING' | 'APPROVED' | 'REJECTED' | 'HOLD': The current KYC status of a customer. `HOLD` means the customer is placed on hold and may be required to update or provide more information.
    - `fullName` string: Individual's full name
    - `birthDate` string, date: Date of birth in ISO 8601 format (YYYY-MM-DD)
    - `nationality` string: Country code (ISO 3166-1 alpha-2)
    - `address` Address
      - `line1` string, required: Street address line 1
      - `line2` string: Street address line 2
      - `city` string: City
      - `state` string: State/Province/Region
      - `postalCode` string, required: Postal/ZIP code
      - `country` string, required: Country code (ISO 3166-1 alpha-2)
    - `idType` 'SSN' | 'ITIN' | 'EIN' | 'NON_US_TAX_ID': Type of tax identification
    - `identifier` string: The individual's identification number, required to onboard them as a US account holder. Only SSN (format `###-##-####`) and ITIN are currently accepted; other identification types are rejected. Write-only — never returned in customer responses.
    - `countryOfIssuance` string: Country that issued the identification (ISO 3166-1 alpha-2). Optional for an individual account holder: SSN and ITIN are US-issued, so this defaults to `US` and is rejected if set to anything else.
    - `sourceOfFundsCategories` IndividualSourceOfFundsCategory[]: Structured source-of-funds categories (FLOW of funds for this account).
    - `sourceOfFundsOtherDescription` string: Free-form description of the customer's source of funds. Required when `sourceOfFundsCategories` includes `OTHER`; otherwise omitted.
    - `sourceOfWealthCategories` SourceOfWealthCategory[]: Structured source-of-wealth categories (STOCK — origin of accumulated wealth).
    - `sourceOfWealthOtherDescription` string: Free-form description of the customer's source of wealth. Required when `sourceOfWealthCategories` includes `OTHER`; otherwise omitted.
    - `purposeOfAccount` 'CONTRACTOR_PAYOUTS' | 'CREATOR_PAYOUTS' | 'EMPLOYEE_PAYOUTS' | 'MARKETPLACE_SELLER_PAYOUTS' | 'SUPPLIER_PAYMENTS' | 'CROSS_BORDER_B2B' | 'AR_AUTOMATION' | 'AP_AUTOMATION' | 'EMBEDDED_PAYMENTS' | 'PLATFORM_FEE_COLLECTION' | 'P2P_TRANSFERS' | 'CHARITABLE_DONATIONS' | 'OTHER': The intended purpose for using the Grid account
    - `purposeOfAccountOtherDescription` string: Free-form description of the customer's intended purpose for the Grid account. Required when `purposeOfAccount` is `OTHER`; otherwise omitted.
    - `expectedMonthlyTransactionCount` 'COUNT_UNDER_10' | 'COUNT_10_TO_100' | 'COUNT_100_TO_500' | 'COUNT_500_TO_1000' | 'COUNT_OVER_1000': Expected number of transactions per month
    - `expectedMonthlyTransactionVolume` 'VOLUME_UNDER_10K' | 'VOLUME_10K_TO_100K' | 'VOLUME_100K_TO_1M' | 'VOLUME_1M_TO_10M' | 'VOLUME_OVER_10M': Expected total transaction volume per month in USD equivalent
    - `annualIncomeRange` 'UNDER_50K' | 'RANGE_50K_100K' | 'RANGE_100K_250K' | 'RANGE_250K_1M' | 'OVER_1M': Bucketed annual income (USD equivalent). Used for enhanced due diligence on higher-risk profiles.
    - `netWorthRange` 'UNDER_100K' | 'RANGE_100K_500K' | 'RANGE_500K_1M' | 'RANGE_1M_5M' | 'RANGE_5M_25M' | 'OVER_25M': Bucketed total net worth (USD equivalent). Used for enhanced due diligence on higher-risk profiles.
    - `pepStatus` 'NONE' | 'DOMESTIC' | 'FOREIGN' | 'HIO' | 'FAMILY_OR_ASSOCIATE': Political exposure declaration (Politically Exposed Person status). `HIO` = head of an international organization. `FAMILY_OR_ASSOCIATE` covers close family members and known close associates of a PEP.
  - BusinessCustomer
    - `id` string: System-generated unique identifier
    - `platformCustomerId` string, required: Platform-specific customer identifier
    - `customerType` 'BUSINESS', required: Whether the customer is an individual or a business entity
    - `endUserTermsConsent` EndUserTermsConsent: Deprecated; use `agreementConsents` instead, which records acceptance of each agreement separately. Reported only for a customer whose acceptance predates that field, and always as the `LIGHTSPARK_END_USER_TERMS` agreement.
      - `acceptedAt` string, date-time, required: Date and time when the customer accepted the End User Terms.
      - `ipAddress` string, required: IP address of the device the customer used when accepting the terms.
      - `termsVersion` string, required: Version identifier of the accepted Grid End User Terms.
      - `acceptanceMethod` 'CHECKBOX' | 'CLICK_TO_ACCEPT', required: Method the customer used to affirmatively accept an agreement.
    - `agreementConsents` AgreementConsent[]: The customer's recorded agreement acceptances, one entry per accepted type holding that type's most recent acceptance. Omitted when the customer has not accepted any agreement yet.
      - `type` 'LIGHTSPARK_END_USER_TERMS' | 'LIGHTSPARK_E_SIGN_CONSENT' | 'LIGHTSPARK_PRIVACY_POLICY' | 'LEAD_E_SIGN_CONSENT' | 'LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT' | 'LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT' | 'LEAD_PRIVACY_POLICY' | 'LEAD_CARDHOLDER_CONSUMER_AGREEMENT' | 'LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT', required: Identifies which Grid agreement a consent record or document refers to. Values are stable identifiers: a document's hosted URL or version may change, but its type does not. Accepting one agreement never implies acceptance of another, even when two agreements share a hosted page. The cardholder and accountholder agreements differ by customer kind: an `INDIVIDUAL` customer accepts the `_CONSUMER_` variant, and a `BUSINESS` customer accepts the `_COMMERCIAL_` one.
      - `acceptedAt` string, date-time, required: Date and time when the customer accepted this agreement. Must include a timezone offset and must not be in the future.
      - `ipAddress` string, required: IP address of the device the customer used when accepting this agreement.
      - `termsVersion` string, required: Version identifier of the accepted agreement, as returned for this type by the agreement documents endpoint. A version is scoped to its type; a version valid for one agreement is not valid for another.
      - `acceptanceMethod` 'CHECKBOX' | 'CLICK_TO_ACCEPT', required: Method the customer used to affirmatively accept an agreement.
    - `region` string: Country code (ISO 3166-1 alpha-2) representing the customer's regional identity and regulatory jurisdiction.
    - `currencies` string[]: List of currency codes enabled for this customer.
    - `email` string, email: Email address for the customer.
    - `phoneNumber` string: Phone number for the customer in strict E.164 format.
    - `umaAddress` string, required: Full UMA address (always present in responses, even if system-generated). This is an optional identifier to route payments to the customer.
    - `createdAt` string, date-time: Creation timestamp
    - `updatedAt` string, date-time: Last update timestamp
    - `isDeleted` boolean: Whether the customer is marked as deleted
    - `contactVerification` ContactVerification: Email and/or phone verification state for the customer. This object is **only present when the customer's regulatory jurisdiction requires contact verification** (e.g. EU customers). For customers who have no such requirement, this object is omitted entirely — no action is needed. Each channel is reported independently: only the channels the customer's provider actually requires are present. A provider may require both email and phone, just one of them, or — when the object is absent — neither. Every channel that **is** present must reach `VERIFIED` before the customer can begin KYC. Drive each present channel with `POST /customers/{customerId}/verify-email` and/or `POST /customers/{customerId}/verify-phone` (and their `/confirm` sub-routes).
      - `email` 'PENDING' | 'VERIFIED': Status of an individual contact-verification channel (email or phone). `PENDING` means verification is required but not yet completed; `VERIFIED` means the channel has been confirmed.
      - `phone` 'PENDING' | 'VERIFIED': Status of an individual contact-verification channel (email or phone). `PENDING` means verification is required but not yet completed; `VERIFIED` means the channel has been confirmed.
    - `kybStatus` 'UNVERIFIED' | 'PENDING' | 'APPROVED' | 'REJECTED' | 'HOLD': The current KYB status of a business customer. `HOLD` means the customer is placed on hold and may be required to update or provide more information.
    - `address` Address
      - `line1` string, required: Street address line 1
      - `line2` string: Street address line 2
      - `city` string: City
      - `state` string: State/Province/Region
      - `postalCode` string, required: Postal/ZIP code
      - `country` string, required: Country code (ISO 3166-1 alpha-2)
    - `businessInfo` object: Business information returned on a customer. `taxId` and `incorporatedOn` are required on creation only when the customer's currency uses direct customer-owned accounts, so both are optional in responses.
      - `legalName` string, required: Legal name of the business
      - `doingBusinessAs` string: Trade name or DBA name of the business, if different from the legal name
      - `country` string: Country of incorporation or registration (ISO 3166-1 alpha-2)
      - `registrationNumber` string: Business registration number
      - `incorporatedOn` string, date: Date of incorporation in ISO 8601 format (YYYY-MM-DD)
      - `entityType` 'SOLE_PROPRIETORSHIP' | 'PARTNERSHIP' | 'LLC' | 'CORPORATION' | 'S_CORPORATION' | 'NON_PROFIT' | 'PUBLICLY_LISTED_COMPANY' | 'TRUST' | 'PRIVATE_FOUNDATION' | 'CHARITY' | 'OTHER': Legal entity type of the business
      - `taxId` string: Tax identification number
      - `countriesOfOperation` string[]: List of countries where the business operates (ISO 3166-1 alpha-2)
      - `businessType` 'AGRICULTURE_FORESTRY_FISHING_AND_HUNTING' | 'MINING_QUARRYING_AND_OIL_AND_GAS_EXTRACTION' | 'UTILITIES' | 'CONSTRUCTION' | 'MANUFACTURING' | 'WHOLESALE_TRADE' | 'RETAIL_TRADE' | 'TRANSPORTATION_AND_WAREHOUSING' | 'INFORMATION' | 'FINANCE_AND_INSURANCE' | 'REAL_ESTATE_AND_RENTAL_AND_LEASING' | 'PROFESSIONAL_SCIENTIFIC_AND_TECHNICAL_SERVICES' | 'MANAGEMENT_OF_COMPANIES_AND_ENTERPRISES' | 'ADMINISTRATIVE_AND_SUPPORT_AND_WASTE_MANAGEMENT_AND_REMEDIATION_SERVICES' | 'EDUCATIONAL_SERVICES' | 'HEALTH_CARE_AND_SOCIAL_ASSISTANCE' | 'ARTS_ENTERTAINMENT_AND_RECREATION' | 'ACCOMMODATION_AND_FOOD_SERVICES' | 'OTHER_SERVICES' | 'PUBLIC_ADMINISTRATION': The high-level industry category of the business
      - `purposeOfAccount` 'CONTRACTOR_PAYOUTS' | 'CREATOR_PAYOUTS' | 'EMPLOYEE_PAYOUTS' | 'MARKETPLACE_SELLER_PAYOUTS' | 'SUPPLIER_PAYMENTS' | 'CROSS_BORDER_B2B' | 'AR_AUTOMATION' | 'AP_AUTOMATION' | 'EMBEDDED_PAYMENTS' | 'PLATFORM_FEE_COLLECTION' | 'P2P_TRANSFERS' | 'CHARITABLE_DONATIONS' | 'OTHER': The intended purpose for using the Grid account
      - `sourceOfFunds` string: The primary source of funds for the business
      - `expectedMonthlyTransactionCount` 'COUNT_UNDER_10' | 'COUNT_10_TO_100' | 'COUNT_100_TO_500' | 'COUNT_500_TO_1000' | 'COUNT_OVER_1000': Expected number of transactions per month
      - `expectedMonthlyTransactionVolume` 'VOLUME_UNDER_10K' | 'VOLUME_10K_TO_100K' | 'VOLUME_100K_TO_1M' | 'VOLUME_1M_TO_10M' | 'VOLUME_OVER_10M': Expected total transaction volume per month in USD equivalent
      - `expectedRecipientJurisdictions` string[]: List of countries where the business expects to send payments (ISO 3166-1 alpha-2)
      - `naicsCode` string: NAICS code describing the nature of the business (2-6 digits)
      - `sourceOfFundsCategories` SourceOfFundsCategory[]: Structured source-of-funds categories for the business
      - `sourceOfFundsOtherDescription` string: Description of the source of funds when OTHER is selected
      - `purposeOfAccountOtherDescription` string: Description of the account purpose when OTHER is selected
      - `expectedCounterpartyCountries` string[]: List of countries of the business's expected transaction counterparties (ISO 3166-1 alpha-2)
      - `primaryContactFirstName` string: First name of the business's primary contact — a registered director or authorised representative of the business. Required in regions where a named individual is verified against the business during onboarding (e.g. the EU). The customer's `email` and `phoneNumber` are this person's contact details.
      - `primaryContactLastName` string: Last name of the business's primary contact.
    - `beneficialOwners` BeneficialOwner[]
      - `id` string, required: Unique identifier for this beneficial owner
      - `customerId` string, required: The ID of the business customer this beneficial owner is associated with
      - `roles` BeneficialOwnerRole[], required: Roles of this person within the business
      - `ownershipPercentage` integer, required: Percentage of ownership in the business (0-100)
      - `personalInfo` BeneficialOwnerPersonalInfo, required
        - `firstName` string, required: First name of the individual
        - `middleName` string: Middle name of the individual
        - `lastName` string, required: Last name of the individual
        - `birthDate` string, date, required: Date of birth in ISO 8601 format (YYYY-MM-DD)
        - `nationality` string, required: Country of nationality (ISO 3166-1 alpha-2)
        - `email` string, email: Email address of the individual
        - `phoneNumber` string: Phone number in E.164 format
        - `address` Address, required
          - `line1` string, required: Street address line 1
          - `line2` string: Street address line 2
          - `city` string: City
          - `state` string: State/Province/Region
          - `postalCode` string, required: Postal/ZIP code
          - `country` string, required: Country code (ISO 3166-1 alpha-2)
        - `idType` 'SSN' | 'ITIN' | 'EIN' | 'NON_US_TAX_ID', required: Type of tax identification
        - `identifier` string, required: The identification number or value
        - `countryOfIssuance` string: Country that issued the identification (ISO 3166-1 alpha-2)
      - `kycStatus` 'UNVERIFIED' | 'PENDING' | 'APPROVED' | 'REJECTED' | 'HOLD', required: The current KYC status of a customer. `HOLD` means the customer is placed on hold and may be required to update or provide more information.
      - `createdAt` string, date-time, required: When this beneficial owner was created
      - `updatedAt` string, date-time: When this beneficial owner was last updated

## Other responses

- `400`: Invalid or expired code
- `401`: Unauthorized
- `404`: Customer not found
- `409`: The customer's payment provider does not require contact verification, or the phone is already verified.
- `500`: Internal service error

## Changes

> 115 revisions in range; 2 not diffed.

- **2026-10-28** `d996ddfb9d2b`: 2 info
  - added the optional property `details/missingFields` to the response with the `400` status
  - added the optional property `details/refusalReason` to the response with the `400` status
- **2026-10-26** `f11f1e76bdd7`: 1 warning
  - added the new `PURCHASE_CARD_LIMIT_REACHED` enum value to the `code` response property for the response status `409`
- **2026-10-26** `0a6dad5815c7`: 1 warning
  - added the new `INVOICE_ALREADY_USED` enum value to the `code` response property for the response status `409`
- **2026-10-24** `715332dcb111`: 1 warning
  - added the new `EXACT_AMOUNT_UNAVAILABLE` enum value to the `code` response property for the response status `400`
- **2026-10-20** `761d1d030cb5`: 2 warning
  - added the new `AGENT_CARD_EXISTS` enum value to the `code` response property for the response status `409`
  - added the new `CARDHOLDER_AGREEMENT_NOT_ACCEPTED` enum value to the `code` response property for the response status `400`

[Operation history](https://skmtc.dev/lightsparkdev/apis/grid-api/changes/customers/:customerId/verify-phone/confirm/post.md)

---

[API](https://skmtc.dev/lightsparkdev/apis/grid-api.md) - [All operations](https://skmtc.dev/lightsparkdev/apis/grid-api/llms.txt) - [OpenAPI document](https://skmtc.dev/lightsparkdev/apis/grid-api/revisions/7a1db46ec552?raw)
