This guide covers the Customer API side of issuing a card to a user that your program created via the Control API. Every call here uses the user’s bearer token.
The application already exists. When the program calls POST /identity on the Control API, it creates the user and their application. So unlike self-serve onboarding, you do not call POST /v1/applications here — the user signs in to an application that’s already waiting for them.

The flow

Step 1 — Sign in

The user signs in with the email and password the program set when it created them. On first login they’re prompted to change the password and set up 2FA or a passkey. See Authentication. Use the resulting token on every call below. When the application’s currentStep is LEGAL_AGREEMENTS, accept the program’s terms:
POST /v1/applications/{applicationId}/agreements/legal/accept
Acceptance is idempotent. See Accept legal agreements.

Step 3 — Complete KYC

Fetch the KYC form schema, render it, and submit the answers:
GET  /v1/applications/{applicationId}/kyc/schema
POST /v1/applications/{applicationId}/kyc
The exact fields and number of steps depend on the program’s configured schema. See Get the KYC schema and Submit KYC data.

Step 4 — Identity verification (Sumsub)

Get a Sumsub web token and pass it to the Sumsub Web/Mobile SDK for document upload and liveness:
GET /v1/applications/{applicationId}/webtoken/sumsub
<SumsubWebSdk accessToken={token} />
See Get a Sumsub token.

Step 5 — Wait for approval

Poll GET /v1/applications and render the screen for each currentStep. When currentStep is null, onboarding is done. (Your program also gets a webhook on approval.) The full status model is in the Onboarding overview.

Step 6 — Read customerId and accountId

The approved application carries the customerId, and the user’s primary account is created automatically. Read it to get the accountId:
GET /v1/customers/{customerId}/accounts
See List accounts.

Step 7 — Order the card

POST /v1/customers/{customerId}/accounts/{accountId}/cards
{ "nickName": "My Card", "cardName": "<card name from options>" }
See Create a card.

Funding

How the card is funded depends on how the program created the user (prepaidCardCustomer):
  • Managed — the program loads funds from its master account; nothing for your app to do.
  • Default — the user’s account has an assigned IBAN; the user funds the card by transferring to it.
The program-side detail (Control API create + Load/Unload) is on the Management docs.