Capabilities

A capability is a feature you can utilize on an account. "This account can be charged on a card." "This account can receive a bank account payout." "This account holder is identity-verified." Each is a capability with its own status and its own list of outstanding requirements.

You request a capability; Frame provisions its requirements, reports its status and what it still needs (currently_due), and bills for its use; you decide what your platform does with what Frame reports. Some capabilities act at transaction time — geo_compliance blocking a restricted charge is the feature doing its job. A capability's status reports what currently is — it does not carry the play-by-play of individual checks, which live on their own records.

Request only what the relationship needs — a buyer paying you on a hosted checkout only needs card_send; a seller getting a payout needs card_receive or bank_account_receive plus the verifications those depend on.

The capability set

CapabilityWhat it enablesAccount requirements
card_sendThe account's card can be charged (the everyday "accept a payment" case).Individual or business account; an attached card payment method.
card_receiveFrame can push a payout to the account's debit card.Individual or business account with a card payout method, plus completed KYC (individual) or KYB (business).
bank_account_sendThe account's bank account can be debited via ACH.Individual or business account; an attached bank account.
bank_account_receiveFrame can push a payout to the account's bank account.Individual or business account with a verified bank account, plus completed KYC (individual) or KYB (business).
kycThe account holder has completed identity verification.Individual account with name, phone, address, date of birth, last 4 of SSN.
idvThe account holder has confirmed their identity with a government ID and a selfie.Individual account. Frame requests it automatically when KYC cannot resolve from data alone.
kybThe business behind the account has completed Know-Your-Business verification.Business account with its legal entity details.
kyc_prefillKYC data is pre-filled from a verified identity source instead of being re-collected.Individual account with a phone number.
phone_verificationThe phone number on file is verified via SMS or voice.Individual account with a phone number.
age_verificationThe account holder's age has been confirmed against the date of birth.Individual account with verified KYC and DOB.
address_verificationA physical address has been validated.Payment method with a billing address; ACH additionally requires verified KYC.
bank_account_verificationBank account ownership has been verified.Individual or business account; must use a hosted onboarding session.
card_verificationA card has been verified without being charged.Individual or business account with a card payment method.
geo_complianceLocation-based rules have been applied to the account.Account with Frame.js or a mobile SDK initialized.
creator_shieldCreator-focused fraud protection signals are running on the account.Individual account with verified KYC.

A few terms to keep oriented:

  • _send means funds are pulled from the account (you charge the buyer's card). _receive means funds are pushed to the account (you pay out to the seller's bank).
  • The "minimal" capability for a buyer account is card_send. It doesn't require KYC, and it's what hosted checkout requests automatically.
  • KYC, age, address, phone, bank account, and card verifications are independent capabilities — request the ones you need rather than running them all by default.

Lifecycle

The status field on a capability is one of three values — this matches the Capability schema:

  • pending — the capability has been requested but at least one requirement is unmet. Frame is waiting on additional information or on a check to resolve.
  • active — as of Frame's last evaluation, every requirement was satisfied and the capability is usable.
  • disabled — the capability has been switched off deliberately, by you or by Frame acting on a policy decision — and nothing else. disabled_reason names the policy when Frame switched it off; it is null for a disable you initiate, where the reason is your own. A failed check never lands here: verification outcomes live on their own records, and a capability whose check failed stays pending.

Two more values you should not branch on. unrequested is the shape of a capability that has never been requested — it is not part of that account's capability list, so there is nothing to read; it stays in the schema enum for backward compatibility. ineligible is retired and has been withdrawn from the public enum: nothing moves a capability into it, ineligible_reason is deprecated and always null, and a row that still reads ineligible is a historical leftover that nothing will revive.

disabled is reversible. POST/v1/accounts/{account_id}/capabilities/{name}/reactivate returns the capability to pending and fires a capability.reactivated webhook — never straight to active, because the checklist has to re-evaluate first. Only a disabled capability can be reactivated; any other state is rejected with 422 and the code capability_not_disabled.

A capability moves between states automatically as data lands. Attach a card → card_send becomes active. Complete KYC through an onboarding session → kyc becomes active. There is no explicit "activate" call; you supply the inputs, Frame re-evaluates.

Re-evaluation is triggered by those inputs landing, not run on a schedule, and some checks resolve in the background. So status holds the result of the most recent evaluation and can trail the account's live state for a short window after a change — while currently_due is computed when you read it and is always current. If the two disagree, trust currently_due. Rather than polling status after a write, listen for the capability webhooks.

What active means, per capability

