> ## 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.

# Multi-Tenant Setup

> Set up a multi-tenant integration with Cadana's Platform API

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>;
};

This guide walks through the full lifecycle of a business on your platform:

```mermaid theme={null}
flowchart LR
    A["1. Create business"] --> B["2. Complete KYB"]
    B --> C["3. Fund the account"]
    C --> D["4. Onboard workers & run payroll"]
```

Each business you create gets its own `tenantKey`. Every subsequent call for that business — KYB, funding, workers, payroll — carries that key in the `X-MultiTenantKey` header.

## Prerequisites

<Steps>
  <Step title="Platform access enabled">
    Contact your account manager to enable Platform API access.
  </Step>

  <Step title="Platform API token">
    Generate a Platform token from your [Platform Dashboard](https://platform.cadanapay.com) under Settings > Developers.
  </Step>
</Steps>

<Warning>
  Platform API access requires special enablement. Standard org tokens cannot create businesses or use the `X-MultiTenantKey` header.
</Warning>

***

## Create a Business

Create a business on your platform. The response includes the `tenantKey` you'll need for all subsequent calls to this business.

<ApiExample method="POST" path="/v1/platform/businesses" body={{ businessName: "Acme Corporation", adminFirstName: "Jane", adminLastName: "Founder", adminEmail: "jane@example.com", country: "US", idempotencyKey: "a1b2c3d4-e5f6-7890-abcd-ef1234567890", address: { line1: "123 Main Street", city: "San Francisco", state: "CA", postalCode: "94105", countryCode: "US" } }} reference="/api-reference/workforce/platform/create" />

**Response:**

```json theme={null}
{
  "businessId": "7dd569f9-bd54-4fbb-a5c2-f0aaadc68adf",
  "tenantKey": "cad95193904"
}
```

<Note>
  Store the `tenantKey` in your database mapped to the business. You'll need it for every API call that targets this business.
</Note>

<Note>
  Creating a business sends a welcome email to `adminEmail`. Pass `suppressWelcomeEmail: true` if you onboard the business yourself and don't want Cadana to email your customer.
</Note>

***

### Add Legal Entities (Optional)

For global payroll, you can create legal entities representing subsidiaries or branches in different jurisdictions:

<ApiExample method="POST" path="/v1/entities" body={{ legalName: "Acme UK Ltd", country: "GB", currency: "GBP" }} reference="/api-reference/workforce/entities/create" />

See [Entity Management](/workforce/entity-management) for full details.

***

## Use the Tenant Key

For all business-specific operations, include the `X-MultiTenantKey` header with the tenant key.

<Warning>
  If you omit the header, the request does **not** fail — it silently runs against your platform's own main business. Always set `X-MultiTenantKey` when you intend to operate on a sub-business.
</Warning>

```bash theme={null}
curl -X GET 'https://api.cadanapay.com/v1/users' \
  -H 'Authorization: Bearer PLATFORM_TOKEN' \
  -H 'X-MultiTenantKey: cad95193904'
```

All business-scoped endpoints (persons, users, payrolls, contracts, invoices, KYB) accept the `X-MultiTenantKey` header. Platform-level endpoints (`/v1/platform/*`) like creating and listing businesses do not take it. See the [API Reference](/api-reference/) for all available endpoints.

***

## List Your Businesses

Retrieve all businesses on your platform. No tenant key needed.

<ApiExample method="GET" path="/v1/platform/businesses" reference="/api-reference/workforce/platform/list" />

**Response:**

```json theme={null}
{
  "data": [
    {
      "id": "7dd569f9-bd54-4fbb-a5c2-f0aaadc68adf",
      "name": "Acme Corporation",
      "shortName": "Acme",
      "status": "ACTIVE",
      "tenantKey": "cad95193904",
      "country": "US",
      "requiresKYB": true,
      "admin": { "name": "Jane Founder", "email": "jane@example.com" },
      "address": { "line1": "123 Main Street", "line2": "", "city": "San Francisco", "postalCode": "94105", "state": "CA", "countryCode": "US" },
      "createdTimestamp": 1765359752,
      "idempotencyKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "Beta Inc",
      "shortName": "Beta",
      "status": "pending_verification",
      "tenantKey": "cad12345678",
      "country": "NG",
      "requiresKYB": true,
      "admin": { "name": "Bola Adeyemi", "email": "bola@example.com" },
      "address": { "line1": "12 Marina Road", "line2": "", "city": "Lagos", "postalCode": "101241", "state": "LA", "countryCode": "NG" },
      "createdTimestamp": 1765359801,
      "idempotencyKey": "b6ae5da9-6342-4a58-bd50-8564d68d3f7e"
    }
  ],
  "node": {
    "previous": null,
    "next": "eyJwbGF0Zm9ybVByZWZpeCI6..."
  }
}
```

A business starts in `pending_verification` and moves to `ACTIVE` once KYB is approved. Use the `node.next` cursor with the `next` query parameter to page through results.

***

## Complete KYB

A new business starts in `pending_verification` and can't process payments until Know Your Business (KYB) verification is approved. There are two ways to submit it:

* **Hosted form** — [generate a KYB link](/platform/kyb-requirements#hosted-kyb-form) and send it to the business owner. They complete a branded multi-step form; links expire after 6 hours and progress is saved between visits.
* **API submission** — collect the data in your own UI and [submit it directly](/platform/kyb-requirements#api-submission). You can submit everything at once or incrementally.

See [KYB Requirements](/platform/kyb-requirements) for required fields, document uploads, and the nuances of updating a submission (in short: PATCH updates existing fields and principals, re-POST to add principals).

### Track Verification

Poll [`GET /v1/businesses/{businessId}/kyb`](/platform/kyb-requirements#check-kyb-status) — `requirements.currentlyDue` lists anything still outstanding — or subscribe to the [`business.kyb.reviewed` and `business.kyb.completed`](/platform/kyb-requirements#webhook-events) webhooks. When KYB reaches `complete`, the business status flips to `ACTIVE`.

***

## Fund the Business

Once the business is `ACTIVE`, retrieve the bank details to send funds to, and check balances:

<ApiExample method="GET" path="/v1/businesses/{businessId}/funding-details" reference="/api-reference/workforce/businesses/get-funding-details" />

<ApiExample method="GET" path="/v1/businesses/{businessId}/balances" reference="/api-reference/workforce/businesses/get-balances" />

See [Fund Your Account](/fund-your-account) for all funding methods (bank transfer, ACH direct debit, crypto) and the sandbox deposit endpoint for instant test funds.

***

## Webhooks

Platform integrations receive webhooks for all businesses. The payload includes a `tenantKey` field to identify which business the event relates to.

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "eventType": "business.kyb.completed",
  "version": "1.0",
  "timestamp": 1765359752,
  "data": {
    "businessId": "7dd569f9-bd54-4fbb-a5c2-f0aaadc68adf",
    "businessName": "Acme Corporation",
    "status": "complete",
    "tenantKey": "cad95193904"
  }
}
```

See [Events](/reference/events) for all event types and [Webhooks](/reference/webhooks) to configure your endpoint.

***

## Sandbox Testing

In sandbox mode, businesses are created instantly and KYB can be auto-approved using test values (e.g., tax ID `000-CAD-AUTO-APPROVE`). All API calls work the same as production.

Use `https://dev-api.cadanapay.com` as the base URL. See [Sandbox & Testing](/reference/sandbox#kyb-testing) for all test values and simulated scenarios.

***

## Troubleshooting

| Error                                         | Cause                                                                                     | Solution                                                  |
| :-------------------------------------------- | :---------------------------------------------------------------------------------------- | :-------------------------------------------------------- |
| Request affects the wrong business (no error) | Missing `X-MultiTenantKey` header — the request ran against your platform's main business | Add the header with the correct tenant key                |
| `401 Unauthorized`                            | Invalid or expired token                                                                  | Verify your Platform token is valid                       |
| `403 Forbidden`                               | Tenant key doesn't belong to your platform                                                | Verify the tenant key matches a business you created      |
| `400 unauthorized access`                     | The `businessId` in the path doesn't belong to the business in `X-MultiTenantKey`         | Use the `businessId` and `tenantKey` of the same business |
| `400 Platform access required`                | Account not enabled for platform access                                                   | Contact your account manager                              |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="KYB Requirements" icon="shield-check" href="/platform/kyb-requirements">
    Business verification requirements
  </Card>

  <Card title="Fund Your Account" icon="building-columns" href="/fund-your-account">
    Fund business accounts before running payroll
  </Card>

  <Card title="Onboard Workers" icon="user-plus" href="/workforce/onboarding-workers">
    Create Person and User records for each business
  </Card>

  <Card title="Pay Workers via Payroll" icon="money-check-dollar" href="/workforce/pay-workers-via-payroll">
    Run payroll for a business
  </Card>

  <Card title="Transaction Reconciliation" icon="file-invoice-dollar" href="/platform/transaction-reconciliation">
    Reconcile transactions across businesses
  </Card>

  <Card title="Workforce API Reference" icon="code" href="/api-reference/workforce">
    Full API documentation
  </Card>
</CardGroup>
