Skip to main content
Grid verifies individual customers with KYC and business customers with KYB. Which applies is decided by customerType, and the result lands on kycStatus for individuals and kybStatus for businesses. Regulated platforms run verification through their own compliance systems and create customers directly with POST /customers. Unregulated platforms have Grid verify, using either of the two paths below.

Your options

Both paths cover KYC and KYB, produce the same status transitions, and emit the same webhooks. You can mix them — supply what you already hold through the API, then let the hosted flow collect the rest. Create the customer, then call POST /customers/{customerId}/kyc-link. There’s no dedicated KYB link endpoint — this one serves both types, and customerType selects which flow the provider runs.
Send the customer to kycUrl, or pass token to the provider’s SDK to embed the flow in your own UI. The field is named kycUrl for both customer types; for a BUSINESS customer it opens the KYB flow, where the applicant confirms the company details, uploads the formation and ownership documents, and declares the control person and every beneficial owner holding 25% or more.
When Grid runs KYB for a business customer, the following information and documents are collected before onboarding completes. Use this list to plan what to gather from the business — provide it via POST /customers, POST /beneficial-owners, and POST /documents (or through the hosted flow).

Business identifying information

  • Entity full legal name
  • Doing Business As (DBA) name, if applicable
  • Physical address — the principal place of business, local office, or other physical location of the entity opening the account
  • Countries of operation
  • Identification number — U.S. taxpayer identification number, or, for a foreign business without one, alternative government-issued documentation certifying the existence of the business

Ownership and control structure

Collected for:
  • One control person — a single individual with significant responsibility to control, manage, or direct the legal entity, and
  • All beneficial owners — every individual who owns 25% or more of the legal entity, directly or indirectly.
For every such individual, provide:
  • Full name
  • Date of birth
  • Address
  • Identification number, by residency:
    • U.S. persons — Social Security Number (SSN) or Individual Taxpayer Identification Number (ITIN)
    • Non-U.S. persons — one or more of: ITIN, passport number with country of issuance, alien identification card number, or another government-issued document evidencing nationality or residence and bearing a photograph or similar safeguard

Required documents

  • Company formation and existence documents. For example:
    • Certificate of incorporation
    • Articles of association
  • Proof of ownership and control structure. For example:
    • Corporate organization and ownership chart
    • Shareholder agreements
    • Operating agreements
    • Register of members
    • Certification of controlling person and beneficial owners
  • Proof of address, dated within the last 3 months. For example:
    • Utility bill
    • Bank statement
    • Lease agreement
    • Official correspondence
  • Tax ID or equivalent identifying-number documents
  • For non-U.S. beneficial owners — passport plus one additional government-issued ID. For example:
    • National ID
  • Links are single-use and expire at expiresAt. Each call mints a fresh one; earlier links aren’t invalidated. redirectUri is optional and must be https://.
  • Generating a link doesn’t change the customer’s status — that happens when they submit.
  • A 409 means contact verification is incomplete. When the customer carries a contactVerification object, every channel it lists must reach VERIFIED first, via POST /customers/{customerId}/verify-email / verify-phone and their /confirm sub-routes. When the object is absent, nothing is required.
  • Business information you supply via POST /customers and PATCH /customers/{customerId} is prefilled into the flow, so send as much as you have before generating the link.
Reaching your redirectUri means the customer finished the flow, not that they were approved. Wait for the decision.

Direct API

Submit the data yourself: POST /customers, then POST /beneficial-owners for business customers, POST /documents for identity and company documents, and finally POST /verifications. If anything is missing, verificationStatus comes back as RESOLVE_ERRORS with one errors entry per problem — fix them and resubmit. For the full walkthrough, see Configuring customers.

Creating a business customer

Either path starts here. POST /customers with customerType: BUSINESS requires: Everything else is optional to the schema, but three groups matter in practice:
  • Contact channelsemail and/or phoneNumber, plus businessInfo.primaryContactFirstName and primaryContactLastName, are required in regions that verify a named representative before verification begins (for example the EU).
  • Currency-driven fieldsGET /config returns supportedCurrencies, each with a providerRequiredCustomerFields list. Anything listed for a currency the business will use must be supplied.
  • Everything the review needsaddress, registrationNumber, entityType, countriesOfOperation, businessType, purposeOfAccount, sourceOfFunds, and the expected-activity fields aren’t enforced at creation. Whatever you omit, the applicant is asked for in the hosted flow.
Individual customers need customerType: INDIVIDUAL; fullName must contain both a given and a family name.

Status transitions

kycStatus and kybStatus share the same values and the same path: UNVERIFIEDPENDINGAPPROVED / REJECTED. While the status is PENDING, let the customer finish account setup but block funding and money movement. GET /verifications?customerId=... gives the finer-grained verificationStatus (RESOLVE_ERRORS, IN_PROGRESS, PENDING_MANUAL_REVIEW, APPROVED, REJECTED, READY_FOR_VERIFICATION) and the errors array. That detail drives the direct API path; in the hosted flow the customer resolves it inside the flow, so integrate against kycStatus / kybStatus.

Webhooks

The KYB_* events fire only for customerType: BUSINESS. data is the full customer resource, identical to GET /customers/{customerId}:
Verify X-Grid-Signature against the raw request body and deduplicate on the webhook id. The VERIFICATION.* events carry the verification-level detail if you want it. To poll instead, read the status off GET /customers/{customerId}.

Sandbox

Business customers are always created with kybStatus: UNVERIFIED. The last 3 characters of businessInfo.registrationNumber decide what happens when the business is verified — whether you submit with POST /verifications or send the business through a hosted KYB link:
A registration number that doesn’t end in 001, 002, or 003 is auto-approved on the spot. The hosted flow then has nothing left to verify, so it asks for no documents and no beneficial owners — which looks exactly like a broken KYB flow but isn’t. Always use a 003 suffix when you want to exercise document and UBO collection.
Once a business customer is approved or rejected, further POST /verifications calls return 400. For individual customers and beneficial owners, the equivalent suffixes live on fullName and on each owner’s last name — see Sandbox testing.