> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cadanapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Up Worker Wallets

> Create User accounts, complete KYC, and provision Cadana wallets for workers

export const ApiExample = ({method = "GET", path, params, body, reference, tenantKey}) => {
  const baseUrl = "https://api.cadanapay.com";
  const query = params ? "?" + Object.entries(params).map(([k, v]) => `${k}=${v}`).join("&") : "";
  const url = `${baseUrl}${path}${query}`;
  const isPlatformPath = (/^\/(v1\/)?platform(\/|$)/).test(path || "");
  const includeTenantKey = tenantKey === undefined ? !isPlatformPath : tenantKey;
  let curl = `curl -X ${method} '${url}' \\\n  -H 'Authorization: Bearer YOUR_API_KEY'`;
  if (includeTenantKey) {
    curl += ` \\\n  -H 'X-MultiTenantKey: YOUR_BUSINESS_TENANT_KEY'`;
  }
  if (body) {
    const formatted = JSON.stringify(body, null, 2);
    curl += ` \\\n  -H 'Content-Type: application/json' \\\n  -d '${formatted}'`;
  }
  return <div>
      <CodeBlock language="bash" filename="bash" wrap>
        {curl}
      </CodeBlock>
      {reference && <div style={{
    marginTop: "-0.5rem",
    marginBottom: "1rem"
  }}>
          <a href={reference} style={{
    fontSize: "0.875rem"
  }}>
            Try it in the playground →
          </a>
        </div>}
    </div>;
};

A **User** is a Cadana account for an existing [Person](/workforce/onboarding-workers). Creating a User provisions a Global Wallet that the worker can use to receive payments, access self-service features, and manage their funds.

***

## Prerequisites

