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

# Integration flow (no mobile app)

> The flow for partners who have no app of their own — employees onboard through the BMONI app via an invite link, while the partner integrates over the API alone, sending invites (with KYC) and reading each employee's VBA.

<div className="bmoni-spine">
  <span>Lifecycle</span>
  <a data-stage="1" href="/lifecycle#1-create-the-user">User</a>
  <a data-stage="2" href="/lifecycle#2-provision-the-smart-wallet">Wallet</a>
  <a data-stage="3" href="/lifecycle#3-verify-identity-kyc">KYC</a>
  <a data-stage="4" href="/lifecycle#4-activate-the-rail">Rail</a>
  <a data-stage="5" href="/lifecycle#5-fund-the-wallet">Fund</a>
  <a data-stage="6" href="/lifecycle#6-move-money">Move money</a>
</div>

Some partners have no mobile app of their own. **Their employees still use the BMONI app** — the partner simply lends it. "No mobile app" describes the *partner*, not the employee.

That makes the partner's integration small and entirely server-side. The partner never builds an app, never generates keys, never signs anything, and never collects KYC documents from the employee in a browser. The partner does exactly two things over the API:

1. **Invite each employee** — one call that also carries the KYC data the employer already holds.
2. **Read each employee's VBA** (and watch webhooks) once they've onboarded — to show it on the partner's own dashboard.

Everything between those two points happens inside the BMONI app, and is already wired there.

