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

# Crear una entidad (persona o empresa)

> Crea una nueva persona o empresa con datos personalizados — en el modelo universal de entidades gu1 para KYC, KYB y análisis de riesgo.

## Descripción general

Crea una nueva entidad con el tipo y atributos especificados. Las entidades representan los objetos de datos principales que deseas analizar para riesgo y cumplimiento.

## Endpoint

```
POST http://api.gu1.ai/entities
```

## Autenticación

Requiere una clave de API válida en el encabezado de autorización:

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Cuerpo de la solicitud

<ParamField body="type" type="string" required>
  El tipo de entidad a crear. Tipos disponibles:

  * `person` - Persona individual/cliente
  * `company` - Entidad empresarial
</ParamField>

<ParamField body="externalId" type="string">
  Tu identificador único para esta entidad en tu sistema. **Opcional** — gu1 asigna uno automáticamente si se omite (ver tabla abajo).
</ParamField>

<ParamField body="name" type="string" required>
  Nombre para mostrar de la entidad
</ParamField>

<ParamField body="countryCode" type="string" required>
  Código de país ISO 3166-1 alfa-2 (ej., "US", "BR", "AR")
</ParamField>

<ParamField body="taxId" type="string">
  Número de identificación fiscal (validado según el país). En una organización, un `taxId` activo normalizado puede pertenecer a **una sola** entidad (`person` o `company`). Los conflictos responden **`409`** con código **`DUPLICATE_TAX_ID`**.
</ParamField>

<Note>
  **Cuando se omite `externalId`**

  | Envías                      | `externalId` guardado                                                                                                                         |
  | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
  | `taxId` (con o sin formato) | Tax ID normalizado: **solo letras y dígitos, mayúsculas** — sin puntos, guiones ni espacios. Ejemplo: `30-12345678-9` → `30123456789`         |
  | Sin `taxId`                 | `{slug-nombre}-{timestamp-ms}` derivado de `name` (minúsculas, no alfanumérico → `-`, máx. 20 caracteres). Ejemplo: `acme-corp-1719345678901` |

  El campo **`taxId`** se sigue guardando en el [formato de visualización del país](/es/api-reference/entities/tax-id-formats) cuando lo envías. Mandá un `externalId` explícito si necesitás tu propio ID de CRM o usuario, independiente del documento fiscal.
</Note>

<ParamField body="email" type="string | null">
  Correo de contacto principal en la fila de la entidad (opcional, nullable). Las entidades existentes quedan en `null` hasta que se envíe un valor. En PATCH, `null` borra el valor.
</ParamField>

<ParamField body="phone" type="string | null">
  Teléfono de contacto principal en la fila de la entidad (opcional, nullable). Las entidades existentes quedan en `null` hasta que se envíe un valor. En PATCH, `null` borra el valor.
</ParamField>

<ParamField body="operationalHours" type="object | null">
  Horario operativo opcional para reglas KYT (`outside_entity_operational_hours`). Campo en **raíz** (no dentro de `attributes`).

  * `timezone` (obligatorio si se envía `operationalHours`): valor del enum **transaction\_time\_zone**. **Lista completa:** [Enum zona horaria](/es/api-reference/transactions/time-zone-enum).
  * `weekly`: claves `monday` … `sunday`. Cada día: `{ "start": "09:00", "end": "18:00" }` o `{ "closed": true }`. Días omitidos = cerrado.
</ParamField>

<ParamField body="nationality" type="string | null">
  Nacionalidad opcional en raíz: ISO 3166-1 alfa-2 o una etiqueta reconocida que la API mapea a ISO2. Si se omite, el campo raíz puede derivarse de `entityData.person.nationality` o `entityData.company.nationality` cuando sea mapeable.
</ParamField>

