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

# Registrar y verificar negocios

> Cómo funciona de punta a punta el registro de negocios y la verificación KYB: qué necesitas tener listo, la secuencia de llamadas y cómo seguir una solicitud hasta la decisión.

## Descripción general

Fluz KYB (Know Your Business) permite que tu plataforma incorpore un negocio a los rieles de Fluz desde tu propia UI. En un conjunto pequeño de operaciones:

1. Resuelves la categoría y subcategoría bajo la cual opera la entidad,
2. Envías el registro de la entidad legal — razón social, estructura, ID fiscal, estado de constitución, domicilio legal y uso previsto de la cuenta — junto con el listado de beneficiarios finales,
3. Completas la verificación de identidad de los propietarios que la requieran, y
4. Sigues el resultado del **caso KYB** hasta su aprobación o rechazo.

El envío en sí es una sola mutación, [registerBusiness](/business-registration). Devuelve un `accountId` de inmediato con un `kybStatus` de `SUBMITTED`.

<Note>
  **El registro es validación, no aprobación.** Una respuesta `success` confirma que el payload pasó la validación y que se abrió un caso KYB. **No** significa que el negocio esté aprobado. Diseña tu integración para que espere un estado aprobado antes de intentar fondear la cuenta o emitir tarjetas.
</Note>

### Lo que habilita una cuenta de negocio

Una vez aprobado KYB, la cuenta de negocio se puede usar para el lado comercial de la plataforma:

* Cuentas de gasto de negocio y saldos
* Tarjetas virtuales comerciales, incluida la emisión masiva
* Usuarios autorizados y controles de gasto a nivel de tarjeta
* Flujos de aprobación para tarjetas, transferencias y reembolsos
* Reportes de transacciones a nivel negocio y anotación de gastos

### Cuándo usar estos endpoints

Usa este flujo cuando quieras recopilar los datos de la entidad y de propiedad en tu propia UI en lugar de enviar a los usuarios a una experiencia alojada por Fluz. Si prefieres que Fluz aloje la recopilación y carga de documentos, habla con tu account manager sobre la opción de incorporación basada en widget.

***

## Flujo de KYB

### Paso a paso