<Info>
  The employer-held KYC travels in the invite, so the employee does **not** re-enter their identity data. At most they take a selfie in-app (liveness can't be employer-supplied). No employee-side forms, no web wallet provisioning.
</Info>

***

## Prerequisites

* A partner **API key** — passed as `x-api-key: <key>` on every request.
* The **proxy base URL** — origin only, no trailing `/v1`.
* A **webhook endpoint** registered with BMONI to receive `employee.linked` and `onboarding.completed`.

***

## End-to-end flow

```mermaid theme={null}
flowchart TD
    A[Partner: POST /v1/partners/employees/invite<br/>name + email + employer-held KYC] --> B[Employee receives email<br/>QR + deep link]
    B --> C{BMONI app installed?}
    C -- no --> D[Deep link → App Store / Play Store<br/>install, then reopen link]
    C -- yes --> E[App opens with the invite context]
    D --> E
    E --> F[Employee creates a BMONI account]
    F --> G[App consumes the deep link<br/>→ shows Link your employer modal]
    G --> H[Employee confirms via work-email OTP<br/>→ employer KYC submitted automatically]
    H --> I[Webhook → partner: employee.linked<br/>carries bmoniUserId]
    I --> J[Employee picks a USD or MXN wallet in-app<br/>→ selfie only, if the provider needs one]
    J --> K[VBA provisioned<br/>→ webhook: onboarding.completed]
    K --> L["Partner: GET /v1/users/{bmoniUserId}/vba/usd<br/>→ show the VBA on the partner dashboard"]
```

<Note>
  The invite call is also the **refresh** call — re-inviting the same email reissues the same deep link. There is no separate link-generation endpoint.
</Note>

***

## Sequence

```mermaid theme={null}
sequenceDiagram
    participant Partner as Partner backend
    participant Proxy as BMONI API
    participant App as BMONI app
    participant Emp as Employee

    Partner->>Proxy: POST /partners/employees/invite (name, email, kyc)
    Proxy-->>Partner: { sent, inviteUrl }
    Proxy->>Emp: Email — QR + deep link
    Emp->>App: Tap link → install if needed → create account
    App->>App: Consume deep link → Link employer modal
    Emp->>App: Confirm via work-email OTP
    App->>Proxy: Verify linkage
    Proxy->>Proxy: Submit employer-held KYC on link
    Proxy-->>Partner: Webhook employee.linked (bmoniUserId)
    Emp->>App: Pick USD / MXN wallet (selfie if required)
    Proxy->>Proxy: Provision VBA
    Proxy-->>Partner: Webhook onboarding.completed
    Partner->>Proxy: GET /users/{bmoniUserId}/vba/usd
    Proxy-->>Partner: VBA account details
```

***

## Step-by-step (partner side)

<Steps>
  <Step title="Invite the employee — with KYC">
    One call sends the co-branded email (QR + deep link) and carries the KYC the employer already holds.

    ```http theme={null}
    POST /v1/partners/employees/invite
    x-api-key: <partner key>
    {
      "name": "Chiamaka Okafor",
      "email": "chiamaka.okafor@allora.mx",
      "kyc": {
        "profile": {
          "personalInfo": { "firstName": "Chiamaka", "lastName": "Okafor", "dateOfBirth": "1990-01-15", "nationality": "MX" },
          "address": { "streetLine1": "Av. Insurgentes Sur 123", "city": "Mexico City", "state": "CDMX", "postalCode": "03100", "countryCode": "MEX" },
          "employment": { "employmentStatus": "employed", "employerName": "Allora HR" },
          "sourceOfFunds": "salary",
          "identificationNumbers": [{ "type": "curp", "number": "OKAC900115MDFXYZ01", "issuingCountryCode": "MEX" }]
        }
      }
    }
    ```

    Returns `{ sent, inviteUrl, error? }`. `kyc.profile` is the same shape as `PATCH /v1/users/{userId}/kyc`; it's submitted to the employee's profile the moment they link. Document *images* and the selfie are handled in-app after linking — they're never part of this payload.
  </Step>

  <Step title="The employee onboards in the BMONI app">
    Not your code — this is the app doing its job. The employee taps the deep link, installs the app if needed, creates a BMONI account, and the app consumes the invite context to show a **Link your employer** modal. They confirm with a work-email OTP; the employer-held KYC is submitted automatically. The only thing the employee may do themselves is a selfie, if the verification provider requires liveness.
  </Step>

  <Step title="Receive employee.linked and store the bmoniUserId">
    ```json theme={null}
    // webhook: employee.linked
    {
      "invitationId": "…",
      "bmoniUserId": "…",
      "companyEmail": "chiamaka.okafor@allora.mx",
      "partnerName": "Allora HR",
      "linkedAt": "2026-01-15T10:00:00Z",
      "kycSubmitted": true
    }
    ```

    `bmoniUserId` is the key for every subsequent read.
  </Step>

  <Step title="Read the VBA for your dashboard">
    The employee picks a USD or MXN wallet in-app; BMONI provisions the VBA and emits `onboarding.completed`. Read it back with the `bmoniUserId`:

    | Currency | Endpoint                                                                                                                   |
    | -------- | -------------------------------------------------------------------------------------------------------------------------- |
    | USD      | `GET /v1/users/{bmoniUserId}/vba/usd` — rich status + account (accountNumber, routingNumber, bankName, SWIFT)              |
    | Any      | `GET /v1/users/{bmoniUserId}/bank-accounts/deposit-accounts/{currency}` — the provisioned deposit account (e.g. MXN CLABE) |

    USD status progresses `none → provisioning → pending → active`; the `account` object is populated once `active`.
  </Step>
</Steps>

***

## Webhooks the partner receives

| Event                                          | Meaning                                                 |
| ---------------------------------------------- | ------------------------------------------------------- |
| `employee.linked`                              | Employee linked to the employer; carries `bmoniUserId`. |
| `onboarding.completed`                         | KYC approved / VBA provisioned for a currency.          |
| `onboarding.failed`                            | Onboarding could not complete.                          |
| `kyc.action_required`                          | Something (often a selfie) is needed from the employee. |
| `employee.deposit.*` / `employee.withdrawal.*` | Money movement on a linked employee's wallet.           |

***

## What the partner does **not** do

* **No app.** Employees use the BMONI app; the partner ships nothing to a device.
* **No signing, no keys, no wallet provisioning.** Wallet creation and its on-device owner-proof signing happen entirely inside the app. The partner has no browser or backend signing step.
* **No employee-entered KYC.** The employer's data rides in the invite; the employee re-enters nothing (a selfie is the only possible employee action).

***

## Reference implementation

The `bmoni-partner-web-demo` app shows the partner side end-to-end: paste an API key, browse an employee roster, send invites (`POST /v1/partners/employees/invite`) with per-row refresh, and surface each linked employee's VBA from the read endpoints above. It is a partner dashboard — it never provisions wallets or signs.
