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

# KYC — Mexico (MXN)

> KYC requirements for enabling MXN rails for Mexican users. Identity review is handled by Etherfuse using the documents already uploaded through the standard KYC wizard.

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

Mexican users get an MXN smart wallet and move money over SPEI/CLABE through the [MXN on/offramp](/api-reference/mxn-ramp). Identity review is handled by **Etherfuse**, reusing the documents the user already uploaded through the standard KYC wizard — there is no separate Mexican document flow. A CLABE is provisioned and the bank account is registered automatically during activation; there is no separate bank-account call.

***

## How it works (the flow)

1. **Run the standard KYC wizard** — `PATCH /kyc` with personal info, the Mexican address, and `identificationNumbers` containing both the **CURP** and **RFC**; then upload the ID document (`/kyc/documents/identification`), **proof of address** (`/kyc/documents/proof-of-address`), and selfie (`/kyc/documents/biometric`). Documents must be JPEG or PNG.
2. **`POST /latam/mx/kyc/activate`** — Submits the profile to Etherfuse for review. The body carries the Mexican paternal/maternal surnames (they are not part of the KYC profile). A Fintoc CLABE is provisioned and the bank account is registered automatically in the background.
3. **`GET /latam/mx/kyc/launch/agreements`** — Send the user to Etherfuse's agreements-signing page. **Signing is required for approval** — without it the review never completes.
4. **`GET /latam/mx/kyc/status`** — Poll until `approved`.
5. **`GET /latam/mx/kyc/launch/idv`** — Only when status returns `bank_verification_required`: send the user through bank identity verification (facial scan + ID match).

<Info>
  A Mexican user who also wants a USD account follows the [Rest of world](/api-reference/kyc-row-requirements) flow in addition to this one — the two are independent activations over the same KYC profile.
</Info>

***

## Activation

```http theme={null}
POST /v1/users/{userId}/latam/mx/kyc/activate
```

| Field                 |                                                 |
| --------------------- | ----------------------------------------------- |
| `paternalLastName`    | required — e.g. `"Pérez"`                       |
| `maternalLastName`    | required — e.g. `"García"`                      |
| `birthCountryIsoCode` | optional — ISO 3166-1 alpha-2; defaults to `MX` |

Returns the review status and which documents were found on the profile:

```json theme={null}
{
  "status": "pending",
  "uploaded": {
    "selfie": true,
    "document": true
  }
}
```

If `selfie` or `document` come back `false`, upload the missing file via the standard KYC document endpoints and activate again. Activation also fails with a `400` if the CURP or RFC identification numbers are missing from the profile.

***

## Agreements signing (required for approval)

```http theme={null}
GET /v1/users/{userId}/latam/mx/kyc/launch/agreements
```

Returns a browser form-POST payload that sends the user to Etherfuse's agreements-signing page:

```json theme={null}
{
  "url": "https://…/auth/launch",
  "method": "POST",
  "fields": {
    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion": "<signed user JWT>",
    "target": "/agreements"
  },
  "html": "<form …>…</form>",
  "expiresAt": "2026-06-02T12:05:00.000Z"
}
```

<Warning>
  **The `assertion` JWT expires roughly 5 minutes after you fetch it.** Fetch this payload at the moment you are ready to send the user to the page — never at the start of a session, and never cached in your own store. An expired launch fails at Etherfuse rather than at BMONI, so you get no error from this API to tell you what went wrong.

  Read `expiresAt` and treat it as a hard deadline. If the user abandons the page, or you are still on your own screens when it passes, call this endpoint again for a fresh payload. There is no cost or limit to re-calling it.
</Warning>

Load `html` into a WebView or browser as-is (it auto-submits), or build the form-POST yourself from `url` + `fields`.

***

## Status values

```http theme={null}
GET /v1/users/{userId}/latam/mx/kyc/status
```

| `status`                     |                                                                                                                                    |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `proposed`                   | Review submitted, not yet decided                                                                                                  |
| `bank_verification_required` | Etherfuse reports the registered bank account non-compliant — launch [bank identity verification](#bank-identity-verification-idv) |
| `approved`                   | Etherfuse KYC approved **and** the bank account is compliant (checked live) — gate showing the MXN deposit account on this         |
| `approved_chain_deploying`   | Approved; on-chain setup still finishing                                                                                           |
| `rejected`                   | Review rejected                                                                                                                    |

***

## Bank identity verification (IDV)

```http theme={null}
GET /v1/users/{userId}/latam/mx/kyc/launch/idv
```

Only needed when `kyc/status` returns `bank_verification_required`. Returns the same launch-payload shape as agreements signing; the user completes a facial scan and ID match to verify the registered bank account. Re-call for a fresh JWT (\~5 min expiry).

***

## Next step

Once status is `approved`, move money with [Mexico — MXN on/offramp](/api-reference/mxn-ramp) — depositing MXN to the user's CLABE onramps automatically, and offramps are a quote followed by an order.