<Steps>
  <Step title="Step 0 — Cumplir los prerrequisitos">
    Nada de esto es parte del flujo, pero todo debe ser cierto antes de llamar a `registerBusiness`. Cada fila enlaza al detalle más abajo. Ver [prerrequisitos](#prerequisitos)
  </Step>

  <Step title="Resolver la categoría y subcategoría del negocio">
    Llama a [getBusinessCategories](/business-categories) y permite que el usuario elija una categoría y una de las subcategorías de esa categoría.
  </Step>

  <Step title="Subir un documento de firmante autorizado, si corresponde">
    Requerido solo cuando el solicitante posee menos del 25% del negocio **y** no es la persona de control. Sube el documento primero y luego pasa la URL devuelta en `authorizedSignerDocumentUrl`. Ver [Enviar documentos del negocio](/submit-business-documents).
  </Step>

  <Step title="Enviar la mutación registerBusiness">
    Envía el registro completo de la entidad, las certificaciones de propiedad y a todos los propietarios en una sola llamada. Los errores de validación se devuelven dentro del payload — ver [Detalles de la respuesta](/business-registration#response-details).
  </Step>

  <Step title="Verificar a los propietarios restantes">
    Lee [getBusiness](/business-status) para ver la verificación esperada y el progreso actual de cada propietario. Para propietarios en la ruta de documentos, genera un enlace con [requestOwnerDocumentVerificationLink](/owner-verification-link) y envíaselo. Los propietarios invitados reciben un email de Fluz y se verifican ellos mismos.
  </Step>

  <Step title="Esperar la decisión de KYB y luego aprovisionar">
    La solicitud comienza en revisión. Muestra ese estado a tu usuario en lugar de dar a entender que ya está activo. Una vez que el estado cambie a `APPROVED`, crea cuentas de gasto y emite tarjetas.
  </Step>
</Steps>

### Secuencia de punta a punta

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant App as Your Application
    participant API as Fluz GraphQL API
    participant Files as Fluz File Upload (REST)
    participant KYB as Fluz Compliance / KYB
    participant Owner as Business Owner

    Note over App,API: Step 0 — the applicant is already a verified Fluz user
    App->>API: query getBusinessCategories
    API-->>App: businessCategoryId + businessSubCategoryId values

    opt Applicant is an authorized signer
        App->>Files: Upload authorization document
        Files-->>App: document URL
    end

    Note over App,API: Step 1 — submit the business
    App->>API: mutation registerBusiness(input)
    alt Validation fails
        API-->>App: success false, with error code and message
        App->>App: Correct the field and resubmit
    else Validation passes
        API-->>App: accountId plus kybStatus SUBMITTED
        API->>KYB: Open KYB case
    end

    Note over App,Owner: Step 2 — owners verify identity
    opt Owner must verify by document
        App->>API: requestOwnerDocumentVerificationLink
        API-->>App: verificationLink
        App->>Owner: Forward the link
        Owner->>KYB: Completes verification
    end

    Note over KYB,App: Step 3 — asynchronous review
    KYB->>KYB: Entity, tax ID, address, and owner checks
    KYB-->>API: Decision (or request for more documentation)
    App->>API: KYB_STATUS_UPDATE webhook, or query getBusiness
    API-->>App: Updated KYB status and owner roster

    Note over App,API: Step 4 — go live
    App->>API: Create spend accounts and issue cards
```

***

## Prerequisitos

| Prerrequisito                                                                                                  | Si falta    |
| -------------------------------------------------------------------------------------------------------------- | ----------- |
| Tu aplicación solicita el [`REGISTER_BUSINESS` permission scope](#application-permission-scopes)               | `AUTH-0031` |
| El solicitante ha [autorizado tu aplicación](#applicant-authorization) para los scopes de negocio que solicita | `AUTH-0008` |
| El solicitante ya está [verificado por CIP](#the-applicant-must-already-be-identity-verified)                  | `ARG-0001`  |
| El solicitante [no tiene ya una solicitud de KYB en curso](#one-open-application-per-user)                     | `BS-0007`   |
| Posees [un Bearer token del tipo de cuenta que cada operación requiere](#access-tokens)                        | `AUTH-0002` |
| Se subió un documento de firmante autorizado, si el solicitante es un firmante autorizado                      | `ARG-0001`  |
| La dirección legal del negocio es real y verificable                                                           | `BS-0002`   |

### Application permission scopes

Selecciona **`REGISTER_BUSINESS`** en los permission scopes de tu aplicación en el dashboard de Fluz. Todas las operaciones de KYB lo requieren, y un token solo puede portar scopes que tu aplicación esté configurada para solicitar. Ver [Application Scopes](/fluz-dashboard/application-scopes).

Suscribirse al webhook [`KYB_STATUS_UPDATE`](#tracking-an-application) requiere el mismo scope.

### Applicant authorization

El solicitante debe haber completado la autorización OAuth para tu aplicación, y esa autorización debe cubrir cada scope de negocio que tu aplicación solicite. Si más tarde agregas un scope, los usuarios existentes deben volver a autorizar antes de poder registrar un negocio; de lo contrario, el registro falla con `AUTH-0008`.

### The applicant must already be cip-verified

El Bearer token identifica al **solicitante**: el usuario que envía la solicitud. Exactamente un propietario en el listado debe coincidir con el usuario del token por **email** (no sensible a mayúsculas/minúsculas) o **número de teléfono**, y ese propietario no puede tener `isInvited: true`.

KYB verifica el negocio y a los *otros* propietarios. No verifica al solicitante, por lo que el solicitante debe alcanzar un estado verificado de antemano. El valor `isUsPerson` que envíes para esa persona decide qué verificación aplica:

| Applicant `isUsPerson` | Estado requerido antes del registro                               |
| ---------------------- | ----------------------------------------------------------------- |
| `true`                 | Una verificación SSN (CIP) exitosa ya registrada para ese usuario |
| `false`                | Una verificación por Documento exitosa                            |

La verificación de identidad ocurre fuera de la superficie de KYB, con el scope `VERIFY_KYC`, usando `verifyUserInformation`, `verifyUserPrefillInformation` o `requestDocumentVerificationLink`. Ver [identity verification (KYC)](/docs/user-kyc-verification). Si la persona aún no tiene una cuenta Fluz, crea una con [registerUser](/user-registration) primero.

### One open application per user

Un usuario no puede iniciar un nuevo registro mientras haya una solicitud existente aún abierta — eso devuelve `BS-0007`.

<Warning>
  No hay clave de idempotencia ni API para cancelar una solicitud en curso. Una solicitud rechazada no deja nada y puede reenviarse, pero una **exitosa** bloquea al usuario para volver a registrarse hasta que se resuelva. Valida antes de enviar y contacta a tu account manager con el `accountId` si un caso parece estancado.
</Warning>

### Access tokens

Cada operación requiere un Bearer token de un tipo de cuenta específico:

| Operación                                                        | Tipo de cuenta del token | Scope requerido     |
| ---------------------------------------------------------------- | ------------------------ | ------------------- |
| [getBusinessCategories](/business-categories)                    | `CONSUMER`               | `REGISTER_BUSINESS` |
| [registerBusiness](/business-registration)                       | `CONSUMER`               | `REGISTER_BUSINESS` |
| [getBusiness](/business-status)                                  | `BUSINESS`               | `REGISTER_BUSINESS` |
| [requestOwnerDocumentVerificationLink](/owner-verification-link) | `BUSINESS`               | `REGISTER_BUSINESS` |

<Note>
  Genera Bearer tokens con `generateUserAccessToken` — ver la sección de Authentication del API reference.
</Note>

***

## Ciclo de vida del estado KYB

```mermaid theme={null}
stateDiagram-v2
    [*] --> SUBMITTED: registerBusiness returns accountId
    SUBMITTED --> PENDING: Case under review
    PENDING --> PENDING: Owners still verifying, or more documentation requested
    PENDING --> APPROVED: Entity and ownership checks cleared
    PENDING --> DECLINED: Checks not cleared
    APPROVED --> [*]: Business can transact
    DECLINED --> [*]: New submission required
```

| Estado      | Qué significa                                                                                                                 | Qué debe hacer tu app                                                                             |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `SUBMITTED` | Devuelto solo por `registerBusiness`. El envío fue aceptado y se abrió un caso KYB.                                           | Almacena el `accountId`. Muestra un estado de “en revisión”.                                      |
| `PENDING`   | Reportado por `getBusiness`. El caso está en revisión, esperando resultados de screening o a que un propietario se verifique. | Sigue monitoreando. No intentes fondear la cuenta ni emitir tarjetas.                             |
| `APPROVED`  | KYB aprobado. La cuenta de negocio es usable.                                                                                 | Aprovisiona cuentas de gasto, emite tarjetas, habilita tu UI de negocio.                          |
| `DECLINED`  | KYB no aprobó.                                                                                                                | Muestra un mensaje neutral y dirige al usuario a soporte. No reintentes el envío automáticamente. |

<Note>
  `SUBMITTED` solo lo devuelve `registerBusiness`. [getBusiness](/business-status) reporta un estado de tres valores, y el estado inmediatamente después del registro se muestra como `PENDING` allí — ambos describen el mismo momento con vocabulario diferente.
</Note>

***

## Seguimiento de una solicitud

Dos formas de seguir una solicitud hasta su estado final. Usa la que se ajuste a tu infraestructura; muchas integraciones usan el webhook por latencia y una lectura ocasional para conciliación.

<Tabs>
  <Tab title="Webhook">
    Suscríbete al evento **`KYB_STATUS_UPDATE`** en el dashboard de Fluz: registra tu URL de callback y selecciona el evento. Tu aplicación necesita el scope `REGISTER_BUSINESS` para suscribirse.

    Fluz hace `POST` a tu endpoint cuando cambia el estado KYB de un negocio.

    ```json theme={null}
    {
      "accountId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "previousStatus": "PENDING",
      "newStatus": "APPROVED",
      "externalReferenceId": "your-partner-user-id-123"
    }
    ```

    | Campo                 | Tipo     | Descripción                                                                                    |
    | --------------------- | -------- | ---------------------------------------------------------------------------------------------- |
    | `accountId`           | `UUID`   | La cuenta de negocio cuyo estado cambió — el mismo `accountId` que devolvió `registerBusiness` |
    | `previousStatus`      | `String` | Estado antes del cambio: `PENDING`, `APPROVED` o `DECLINED`                                    |
    | `newStatus`           | `String` | Estado después del cambio: `PENDING`, `APPROVED` o `DECLINED`                                  |
    | `externalReferenceId` | `String` | Tu propia referencia, cuando la proporcionaste al registrar. Omitido en caso contrario         |

    Dos cosas a manejar:

    * **Trata la entrega como al menos-una-vez.** Haz tu handler idempotente, con llave en `accountId` más `newStatus`.
    * **Puedes recibir eventos donde `previousStatus` es igual a `newStatus`.** El caso cambió entre estados internos que se exponen como el mismo estado público. Trátalos como no-ops.

    <Note>
      El payload lleva solo el estado del negocio — no incluye el listado de propietarios. Llama a [getBusiness](/business-status) cuando necesites el progreso por propietario.
    </Note>
  </Tab>

  <Tab title="Lectura directa de estado">
    Llama a [getBusiness](/business-status) con un token de cuenta de negocio. Devuelve el mismo `kybStatus` más el listado actual de propietarios, lo que lo convierte en la única forma de ver si un propietario individual aún necesita verificarse.

    ```graphql theme={null}
    query GetBusiness {
      getBusiness {
        accountId
        kybStatus
        owners {
          id
          name
          verificationType
          status
        }
      }
    }
    ```

    Léele cuando el usuario regrese a tu pantalla de onboarding de negocio, y en un programa de fondo de baja frecuencia — por hora, no por carga de página. Continúa hasta que `kybStatus` sea final **y** cada propietario reporte `READY`.
  </Tab>
</Tabs>

<Info>
  Las revisiones normalmente se resuelven dentro de uno a dos días hábiles, pero pueden demorar más cuando se solicita documentación adicional o un propietario no ha completado su verificación de identidad. Si un caso parece estancado, contacta a tu account manager con el `accountId` en lugar de reenviar — un segundo envío será bloqueado por `BS-0007`.
</Info>

***

## Identificación de negocios con `externalReferenceId`

Fluz identifica un negocio por su `accountId`, un UUID generado al registrarse. `externalReferenceId` es un identificador opcional que **tú** suministras en su lugar, para que puedas trabajar con Fluz usando el ID que tu propio sistema ya usa para ese cliente.

Pásalo una vez, en [registerBusiness](/business-registration):

```json theme={null}
{ "externalReferenceId": "your-partner-user-id-123" }
```

Se almacena en la cuenta de negocio y te da tres cosas:

* **Generación de tokens sin almacenar IDs de Fluz.** Genera un access token de cuenta de negocio por referencia en lugar de por `userId` y `accountId`.
* **Correlación de webhooks.** La referencia regresa en cada evento [`KYB_STATUS_UPDATE`](#tracking-an-application), para que puedas asociar un evento a tu propio registro sin una tabla de correspondencias.

Es opcional. Si lo omites, todo funciona — solo que tendrás que almacenar el `accountId` tú mismo, lo cual deberías hacer de todos modos.

### Reglas

| Escenario                                                      | Resultado                                                                                                                     |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Omitido                                                        | La cuenta de negocio se crea sin referencia externa                                                                           |
| Provisto, no usado aún                                         | La referencia se almacena en la nueva cuenta de negocio                                                                       |
| Provisto, ya en la propia cuenta de consumidor del solicitante | La referencia se mueve de la cuenta de consumidor a la nueva cuenta de negocio, por lo que desde entonces resuelve al negocio |
| Provisto, ya en otro negocio                                   | El registro falla con `AUTH-0008`. El negocio existente conserva la referencia                                                |

<Warning>
  **Usa un valor único por negocio.** Una referencia solo puede apuntar a una cuenta de negocio, por lo que reutilizar un valor entre dos negocios hace fallar el segundo registro. Derívala de tu propia clave primaria en lugar de algo reutilizable como un email.
</Warning>

<Note>
  Hay dos referencias en juego y es fácil confundirlas. La referencia **que ya lleva tu access token** se usa para localizar la autorización existente del solicitante. La referencia **en el input de `registerBusiness`** es la que se escribe en la nueva cuenta de negocio. Cumplen propósitos diferentes.
</Note>

***

## Páginas relacionadas

<CardGroup cols={2}>
  <Card title="Registrar un negocio" icon="building" href="/business-registration">
    La mutación `registerBusiness`: referencia completa de parámetros, reglas de propiedad y códigos de error.
  </Card>

  <Card title="Categorías de negocio" icon="list" href="/business-categories">
    Obtén los IDs de categoría y subcategoría requeridos por la mutación.
  </Card>

  <Card title="Enviar documentos del negocio" icon="file-arrow-up" href="/submit-business-documents">
    Sube documentos de autorización y responde a solicitudes de documentación de KYB.
  </Card>

  <Card title="Estado KYB del negocio" icon="arrows-rotate" href="/business-status">
    Lee el estado KYB y el progreso de verificación por propietario.
  </Card>

  <Card title="Enlace de verificación del propietario" icon="id-card" href="/owner-verification-link">
    Genera un enlace compartible de verificación de identidad para un propietario.
  </Card>

  <Card title="Registrar clientes" icon="user-plus" href="/user-registration">
    Crea el usuario de Fluz que actuará como solicitante.
  </Card>
</CardGroup>