<ParamField body="monitoring" type="object">
  Opcional. Pide que un **enriquecimiento que admite monitoreo** corra en **modo lista vigilada** (op 1: screening + alta en watchlist para corridas periódicas), no solo como consulta puntual (op 0).

  **Alcance hoy:** solo **`global_gueno_sanctions_enrichment`**. La clave del mapa es el **mismo código** que en `autoExecuteIntegrations.enrichments`. Los códigos legacy `*_check` **fueron eliminados (2026-06-04)** y ya no forman parte del contrato.

  * **`main`**: flags para la **entidad principal** de este `POST /entities`.
  * **`relationships`**: **ignorado** aquí; usá [Crear automáticamente](/es/api-reference/entities/create-automatic) con `depth` > 0.

  **Valor por código** (recomendado objeto; la API acepta también `boolean` legacy):

  * `{ "watchlist": true }` — suscripción; matriz de monitoreo = heredar `riskMatrixId` de la entidad.
  * `{ "watchlist": true, "riskMatrixId": "<uuid>" }` — suscripción; **solo** esa matriz en reglas/screening disparados por monitoreo.
  * `{ "watchlist": false }` o `false` — sin lista vigilada.
  * `true` — equivalente a `{ "watchlist": true }`.

  **Requisitos** (si falta alguno, el enrichment corre igual como consulta normal, sin error obligatorio): (1) el código en `autoExecuteIntegrations.enrichments` o activo vía execute-all; (2) monitoreo habilitado en **Marketplace** para Gu1 sanciones.

  Guía: [Monitoreo de sanciones Gu1](/es/guias/monitoreo-sanciones-gueno-cliente). Ejemplos: [Monitoreo al crear](#ejemplo-monitoreo-de-sanciones-gu1-al-crear).
</ParamField>

<ParamField body="autoExecuteIntegrations" type="object">
  **Opcional** — Ejecutar integraciones (enriquecimientos y checks) justo después de crear la entidad.

  Propiedades:

  * `executeAllActiveEnrichments` (boolean)
  * `enrichments` (array de códigos de proveedor; ver [códigos de proveedor](/es/api-reference/integrations/provider-codes))
  * `enrichmentGroupRefs` (array de strings, opcional) — Slugs de **grupos de enriquecimiento** del Marketplace (solo enriquecimientos). Con `executeAllActiveEnrichments: false`, se resuelven y se combinan con `enrichments` explícitos. Con `executeAllActiveEnrichments: true`, los refs de grupo no se usan; los `enrichments` explícitos pueden seguir añadiendo códigos tras el conjunto activo.
</ParamField>

<ParamField body="attributes" type="object">
  **Opcional** — Atributos personalizados. Acepta formato **plano** (`{ "phone": "..." }`) o **anidado por categoría** (`{ "contact": { "phone": "..." } }`). Se almacenan **tal cual** (los objetos anidados actúan como categorías y se devuelven como se enviaron); ver [Actualizar entidad](/es/api-reference/entities/update) para detalles.
</ParamField>

<ParamField body="entityData" type="object">
  **Opcional** - Estructura de datos específica del tipo. Ver ejemplos a continuación para cada tipo de entidad.

  <Note>
    **¿Cuándo usar entityData?**

    * **Opcional para creación básica de entidad** - Puedes crear una entidad con solo `type`, `name`, `taxId` y `countryCode`
    * **Requerido para enriquecimiento y análisis de riesgo** - Si quieres ejecutar verificaciones de cumplimiento, necesitarás proporcionar campos relevantes
    * **Se puede completar después** - Puedes crear una entidad mínima primero, luego actualizarla con datos completos antes de ejecutar el análisis de riesgo

    **Ejemplo Mínimo (Person):**

    ```json theme={null}
    {
      "type": "person",
      "name": "Juan Pérez",
      "taxId": "12345678",
      "countryCode": "AR"
      // No se necesita entityData para creación básica
    }
    ```

    **Ejemplo Completo (Person con datos KYC):**

    ```json theme={null}
    {
      "type": "person",
      "name": "Juan Pérez",
      "taxId": "12345678",
      "countryCode": "AR",
      "entityData": {
        "person": {
          "firstName": "Juan",
          "lastName": "Pérez",
          "dateOfBirth": "1980-01-15",
          "email": "juan@example.com",
          "phone": "+5491123456789"
        }
      }
    }
    ```
  </Note>
</ParamField>

### Matriz de riesgo y ejecución de reglas

<ParamField body="riskMatrixId" type="string | string[]">
  Uno o más UUIDs de matrices de riesgo (legacy: un solo UUID). Si se envían, tras la creación el sistema evalúa la entidad **solo** contra reglas activas de esas matrices (salvo `skipRulesExecution: true`). Misma semántica que `riskMatrixIds` cuando enviás un único id como string.
</ParamField>

<ParamField body="riskMatrixIds" type="string[]">
  Forma preferida para **varias** matrices: lista ordenada de UUIDs de tu organización. Si viene informada y no vacía, tiene precedencia sobre `riskMatrixId`.
</ParamField>

<ParamField body="skipRulesExecution" type="boolean" default="false">
  Omitir la ejecución automática de reglas tras crear la entidad. Usalo para crear primero y disparar reglas manualmente después.
</ParamField>

<ParamField body="shareholderDepth" type="number" default="0">
  Solo entidades **company**: niveles de accionistas a crear automáticamente (0–5). `0` = ninguno (default).
</ParamField>

<ParamField body="relationships" type="array">
  Vínculos **declarativos** a entidades **ya existentes** en la misma organización (máx. 10). Independiente de `shareholderDepth` / enrichment.

  Cada ítem debe incluir **exactamente uno** de: `relatedEntityId` (UUID), `relatedTaxId`, `relatedExternalId`.

  | Campo                | Descripción                                                                                                                                                                                                |
  | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `relationshipType`   | Enum del grafo (`shareholder`, `manages`, `owns`, `employed_by`, …)                                                                                                                                        |
  | `role` / `roles`     | Rol(es) en `metadata.roles` (ej. `SOCIO`, `REPRESENTANTE`)                                                                                                                                                 |
  | `relatedCountryCode` | ISO2 opcional para normalizar `relatedTaxId` (default: `countryCode` de la entidad nueva)                                                                                                                  |
  | `asSource`           | Default `true`: la entidad creada es **source** y la relacionada es **target**. Con `shareholder`, la creada es accionista/socio de la contraparte (ej. persona → empresa). `false` invierte la dirección. |

  Si la contraparte no existe → **404** `RELATED_ENTITY_NOT_FOUND` y **no** se crea la entidad.
</ParamField>

## Estructuras de datos de entidades

### Entidad Persona

```json theme={null}
{
  "person": {
    "firstName": "string",
    "lastName": "string",
    "dateOfBirth": "YYYY-MM-DD",
    "nationality": "string",
    "occupation": "string",
    "income": number,
    "incomeCurrency": "string",
    "address": "string | object (ver nota Formato de dirección)",
    "city": "string",
    "state": "string",
    "country": "string",
    "postalCode": "string",
    "email": "string",
    "gender": "M | F | male | female | unknown | other",
    "phone": "string",
    "alternativePhone": "string",
    "idType": "national_id | passport | drivers_license | tax_id | other",
    "idNumber": "string",
    "isPep": boolean,
    "pepPosition": "string",
    "pepCountry": "string"
  }
}
```

<Note>
  **Género (`entityData.person.gender`)** — enum cerrado. Solo se aceptan los valores de la tabla; cualquier otro string (p. ej. `X`, `non_binary`) devuelve **error de validación**.

  | Valor          | Significado                                                    |
  | -------------- | -------------------------------------------------------------- |
  | `M` o `male`   | Masculino                                                      |
  | `F` o `female` | Femenino                                                       |
  | `other`        | Otro / no binario — usar este código para identidad no binaria |
  | `unknown`      | No informado o desconocido                                     |

  **Argentina (AR):** la derivación automática de CUIL desde DNI + género y las validaciones RENAPER solo reconocen `M`/`F` (o `male`/`female`). Con `other` o `unknown` no se deriva CUIL y RENAPER no puede usar el género de la entidad.
</Note>

### Entidad Empresa

```json theme={null}
{
  "company": {
    "legalName": "string",
    "tradeName": "string",
    "incorporationDate": "YYYY-MM-DD",
    "industry": "string",
    "employeeCount": number,
    "revenue": number
  }
}
```

### Entidad Alerta

```json theme={null}
{
  "alert": {
    "alertNumber": "string",
    "alertType": "RISK | COMPLIANCE | FRAUD | REGULATORY | SYSTEM",
    "severity": "INFO | WARNING | HIGH | CRITICAL",
    "status": "NEW | ACKNOWLEDGED | INVESTIGATING | RESOLVED | FALSE_POSITIVE",
    "sourceSystem": "string",
    "triggerRuleId": "string",
    "triggerCondition": "string",
    "affectedEntityId": "string",
    "relatedEntityIds": ["string"],
    "alertedAt": "ISO8601 timestamp",
    "acknowledgedAt": "ISO8601 timestamp",
    "acknowledgedBy": "string",
    "resolvedAt": "ISO8601 timestamp",
    "resolvedBy": "string",
    "resolutionNotes": "string",
    "falsePositiveReason": "string"
  }
}
```

## Parámetros de Query

<ParamField query="refresh" type="boolean" default="false">
  Fuerza el re-enriquecimiento de la entidad incluso si ya existe en el sistema.

  **Tipo**: `boolean` (query string: `"true"` o `"false"`)

  **Comportamiento**:

  * Cuando es `true`: Fuerza al sistema a obtener datos frescos de proveedores de enriquecimiento (ej: verificación de antecedentes, datos KYC, registros de empresas)
  * Cuando es `false` u omitido: Utiliza datos de enriquecimiento en caché si están disponibles
  * Sobreescribe la configuración de organización `enrichmentsConfig.reEnrichExistingEntities`

  **Casos de Uso**:

  * Re-validar datos de entidad después de un período de tiempo significativo
  * Actualizar información cuando se sabe que los datos externos han cambiado
  * Actualización manual activada por el equipo de cumplimiento
  * Auditorías periódicas de calidad de datos

  **Ejemplo**:

  ```bash theme={null}
  POST http://api.gu1.ai/entities?refresh=true
  ```

  **Nota**: El re-enriquecimiento puede incurrir en costos adicionales de proveedores de datos externos.
</ParamField>

## Respuesta

<ResponseField name="success" type="boolean">
  Indica si la entidad se creó correctamente
</ResponseField>

<ResponseField name="entity" type="object">
  El objeto de entidad creado incluyendo:

  * `id` - ID interno de gu1
  * `externalId` - Tu ID externo
  * `organizationId` - ID de tu organización
  * `type` - Tipo de entidad
  * `name` - Nombre de la entidad
  * `riskScore` - Puntuación de riesgo inicial (0-100)
  * `status` - Estado de la entidad
  * `entityData` - Datos específicos del tipo
  * `attributes` - Atributos personalizados
  * `createdAt` - Marca de tiempo de creación
  * `updatedAt` - Marca de tiempo de última actualización
</ResponseField>

<ResponseField name="rulesResult" type="object">
  Resultado de la ejecución de reglas (solo presente cuando se ejecutaron reglas, p. ej. cuando **skipRulesExecution** es `false` y hay matriz de riesgo configurada), incluyendo:

  * **success** (boolean) - Si las reglas se ejecutaron correctamente
  * **rulesTriggered** (number) - Número de reglas disparadas
  * **alerts** (array) - Alertas generadas por las reglas
  * **riskScore** (number) - Puntuación de riesgo final
  * **decision** (string) - Decisión final (APPROVE, REJECT, HOLD, REVIEW\_REQUIRED)
  * **rulesExecutionSummary** (object) - Presente cuando se ejecutaron reglas. Ver abajo la estructura.
</ResponseField>

<ResponseField name="rulesExecutionSummary" type="object">
  **Solo presente cuando se ejecutaron reglas (p. ej. skipRulesExecution es false).** Resumen de qué reglas hicieron match (hit) vs no (no hit), acciones ejecutadas y puntuación total. Omitido cuando las reglas no se ejecutaron.

  * **rulesHit** (array) - Reglas cuyas condiciones se cumplieron. Cada ítem: **name**, **description**, **score**, **priority**, **category**, **status** (p. ej. `active`, `shadow`), **conditions** (array de `{ field, value, operator? }`), **actions** (alerts, suggestion, status, assignedUser).
  * **rulesNoHit** (array) - Reglas evaluadas pero cuyas condiciones no se cumplieron. Misma estructura que rulesHit (incluye acciones configuradas, no ejecutadas).
  * **actionsExecuted** (object) - Acciones ejecutadas agregadas de todas las reglas que hicieron hit: **alerts** (array de `{ name?, type?, severity?, description? }`), **suggestion** (`BLOCK` | `SUSPEND` | `FLAG`, mayor peso), **status** (estado aplicado a la entidad, si hay), **assignedUser** (`{ userId }`, si hay), **customKeys** (array de strings, opcional) — claves de acciones personalizadas de las reglas que hicieron match; para integraciones/workflows.
  * **totalScore** (number) - Suma del **score** de todas las reglas que hicieron hit y no están en estado `shadow`.
</ResponseField>

## Ejemplo: monitoreo de sanciones Gu1 al crear

El parámetro **`monitoring`** no ejecuta integraciones por sí solo: solo modifica **cómo** corre un enrichment que ya pediste en **`autoExecuteIntegrations`**. Hoy solo aplica a integraciones del catálogo con **monitoreo de org** (Marketplace); en creación por API el caso documentado es **`global_gueno_sanctions_enrichment`**.

| Condición                                                                                                           | Efecto                                                                         |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Código en `autoExecuteIntegrations.enrichments` + `monitoring.main[código]` con watchlist activo + monitoreo org ON | Enrichment en **op 1** (consulta + alta en lista vigilada / screening diario). |
| Falta `monitoring` o `watchlist: false`                                                                             | **Op 0** — consulta puntual, sin suscripción.                                  |
| Hay `monitoring` pero monitoreo org OFF                                                                             | **Op 0** — sin error obligatorio; el screening igual corre.                    |
| Solo `monitoring` sin el código en `enrichments`                                                                    | `monitoring` no tiene efecto (nada que ejecutar con ese flag).                 |

<Warning>
  Los códigos `*_check` (p. ej. `global_gueno_sanctions_check`) **fueron eliminados (2026-06-04)**. Para lista vigilada al crear, usá **`global_gueno_sanctions_enrichment`** en `enrichments` y el mismo código en `monitoring.main`.
</Warning>

### Solo lista vigilada Gu1 (persona)

```json theme={null}
{
  "type": "person",
  "externalId": "cust_screening_001",
  "name": "María González",
  "countryCode": "AR",
  "taxId": "27-12345678-1",
  "entityData": {
    "person": {
      "firstName": "María",
      "lastName": "González",
      "dateOfBirth": "1985-03-15",
      "nationality": "AR"
    }
  },
  "monitoring": {
    "main": {
      "global_gueno_sanctions_enrichment": {
        "watchlist": true
      }
    }
  },
  "autoExecuteIntegrations": {
    "executeAllActiveEnrichments": false,
    "enrichments": ["global_gueno_sanctions_enrichment"]
  }
}
```

### Enriquecimientos locales + monitoreo Gu1 (persona AR)

Mismo `POST /entities`: podés combinar enrichments de registro/KYC con Gu1 en lista vigilada. **`monitoring` solo afecta** al código que figure en el mapa (acá, Gu1 sanciones).

```json theme={null}
{
  "type": "person",
  "name": "María González",
  "taxId": "20-12345678-9",
  "countryCode": "AR",
  "riskMatrixId": "550e8400-e29b-41d4-a716-446655440000",
  "entityData": {
    "person": {
      "firstName": "María",
      "lastName": "González",
      "dateOfBirth": "1985-03-15"
    }
  },
  "autoExecuteIntegrations": {
    "executeAllActiveEnrichments": false,
    "enrichments": [
      "ar_renaper_data_enrichment",
      "ar_repet_person_enrichment",
      "global_gueno_sanctions_enrichment"
    ]
  },
  "monitoring": {
    "main": {
      "global_gueno_sanctions_enrichment": {
        "watchlist": true
      }
    }
  }
}
```

Los enrichments `ar_renaper_*` y `ar_repet_*` corren como consulta normal; solo `global_gueno_sanctions_enrichment` puede pasar a op 1 si el monitoreo está habilitado en Marketplace.

### Matriz de riesgo solo para monitoreo (opcional)

Si además de `riskMatrixId` en la entidad querés una matriz **distinta** solo para reglas disparadas por el screening diario:

```json theme={null}
"monitoring": {
  "main": {
    "global_gueno_sanctions_enrichment": {
      "watchlist": true,
      "riskMatrixId": "660e8400-e29b-41d4-a716-446655440001"
    }
  }
}
```

`riskMatrixId: null` en el objeto equivale a **heredar** la matriz global de la entidad para esas corridas.

### Empresa (`type: "company"`)

Misma forma en `monitoring.main`; cambiá `type`, `entityData.company` y los códigos de `enrichments` según el país.

```json theme={null}
{
  "type": "company",
  "externalId": "co_screening_001",
  "name": "Tech Solutions S.A.",
  "countryCode": "AR",
  "taxId": "30-71000001-2",
  "entityData": {
    "company": {
      "legalName": "Tech Solutions S.A.",
      "tradeName": "Tech Solutions",
      "industry": "Software"
    }
  },
  "monitoring": {
    "main": {
      "global_gueno_sanctions_enrichment": { "watchlist": true }
    }
  },
  "autoExecuteIntegrations": {
    "executeAllActiveEnrichments": false,
    "enrichments": ["global_gueno_sanctions_enrichment"]
  }
}
```

<Info>
  **`monitoring.relationships`** no se usa en `POST /entities`. Para accionistas o relacionadas en el mismo job, usá [Crear automáticamente](/es/api-reference/entities/create-automatic) con `depth` > 0, `monitoring.relationships` y los enrichments correspondientes en `autoExecuteIntegrationsShareholders`.
</Info>

## Ejemplos

### Crear Entidad Persona (KYC)

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST http://api.gu1.ai/entities \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "person",
      "externalId": "customer_12345",
      "name": "María González",
      "countryCode": "AR",
      "taxId": "20-12345678-9",
      "entityData": {
        "person": {
          "firstName": "María",
          "lastName": "González",
          "dateOfBirth": "1985-03-15",
          "nationality": "AR",
          "occupation": "Software Engineer",
          "income": 85000
        }
      },
      "attributes": {
        "email": "maria.gonzalez@example.com",
        "phone": "+54 11 1234-5678",
        "customerSince": "2024-01-15"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://api.gu1.ai/entities', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      type: 'person',
      externalId: 'customer_12345',
      name: 'María González',
      countryCode: 'AR',
      taxId: '20-12345678-9',
      entityData: {
        person: {
          firstName: 'María',
          lastName: 'González',
          dateOfBirth: '1985-03-15',
          nationality: 'AR',
          occupation: 'Software Engineer',
          income: 85000
        }
      },
      attributes: {
        email: 'maria.gonzalez@example.com',
        phone: '+54 11 1234-5678',
        customerSince: '2024-01-15'
      }
    })
  });

  const data = await response.json();
  console.log(data.entity);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'http://api.gu1.ai/entities',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'type': 'person',
          'externalId': 'customer_12345',
          'name': 'María González',
          'countryCode': 'AR',
          'taxId': '20-12345678-9',
          'entityData': {
              'person': {
                  'firstName': 'María',
                  'lastName': 'González',
                  'dateOfBirth': '1985-03-15',
                  'nationality': 'AR',
                  'occupation': 'Software Engineer',
                  'income': 85000
              }
          },
          'attributes': {
              'email': 'maria.gonzalez@example.com',
              'phone': '+54 11 1234-5678',
              'customerSince': '2024-01-15'
          }
      }
  )

  entity = response.json()['entity']
  print(entity)
  ```
</CodeGroup>

### Crear Entidad Empresa (KYB)

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST http://api.gu1.ai/entities \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "company",
      "externalId": "company_789",
      "name": "Tech Solutions S.A.",
      "countryCode": "BR",
      "taxId": "12.345.678/0001-90",
      "entityData": {
        "company": {
          "legalName": "Tech Solutions Sociedade Anônima",
          "tradeName": "Tech Solutions",
          "incorporationDate": "2020-06-15",
          "industry": "Software Development",
          "employeeCount": 50,
          "revenue": 5000000
        }
      },
      "attributes": {
        "website": "https://techsolutions.com.br",
        "registeredAddress": "Av. Paulista, 1000, São Paulo",
        "partnershipTier": "gold"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://api.gu1.ai/entities', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      type: 'company',
      externalId: 'company_789',
      name: 'Tech Solutions S.A.',
      countryCode: 'BR',
      taxId: '12.345.678/0001-90',
      entityData: {
        company: {
          legalName: 'Tech Solutions Sociedade Anônima',
          tradeName: 'Tech Solutions',
          incorporationDate: '2020-06-15',
          industry: 'Software Development',
          employeeCount: 50,
          revenue: 5000000
        }
      },
      attributes: {
        website: 'https://techsolutions.com.br',
        registeredAddress: 'Av. Paulista, 1000, São Paulo',
        partnershipTier: 'gold'
      }
    })
  });

  const data = await response.json();
  console.log(data.entity);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'http://api.gu1.ai/entities',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'type': 'company',
          'externalId': 'company_789',
          'name': 'Tech Solutions S.A.',
          'countryCode': 'BR',
          'taxId': '12.345.678/0001-90',
          'entityData': {
              'company': {
                  'legalName': 'Tech Solutions Sociedade Anônima',
                  'tradeName': 'Tech Solutions',
                  'incorporationDate': '2020-06-15',
                  'industry': 'Software Development',
                  'employeeCount': 50,
                  'revenue': 5000000
              }
          },
          'attributes': {
              'website': 'https://techsolutions.com.br',
              'registeredAddress': 'Av. Paulista, 1000, São Paulo',
              'partnershipTier': 'gold'
          }
      }
  )

  entity = response.json()['entity']
  print(entity)
  ```
