Onboarding API Overview

What you can do with the Onboarding API

The Onboarding APIs are your entry point to the Bakkt platform. It handles individual user and corporate entity creation, authentication, identity verification, and merchant configuration.

Explore core features and endpoints

User Management

Create and manage individual user accounts with comprehensive profile data.

  • Create User POST /user Create a new user account with basic information and digital assets addresses
  • Update User PATCH /user Update user profile details, addresses, and preferences
  • Get User GET /user Retrieve complete user profile including status and verification level

Learn more →

Corporate Management

Create and manage corporate entities with KYB verification support.

Learn more →

Authentication

Authenticate users via SIWE (Sign In With Ethereum) or Email OTP.

Learn more →

Verification KYC/KYB

Integrated identity verification with Sumsub for compliance.

Learn more →

Quick Start

In three steps you'll create a user, authenticate them, and kick off identity verification — enough to take a brand-new account from KYC_NEEDED to a Sumsub session in under five minutes.

Before you begin

  • A sandbox API key from your merchant dashboard
  • A test email address you can receive OTPs at
  • Base URL: https://sandbox.api.bakkt.com

All examples below run against sandbox. Swap the host for https://api.bakkt.com when moving to production.

Step 1: Create a user

curl -X POST https://sandbox.api.bakkt.com/user \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Alice",
    "last_name": "Smith",
    "email": "[email protected]",
    "country": "GB",
    "accepted_terms_of_service_hash": "base64_hash_here"
  }'

Response:

{
  "user_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "KYC_NEEDED"
}

Save user_uuid — you'll need it for the next step.

Step 2: Authenticate

Trigger an OTP delivery:

curl -X POST https://sandbox.api.bakkt.com/auth/login \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_uuid": "550e8400-e29b-41d4-a716-446655440000" }'

Then submit the 6-digit code Alice received by email:

curl -X POST https://sandbox.api.bakkt.com/auth/otp/ \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "one_time_password": "123456"
  }'

Response:

{
  "bakkt_session_id": "eyJhbGciOi...",
  "user_uuid": "550e8400-e29b-41d4-a716-446655440000"
}

Pass bakkt_session_id as the bakkt-session-id header on every authenticated request from here on.

Step 3: Start KYC

curl -X POST https://sandbox.api.bakkt.com/user/kyc/applicant \
  -H "Authorization: YOUR_API_KEY" \
  -H "bakkt-session-id: YOUR_SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "address": {
      "address_line_1": "123 Main Street",
      "post_code": "SW1A 1AA",
      "city": "London",
      "country": "GB"
    },
    "date_of_birth": "1990-05-15",
    "source_of_funds": "SALARY"
  }'

A 204 No Content means the application was created. Fetch a Sumsub token to launch the verification UI:

curl https://sandbox.api.bakkt.com/user/kyc/applicant/token \
  -H "Authorization: YOUR_API_KEY" \
  -H "bakkt-session-id: YOUR_SESSION_ID"

Response:

{ "token": "_act-sbx-..." }

Hand that token to the Sumsub Web SDK and Alice can complete document upload. Subscribe to the KYC webhook (or poll GET /user) to be notified when her status moves to FULL_USER.

End-to-end example

The same flow against a hypothetical SDK wrapper, including KYC status polling:

// 1. Create user
const user = await bakkt.createUser({
  first_name: 'Alice',
  last_name: 'Smith',
  email: '[email protected]',
  country: 'GB',
  accepted_terms_of_service_hash: 'base64_hash_here'
});

// 2. Authenticate
await bakkt.triggerOTP(user.user_uuid);
const session = await bakkt.submitOTP(user.user_uuid, '123456');

// 3. Initiate KYC
await bakkt.createKYCApplication(session.session_id);
const sumsubToken = await bakkt.getKYCToken(session.session_id);

// 4. User completes KYC in your UI
// (Using Sumsub Web SDK with the token)

// 5. Monitor KYC status via webhook or polling
const kycStatus = await bakkt.getKYCStatus(session.session_id);

// 6. Once approved, user can transact
if (kycStatus.status === 'FULL_USER') {
  // User ready for payments!
}

Next steps

  • User management — user lifecycle, country-specific requirements, and best practices.
  • Corporate management — create corporate entities, link users, and manage business profiles.
  • Authentication — SIWE, Email OTP, and session handling in depth.
  • KYC & KYB — verification flows, statuses, and how to react to common rejection reasons.
  • Webhooks — subscribe to status changes instead of polling.
  • Full API reference — every endpoint, schema, and error code.