Skip to main content

Identity (KYC / KYB)

A verification session verifies a person (KYC — a tenant member) or your business (KYB — the tenant itself). The human completes the vendor workflow on their phone: the API mints a one-time SafeBank handoff URL, your terminal or app renders it as a QR code, and the phone lands in the provider's hosted flow. SafeBank normalizes every provider status — no vendor names or vendor statuses ever appear in the API.

A successful session issues a durable credential (PERSON_IDENTITY / BUSINESS_IDENTITY). Payment eligibility evaluates current credential state at decision time — credentials expire, can be revoked, and are superseded by re-verification.

Session lifecycle (normalized statuses):

CREATED → ACTION_REQUIRED → IN_PROGRESS → PROCESSING ─┬─▶ VERIFIED
▲ │ ├─▶ REJECTED
└── ADDITIONAL_INFORMATION_REQUIRED ◀┤
└─▶ PENDING_REVIEW ─▶ VERIFIED / REJECTED
CANCELED / EXPIRED / ERROR are terminal from any live state.

PENDING_REVIEW means a human reviewer has the case — it is not a rejection, and the API never claims VERIFIED before the provider decision lands.

Key endpoints

MethodPathScopePurpose
POST/v1/verification-sessionsidentity:writeStart a KYC (memberId required) or KYB session
GET/v1/verification-sessionsidentity:readList sessions (filter by subject)
GET/v1/verification-sessions/{id}identity:readSession status + requirements
POST/v1/verification-sessions/{id}/handoffidentity:writeMint the one-time QR handoff URL (~10 min TTL, single use)
POST/v1/verification-sessions/{id}/cancelidentity:writeCancel a live session
POST/v1/verification-sessions/{id}/simulateidentity:writeSandbox only (TEST key + mock provider): advance one step
GET/v1/credentialsidentity:readList issued credentials
GET/v1/credentials/{id}identity:readGet a credential

The handoff QR encodes only a short-lived SafeBank URL — no personal data, no provider secrets. It is single-use: the first scan consumes it, and a replayed link is rejected with 410.

CLI

# Verify a person (cross-device: scan the QR with their phone)
sb kyc start --member mem_123 --qr --wait

# Verify your business
sb kyb start --qr --wait

# Check back later — Ctrl-C never cancels the session
sb kyc status vfy_abc --wait
sb kyc list
sb kyc credentials

# Sandbox: walk the mock provider one step per call
sb kyc simulate vfy_abc

--wait polls the SafeBank API (never the vendor) and exits after a terminal status; --json emits a single parseable document with the handoff URL in the payload and no QR bytes.

SDK

const session = await sb.verifications.create({ kind: 'KYC', memberId })
const handoff = await sb.verifications.createHandoff(session.id)
// render handoff.url as a QR code…
const final = await sb.waitForVerification(session.id, { timeoutMs: 15 * 60_000 })
if (final.status === 'VERIFIED') {
const credential = await sb.credentials.get(final.credentialId!)
}

Sandbox scenarios

The sandbox provider is deterministic: the subject's legal name steers the scenario, and sessions only move when you call simulate.

Legal name containsPath
(anything else)happy path → VERIFIED
reviewparks at PENDING_REVIEW, then VERIFIED
docsdetours through ADDITIONAL_INFORMATION_REQUIRED
rejectends REJECTED
errorends ERROR

Payout destinations

Once KYB-verified, a business can register where it wants to be paid — e.g. USDT on TRON. Addresses are stored verbatim (base58check networks are case-sensitive); ownership starts DECLARED, and only a VERIFIED destination can become the default payout preference. Verifying issues a DESTINATION_OWNERSHIP credential. (Ownership proof is sandbox-only until the production proof method ships — the API refuses to pretend otherwise.)

MethodPathScopePurpose
POST/v1/payout-destinationsidentity:writeSave a destination (requires active KYB)
GET/v1/payout-destinationsidentity:readList destinations
POST/v1/payout-destinations/{id}/verifyidentity:writeVerify ownership (sandbox)
POST/v1/payout-destinations/{id}/set-defaultidentity:writeDefault payout preference
sb destinations add --network tron --asset USDT TR7NHqje…
sb destinations verify dst_abc
sb destinations set-default dst_abc

See also

  • Authenticationidentity:* scopes; agent keys can never hold identity:write
  • Payments — credential-gated payment eligibility (rolling out)