KYC

Know Your Customer (KYC) verifies that an individual account holder is who they say they are. It's a regulatory and fraud-prevention primitive: collect a legal identity, match it against authoritative sources, confirm with a document and a selfie, and produce a binary outcome you can act on. Frame models KYC as a capability on an account — you request it, Frame runs the checks, and any downstream payment capability that depends on a verified identity activates automatically.

KYC is for individual accounts only. Businesses follow KYB (Know Your Business), which Frame runs against the legal entity while onboarding each owner or controller as a separate individual account in parallel.

When you need KYC

Request the kyc capability when your flow requires a verified identity. The two common cases:

  • Paying funds out to an individual. card_receive and bank_account_receive both depend on completed KYC. Frame won't push money to an unverified person.
  • Running age-restricted flows. age_verification and other compliance capabilities build on top of KYC.

If you request card_receive, bank_account_receive, or creator_shield on an account, Frame includes kyc automatically — you don't have to ask for it separately. Request kyc directly when you need identity verification independent of any payment capability (e.g., for compliance threshold enforcement on your platform).

Buyers paying you through hosted checkout don't need KYC. The card_send capability activates on a payment method alone; verifying every buyer's identity would be excessive friction for the case where you only need to charge their card.

Required information

To complete KYC for an individual account, Frame needs:

FieldWhere it lives on the Account
Legal first nameprofile.individual.name.first_name
Legal last nameprofile.individual.name.last_name
Phone numberprofile.individual.phone
Date of birthprofile.individual.birthdate
Residential addressprofile.individual.address
Last 4 of SSNCollected during the onboarding session and stored encrypted; only ssn_last_four is returned via the API

Anything you have at account-creation time, prefill — Frame won't re-collect it during the hosted flow. Fields you don't have are surfaced in the capability's currently_due array; the onboarding session then collects them through Frame-hosted UI.

The flow

KYC is gated by a hosted onboarding session — Frame owns the UX, you own the redirect points. The shape:

  1. Create the account with kyc in the capabilities array and any identity fields you already have.
  2. Create an onboarding session for the account. Frame returns a URL.
  3. Redirect the account holder to that URL. The hosted flow walks them through:
    • Consenting to the identity verification process.
    • Confirming any additional fields Frame couldn't prefill from your input (last 4 of SSN, address corrections, etc.).
  4. Handle the return. Frame redirects the account holder to your return_url when they finish. The redirect fires when the user clicks through — not when the verification has resolved. Document verification runs asynchronously and can take seconds to minutes.
  5. Confirm activation. Subscribe to the capability.activated (success) or capability.disabled (failure) webhook, or poll the account's kyc capability status until it settles. Don't act on the redirect alone.

KYC resolves from data alone. Frame matches the identity fields against authoritative sources and returns a decision — no document, no selfie. Document capture is a separate step that runs only when the data checks cannot reach a decision.

Walk-through with code: Run KYC.

When KYC asks for a document

Some identities do not resolve from data. A thin credit file, a recent address change, or a name that authoritative sources hold differently all produce an inconclusive result rather than a pass or a fail. Frame does not decline these account holders. It asks them for a government ID instead.

When that happens, Frame requests the idv capability on the account and fires a capability.requested webhook. The kyc capability stays pending — it has not failed, it is waiting on the document.

An onboarding session picks the step up on its own. A session derives its steps from the account's outstanding requirements on every request, so an account holder still in the flow when the step-up fires sees an ID verification step appear. You don't create it, name it, or configure it.

That covers the common case, because KYC usually resolves while the holder is still in the session. Handle the other case explicitly:

  1. Handle the capability.requested webhook. The payload names the account and the idv capability. Treat it as "this account holder has more to do," not as an error.
  2. Check whether their session is still live. Sessions carry an expiry. If the holder is still in an unexpired session, they are already looking at the new step and you need to do nothing.
  3. Create a new onboarding session only if the old one has expired — or if the holder left before the decision landed. Redirect them back to the new URL.
  4. Confirm activation the same way you do for KYC: wait for capability.activated on kyc. A passing document resolves the original KYC check, and the downstream payment capabilities activate behind it.

KYC resolves asynchronously, so the decision can land after the account holder has closed the tab or after the session has expired. That is what the webhook is for — it's your signal to bring them back, whether or not they were still on screen.

Budget for this branch before you go live. An integration that treats every non-active KYC as a failure strands the account holders who only needed to show an ID.

Outcomes