</CodeGroup>

## Ejemplo de respuesta

```json theme={null}
{
  "success": true,
  "entity": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "externalId": "customer_12345",
    "organizationId": "8e2f89ab-c216-4eb4-90eb-ca5d44499aaa",
    "type": "person",
    "name": "María González",
    "taxId": "20-12345678-9",
    "countryCode": "AR",
    "riskScore": 25,
    "status": "active",
    "entityData": {
      "person": {
        "firstName": "María",
        "lastName": "González",
        "dateOfBirth": "1985-03-15",
        "nationality": "AR",
        "occupation": "Software Engineer",
        "income": 85000
      }
    },
    "attributes": {
      "email": "maria.gonzalez@example.com",
      "phone": "+54 11 1234-5678",
      "customerSince": "2024-01-15"
    },
    "createdAt": "2024-10-03T14:30:00.000Z",
    "updatedAt": "2024-10-03T14:30:00.000Z"
  }
}
```

## Respuestas de Error

### 400 Bad Request - ID Fiscal Inválido

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Formato de CUIT inválido. Por favor verifica el formato e intenta nuevamente.",
    "details": {
      "field": "taxId",
      "taxIdName": "CUIT",
      "providedValue": "20-12345678-9"
    }
  },
  "entity": null
}
```

### 400 Bad Request - Campos Requeridos Faltantes

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Faltan campos requeridos para la creación de la empresa",
    "details": {
      "missingFields": ["legalName", "industry"],
      "requiredFields": ["legalName", "tradeName", "industry", "incorporationDate"],
      "countryCode": "BR"
    }
  },
  "entity": null
}
```