<Steps>
  <Step title="API key from Dashboard">
    Get your API key from the [Cadana Dashboard](https://app.cadanapay.com). See [Authentication](/authentication) for details.
  </Step>

  <Step title="Existing Person record">
    The worker must already be onboarded as a Person. See [Onboard Workers](/workforce/onboarding-workers).
  </Step>
</Steps>

***

## Step 1: Create a User

Invite the worker to Cadana by creating a User linked to their Person record. This provisions a wallet in their compensation currency.

<ApiExample method="POST" path="/v1/users/invite" body={{ personId: "8ef9a712-cdae-4110-b1ea-9ba95abbee6e" }} reference="/api-reference/workforce/users/invite" />

**Response:**

```json theme={null}
{
  "userId": "3a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
```

By default, the worker receives a welcome email with instructions to set up their password and log into the Cadana app.

### Get the onboarding link

Pass `returnLink: true` to receive the worker's unique onboarding URL in the response. This is useful when you want to send it through a custom channel.

<ApiExample method="POST" path="/v1/users/invite" body={{ personId: "8ef9a712-cdae-4110-b1ea-9ba95abbee6e", returnLink: true }} reference="/api-reference/workforce/users/invite" />

**Response:**

```json theme={null}
{
  "userId": "3a1b2c3d-4e5f-6789-abcd-ef0123456789",
  "inviteLink": "https://app.cadanapay.com/login?auth=..."
}
```

<Tip>
  The `inviteLink` is also returned when `suppressWelcomeEmail` is `true`, even without setting `returnLink`.
</Tip>

<Info>
  **Using custom authentication?** Pass `"suppressWelcomeEmail": true` to skip the welcome email and password setup. You'll handle login via your own SSO flow instead. See [Custom Authentication](/white-label/custom-authentication).
</Info>

***

## Step 2: KYC Verification

Before the wallet can be fully functional, the worker must complete identity verification (KYC). There are two ways to do this:

### Option A: Worker self-service

The worker completes KYC themselves through the Cadana app or your [white-label UI](/white-label/overview) after logging in.

### Option B: Submit KYC via API

You can submit KYC on behalf of the worker directly through the API. This is useful when you've already collected identity documents during your own onboarding flow.

<ApiExample method="POST" path="/v1/users/3a1b2c3d-4e5f-6789-abcd-ef0123456789/kyc" body={{ firstName: "John", lastName: "Doe", dob: "1990-01-15", nationality: "NG", address: { line1: "12 Marina Road", city: "Lagos", postalCode: "101001", state: "Lagos", countryCode: "NG" }, idDetails: { type: "passport", number: "123456789", issuedBy: "Nigeria Immigration Service", issuedCountryCode: "NG", issuedDate: "2020-01-15", expirationDate: "2030-01-15", frontFileId: "1d3f870c-bc91-4636-a0d4-8e54bccf7d64", selfieFileId: "9c2e517b-4d38-4f21-8a6e-3b1f0c9d2e45" } }} reference="/api-reference/workforce/users/submit-kyc" />

Returns `204` on success — the submission is sent for verification.

<Tip>
  Upload identity documents first using the [file upload flow](/reference/working-with-files), then pass the returned `fileId` values in `idDetails`. `frontFileId` and `selfieFileId` are required; add `backFileId` for two-sided documents. See [KYC Verification](/platform/kyc-verification#identity-document) for the full field reference.
</Tip>

### Check KYC status

Poll the KYC endpoint or listen for the `user.kyc.updated` [webhook event](/reference/events) to track verification progress:

<ApiExample method="GET" path="/v1/users/3a1b2c3d-4e5f-6789-abcd-ef0123456789/kyc" reference="/api-reference/workforce/users/get-kyc" />

**Response:**

```json theme={null}
{
  "idDetails": {
    "country": "NG",
    "type": "Passport"
  },
  "identity": "approved",
  "address": "approved",
  "firstName": "John",
  "lastName": "Doe"
}
```

<Tip>
  **Sandbox behavior:** Submit with the sentinel values `idDetails.number: "auto-approve"` and `address.line2: "auto-approve"` to have verification approved automatically. Submissions without a sentinel are not auto-approved. See [KYC Testing](/reference/sandbox#kyc-testing).
</Tip>

For details on what's required, see [KYC Verification](/platform/kyc-verification).

### Tax Forms (U.S. Businesses)

Contractors hired by U.S. businesses are also required to complete and sign a tax form (W-9, W-8BEN, or W-8BEN-E) as part of wallet onboarding. The contractor completes this through the Cadana app alongside KYC — no API integration needed.

You can retrieve and download completed forms via the API. See [Tax Forms](/wallets/tax-forms).

***

## Wallet Payment Method

When you create a User for a Person, the platform automatically sets wallet as the preferred payment method. No additional API call is needed — payroll disbursements will go to the worker's Cadana wallet by default.

You can verify this by checking the Person's payment info:

<ApiExample method="GET" path="/v1/persons/8ef9a712-cdae-4110-b1ea-9ba95abbee6e/paymentInfo" reference="/api-reference/workforce/persons/get-payment-information" />

<Note>
  If you need to switch the worker to a different payment method (bank transfer, mobile money, etc.), use [`PUT /v1/persons/{personId}/paymentInfo`](/api-reference/workforce/persons/update-payment-information). See [Onboard Workers](/workforce/onboarding-workers#direct-payment-methods-alternative) for details.
</Note>

***

## Check Wallet Balance

Retrieve a worker's wallet balances. A worker can hold balances in multiple currencies.

<ApiExample method="GET" path="/v1/users/3a1b2c3d-4e5f-6789-abcd-ef0123456789/wallets" reference="/api-reference/wallets/balances/get-user-wallets-balances" />

**Response:**

```json theme={null}
{
  "data": [
    {
      "id": "517075a2-17db-469f-9481-eb8347cb920c",
      "currency": "USD",
      "balance": 703448,
      "available": 703448,
      "processing": 0
    }
  ],
  "node": {
    "previous": null,
    "next": null
  }
}
```

| Field        | Description                                                 |
| :----------- | :---------------------------------------------------------- |
| `currency`   | Wallet currency                                             |
| `balance`    | Total balance in lowest denomination (cents)                |
| `available`  | Amount available for withdrawal                             |
| `processing` | Amount currently being processed (e.g. pending withdrawals) |

***

## Managing Users

| Operation  | Endpoint                                                       | Description                      |
| :--------- | :------------------------------------------------------------- | :------------------------------- |
| List users | [`GET /v1/users`](/api-reference/workforce/users/list)         | Filter by `personId` or `email`  |
| Get user   | [`GET /v1/users/{userId}`](/api-reference/workforce/users/get) | Retrieve user details and status |

See the [Workforce API Reference](/api-reference/workforce) for full request and response schemas.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Pay Workers via Payroll" icon="rocket" href="/workforce/pay-workers-via-payroll">
    Pay workers into their wallets
  </Card>

  <Card title="KYC Verification" icon="shield-check" href="/platform/kyc-verification">
    How identity verification works
  </Card>

  <Card title="Tax Forms" icon="file-invoice" href="/wallets/tax-forms">
    W-9 and W-8 forms for U.S. business contractors
  </Card>

  <Card title="Custom Authentication" icon="key" href="/white-label/custom-authentication">
    Integrate your own SSO for worker login
  </Card>

  <Card title="Wallets API Reference" icon="code" href="/api-reference/wallets">
    Full wallet endpoint documentation
  </Card>
</CardGroup>