The kyc capability uses the standard capability lifecycle. The states that matter in practice for a KYC flow you've requested:

  • active — Frame matched the identity against authoritative sources, and any document it asked for passed. The account holder is verified. Any payment capabilities that depended on KYC activate automatically.
  • disabled — verification failed. Look at the capability's associated error records for the failure category (document quality, identity mismatch, etc.) where shareable. Your application should surface a remediation path: retry, request manual review, or decline service per your platform's policy.
  • pending — Frame is still waiting on something. Either a back-channel check has not resolved, or the identity did not resolve from data and Frame is waiting on a document. Check whether the account carries an idv capability: if it does, the account holder has an outstanding step, not a stalled check. Stay subscribed to the capability webhook either way.

unrequested and ineligible are also valid states on a capability — see the capabilities concept — but for KYC the common path is pendingactive or pendingdisabled.

Outcomes are not predictive — a disabled KYC for one account holder doesn't say anything about a different one, even with similar fields. KYC is identity verification, not risk scoring.

Re-verification

KYC isn't a one-shot. If an account holder's information changes (legal name change, new address) or your platform's compliance policy mandates periodic refresh, update the profile fields. Frame re-evaluates the kyc capability against the new data automatically. If the update introduces fields Frame can't reconcile against the existing verified record (e.g., a substantially different document), the capability transitions back to pending and a fresh onboarding session collects what's needed.

The previous KYC result isn't "lost" — Frame tracks the verification history on the account. The capability surface reflects the current state.

Scope — what KYC checks

KYC verifies the legal identity claim:

  • The name, SSN last 4, address, and date of birth reconcile against authoritative sources.
  • The identity belongs to a real person, and that person is not deceased.
  • The identity shows no signal of synthetic or stolen construction.

When those checks resolve the identity, KYC is done. When they cannot, the idv capability adds a document layer on top:

  • The document is authentic (not forged, not visibly tampered).
  • The selfie is a live person, not a static image.
  • The selfie face matches the document photo within Frame's matching threshold.

KYC does not check:

  • Whether the person is on a sanctions list (that's separate compliance work, run alongside).
  • Whether the address is currently valid (that's address_verification).
  • Whether the phone is reachable (that's phone_verification).
  • Whether the person is of legal age for a regulated activity (that's age_verification, which builds on KYC).

Treat KYC as the foundation: it verifies identity, and the other compliance capabilities verify specific attributes of that identity.

Platform scope

In V1, Frame's KYC flow is delivered through frame-js (the web SDK) plus a server-side onboarding session you create from your backend. The hosted verification UI loads on os.framepayments.com and walks the account holder through document capture in the browser or mobile browser. Native mobile SDK integration (React Native, iOS, Android) is on the roadmap — if you need KYC inside a native mobile app, talk to Frame support about the current options.

Gotchas

Symptom: the account holder completed the session and was redirected back, but the kyc capability is still pending. Why: Frame's redirect fires when the user clicks through, not when document analysis resolves. Verification can take seconds to minutes. Fix: listen for capability.activated / capability.disabled webhooks; treat the redirect as "they finished entering data," not "verification passed."

Symptom: you requested kyc plus card_receive on a new account and only kyc shows up pending in the response. Why: Frame stages dependent capabilities — card_receive won't be evaluated until kyc activates. The capability still exists on the account, just not surfaced until its prerequisites resolve. Fix: once kyc transitions to active, retrieve the account again and you'll see card_receive listed and being evaluated.

Symptom: the kyc capability sits pending indefinitely, and the account has grown an idv capability you never requested. Why: the identity didn't resolve from data, so Frame requested a government ID. The account holder has an outstanding step and nothing is going to move until they complete it. Fix: handle the capability.requested webhook, create a fresh onboarding session, and redirect the account holder back into it. See When KYC asks for a document.

Symptom: you sent the account holder back to their original onboarding session URL for the step-up and the link no longer works. Why: onboarding sessions expire, and KYC can resolve after the holder has left. The step itself is fine — a live session would have shown it — but the session is gone. Fix: create a new onboarding session for the account and redirect them to that URL.

Symptom: a KYC verification passes for one account holder and fails for a similar-looking one. Why: document quality, lighting, and the matching threshold are all stochastic. KYC is identity-level, not risk-level — small data differences yield different outcomes. Fix: surface a remediation path (re-submit with clearer photos, manual review) rather than treating the failure as final.

Reference

For the full API surface, see POST/v1/accounts and POST/v1/onboarding_sessions.

Frame Assistant

Ask anything about Frame's APIs and products