### 409 Conflict - Entidad Duplicada

```json theme={null}
{
  "success": false,
  "error": {
    "code": "DUPLICATE_ENTITY",
    "message": "Ya existe una entidad con este external_id",
    "details": {
      "field": "external_id",
      "value": "customer_12345",
      "constraint": "entities_organization_external_id_unique"
    }
  },
  "entity": null
}
```

Un **tax ID** duplicado (misma organización, cualquier tipo de entidad) responde **`DUPLICATE_TAX_ID`** con `existingEntityId` / `existingEntityType` en `details` cuando están disponibles.

### 401 Unauthorized

```json theme={null}
{
  "error": "Invalid or missing API key",
  "code": "INVALID_KEY"
}
```

### 429 Too Many Requests

```json theme={null}
{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "message": "Has excedido tu límite de velocidad de la API. Por favor espera antes de hacer más solicitudes.",
  "retryAfter": 3600,
  "limit": 100,
  "remaining": 0,
  "resetAt": "2025-01-15T10:00:00Z"
}
```

### 500 Internal Server Error

```json theme={null}
{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Ocurrió un error inesperado al crear la entidad",
    "details": {
      "message": "Database connection timeout"
    }
  },
  "entity": null
}
```

## Próximos pasos

Después de crear una entidad, puedes:

1. [Solicitar análisis de IA](/en/api-reference/entities/analyze) - Obtener evaluación de riesgo automatizada
2. [Listar entidades](/es/api-reference/entities/list) - Consultar tus entidades
3. [Obtener detalles de entidad](/es/api-reference/entities/get) - Recuperar información completa de la entidad
4. [Aplicar reglas](/es/api-reference/rules/execute) - Ejecutar reglas de cumplimiento y riesgo