One rule governs status everywhere: active means every requirement on the capability's checklist was satisfied as of Frame's last evaluation. What the checklist contains differs by capability, so active answers a different question depending on which one you're reading:

Capabilitiesactive answers
kyc, kyb, idv, age_verification, phone_verification"Is this person or business verified?" — the verification itself is on the checklist.
card_send, card_receive, bank_account_send, bank_account_receive, address_verification, card_verification, bank_account_verification"Is this ready to use?" — provisioning steps like an attached payment method and accepted terms; the receive capabilities also depend on verification.
geo_compliance, kyc_prefill"Is the feature on?" — a minimal checklist; the feature does its work per-transaction or per-flow once enabled.
creator_shield"Verified person, enrolled, monitoring running."

Read the row you care about with its own question in mind — kyc_prefill: active means the prefill accelerator is enabled for the account, not that a prefill succeeded; kyc: active means the person is verified.

currently_due

When a capability is pending, the currently_due array on the capability lists the actionable outstanding requirements — fields the account holder still has to supply.

{
  "name": "kyc",
  "status": "pending",
  "currently_due": ["profile.individual.address", "profile.individual.birthdate"]
}

currently_due is what you'd hand to an onboarding session to collect, or what you'd surface in your own UI. It is computed when you read it, and it lists only work that can still move the capability forward. A pending capability with a populated currently_due is waiting on the account holder.

An empty currently_due on a pending capability means the opposite: there is nothing the account holder can do right now. Read errors[] to find out which case you are in.

  • errors[] is empty — Frame is waiting on a back-channel check: a verification still resolving, a document under review. Listen for capability.activated.
  • errors[] carries a terminal conclusion (code: "verification_rejected") — the outcome cannot change however the account holder retries, so Frame publishes no fields to collect. Do not wait for capability.activated; it is not coming. Decline per your policy.

Never prompt for fields you did not read out of currently_due. A capability whose conclusion is terminal reports an empty list precisely so that a UI driven by it stops asking.

A failed check does not fire a capability event: it is reported on the requirement's verification record (for KYC, on the identity verification and its account.identity_verification.* webhook family) and on the capability's errors[].

errors

status reports what a capability is. errors[] reports the conclusion standing against it — why it is not active.

{
  "name": "kyc",
  "status": "pending",
  "currently_due": [],
  "errors": [
    {
      "object": "capability_error",
      "code": "verification_rejected",
      "message": "Verification was rejected.",
      "requirement_id": "..."
    }
  ]
}

Three properties are worth designing around:

  • It is derived, not stored. Frame computes it when you read the capability, from the unmet obligation's latest conclusion. Satisfy the obligation and the entry disappears on the next read — there is no separate "clear the error" call.
  • Read it as a list, not errors[0]. Today Frame reports the single most binding conclusion — an obligation has one word at a time, and a conclusion Frame reached outranks a prerequisite it is still waiting on — so the array usually holds one entry. Treat that as a convenience, not a contract: iterate it, so a future response that carries more than one entry does not break your integration.
  • The code is provider-neutral. Frame classifies every provider's outcome into its own vocabulary, so the code is stable across a change of verification provider. Vendor reason codes never reach the API.

Most codes name how a verification run concluded, and of those verification_rejected is the only terminal one: no retry changes it. Everything else — a data mismatch, an identity Frame could not locate, a provider error — is recoverable, and the remediation differs per code. See the failure types for the category and remediation of each.

One code is not a conclusion at all. identity_document_required is a hold: nothing failed, a prerequisite is outstanding — Frame is waiting on a government ID. Read it as work still to do, never as a failure to decline on. See when KYC asks for a document.

Capabilities and account status

Capabilities are the gate. An account's status is not derived from them, and branching on it will mislead you.

An account created through the API starts active, and no capability moves it from there. It does not go pending because a capability is pending, and it does not go disabled because its capabilities are disabled. active on an account means "not restricted and not disabled" — it says nothing about whether any particular feature is usable.

What actually decides whether you can transact is the capability: read kyc.status to know whether the holder is verified, card_send.status to know whether their card can be charged. An account can sit at active with every capability still pending.

The two account statuses that do gate are restricted and disabled, both of which Frame sets deliberately. See accounts for the full state model.

Adding capabilities later

Capabilities are not locked at account creation. As an account holder unlocks new features on your platform — graduating from buyer to seller, opting into payouts — request additional capabilities by passing them on an update or by creating a new onboarding session configured for the additions. Each fresh session collects only the deltas, not what's already on file.

Reference

For the full capability set on a live account, see GET/v1/accounts/{account_id}/capabilities.

Frame Assistant

Ask anything about Frame's APIs and products