Onboarding Flow

Kulipa API — Customer Onboarding Guide

Docs: https://kulipa.readme.io/reference/getting-started
API Base URL: https://api.kulipa.xyz/v1
Dashboard: https://dashboard.kulipa.xyz


1. Overview

Kulipa provides a card-issuing API that lets you create and manage virtual and physical Mastercard/Visa debit cards for your users, backed by stablecoin in users' wallets. Integration involves four main pillars:

  • Users — create and manage end-user identities
  • KYC — verify user identity (via Persona SDK or shared/imported KYC)
  • Wallets — stablecoin-funded wallets linked to each user
  • Cards — virtual or physical cards issued against wallet balances

2. Environments

EnvironmentPurposeAPI Keys
SandboxIntegration & testingSandbox-specific keys
ProductionLive users & real fundsProduction keys (shown once — store securely)

⚠️

Sandbox and production are fully isolated — objects in one are not accessible in the other.

⚠️ Production API keys are shown only once. If lost, roll or delete and regenerate.


3. Step-by-Step Integration

Step 1 — Receive Your Sandbox API Key (API docs — Authentication)

Your onboarding engineer will provide sandbox API keys. Share a list of email addresses that need access.

Step 2 — Create a User (API docs — Users)

Every cardholder starts as a User object:

POST /v1/users
{
  "email": "[email protected]",
  "firstName": "Jane",
  "lastName": "Doe",
  "countryOfResidence": "GB"
}

→ Returns a usr-xxxx ID. Store this.

If a user already exists with the same phone, you will receive a 409 duplicate_user_error. Do not retry creation — retrieve the existing user instead.

Step 3 — Initiate KYC (API docs — KYC)

Kulipa uses Persona for identity verification. You have two options:

Option A — Kulipa-hosted KYC (standard)
Initiate a KYC session and redirect your user to the Persona widget:

PUT /v1/kycs
{ "userId": "usr-xxxx", "type": "full" }

The user completes document verification in-app. KYC links expire after 14 days. Use the Resume KYC endpoint for expired sessions — note that only expired KYCs can be resumed, not pending ones.

Option B — Shared / Imported KYC
If your platform already performs equivalent KYC (per Kulipa's standards), you may import pre-verified data:

POST /v1/kycs

This requires a signed addendum to your contract. Contact your account manager to enable it.

KYC statuses: pendingapproved / declined / expired
You will receive webhook events on every status change.

For physical card shipping KYC:
Run a shipping-type KYC before creating a physical card. Wait for the completed event before calling card creation, to ensure the shipping address is set correctly.

Step 4 — Fund the Wallet (API docs — Wallets)

Each approved user gets a stablecoin wallet. Top it up by sending stablecoin on-chain to the wallet's deposit address. Deposits reflect automatically once confirmed on-chain.

If a deposit does not reflect, check for a create_wallet_error — it may indicate the wallet was not provisioned. Contact support with the usr-xxxx ID.

Step 5 — Issue a Card (API docs — Cards)

Once KYC is approved and the wallet has funds, issue a card:

# Virtual card
POST /v1/cards
{ "type": "virtual", "userId": "usr-xxxx" }

# Physical card
POST /v1/cards
{ "type": "physical", "userId": "usr-xxxx", "tier": "standard", "deliveryType": "ship_to_user" }

Note: address.state must be ≤ 12 characters. Truncate or abbreviate longer state/region names before sending.

Card statuses: inactiveactivefrozen / revoked

Step 6 — Set Up a Webhook Listener (API docs — Webhooks)

Build and deploy a server that accepts POST requests from Kulipa. Register it:

POST /v1/webhook-subscriptions
{ "url": "https://your-server.com/kulipa-webhook" }

Key events to handle:

EventDescription
kyc.approvedUser is verified — safe to issue a card
kyc.declinedUser failed verification
kyc.expiredKYC link expired — trigger Resume KYC
cardAuthorization.approvedPayment authorized — withhold funds
cardAuthorization.rejectedPayment declined
cardAuthorization.clearedSettlement confirmed
card.shippedPhysical card dispatched
balance.updatedWallet balance changed

Verify webhook signatures using the public key endpoint.

Step 7 — Handle 3DS (API docs — 3DS)

For 3D Secure authentication requests, implement decision endpoints:

POST /v1/3ds/accept   # approve the auth
POST /v1/3ds/reject   # decline the auth

Repeated 3DS failures on a card (e.g. recurring subscriptions) may indicate a misconfiguration. Check your webhook handler is correctly responding in time.

Step 8 — Simulate Transactions (Sandbox Only) (API docs — Transactions (Simulations))

Use simulation endpoints to test your integration end-to-end before going live:

  • POST /v1/simulate/authorization
  • POST /v1/simulate/authorization/clearing
  • POST /v1/simulate/authorization/reversal
  • POST /v1/simulate/authorization/refund
  • POST /v1/simulate/3ds

4. Apple Pay & Google Pay

To enable wallet tokenization:

  1. Generate tokenization data: POST /v1/cards/{cardId}/apple-pay-tokenization or /google-pay-tokenization
  2. Send the response payload to Apple/Google for provisioning
  3. After user authenticates, confirm via: POST /v1/cards/{cardId}/activate-tokenization

For Google Pay: you'll need access to the Google Pay & Wallet Console. Ask your Kulipa contact to send you an invite.
For Apple Pay: coordinate Apple's entitlements (Team ID, App ID, Bundle ID) with Kulipa — this requires our involvement.

Cards issued in some regions may not support Apple Pay. Google Pay (tokenization only) is more broadly available. Contact your account manager for current regional support.


5. Go-Live Checklist

  • Sandbox integration complete and tested
  • Webhook listener deployed and verified
  • KYC flow (Persona SDK or Shared KYC) end-to-end tested
  • Physical card shipping address flow tested (if applicable)
  • Apple/Google Pay tested (if applicable)
  • Production API keys received and stored securely
  • Support process set up (Linear board access, on-call contacts)
  • Compliance review complete (KYB form, KYC policy submitted for imported KYCs)

6. Key API Reference Links