# Crear (/docs/developers/api-reference/employer-registrations/create)

## Descripcion general [#descripcion-general]

Este endpoint permite crear uno o varios registros patronales (IMSS) dentro de tu organización. Acepta tanto **un objeto** como un **arreglo de hasta 100 objetos**, y la respuesta refleja la forma del cuerpo enviado. Cada fila debe enviar `legal_entity_number`, `number`, `risk_class`, `risk_premium` y `premium_effective_from`. Una solicitud exitosa devuelve `201` con los registros creados, incluyendo los campos generados por el servidor (`employer_registration_number`, `created_at`, `updated_at`).

En modo lote, si **cualquier** fila falla la validación, **ningún** registro se crea — la respuesta lista los problemas por fila para corregirlos en una sola pasada. Un lote puede mezclar registros de varias razones sociales: la unicidad se aplica por par `(legal_entity_number, number)`, por lo que dos filas con el mismo `number` pero distinta `legal_entity_number` son válidas.

`risk_premium` se acepta como número JSON (`0–1`) en el cuerpo, pero se serializa como **string decimal** (`Decimal(9,7)`, por ejemplo `"0.0054355"`) en la respuesta para preservar la precisión.

**Inicio del audit trail de prima.** En cada creación exitosa se abre una fila inicial en `premium_history` con `effective_from = premium_effective_from` y `effective_to = null`. Este trail es la fuente para los archivos SUA, así que es **append-only** — nunca se edita. Los cambios posteriores de `risk_class` / `risk_premium` agregan nuevas filas vía `PATCH`.

## Endpoint [#endpoint]

`POST https://app.integranom.com/api/v1/employer-registrations`

## Solicitud unica — minima [#solicitud-unica--minima]

***

Envía los cinco campos obligatorios. `label` queda en `null` y `is_active` toma `true` por defecto.

```json
{
  "legal_entity_number": 1,
  "number": "Y6712345678",
  "risk_class": 1,
  "risk_premium": 0.005,
  "premium_effective_from": "2026-01-01"
}
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/employer-registrations" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "legal_entity_number": 1,
  "number": "Y6712345678",
  "risk_class": 1,
  "risk_premium": 0.005,
  "premium_effective_from": "2026-01-01"
}'
```

**Respuesta**

```json
{
"employer_registration_number": 5,
"legal_entity_number": 1,
"number": "Y6712345678",
"label": null,
"risk_class": 1,
"risk_premium": "0.005",
"premium_effective_from": "2026-01-01T00:00:00.000Z",
"is_active": true,
"created_at": "2026-05-25T10:00:00.000Z",
"updated_at": "2026-05-25T10:00:00.000Z"
}
```

## Solicitud unica — todos los campos [#solicitud-unica--todos-los-campos]

***

Con `label` para referencia interna y `is_active` explícito. Observa cómo `risk_premium` se envía como número (`0.005`) y se devuelve como string decimal (`"0.005"`), y `premium_effective_from` se devuelve como timestamp ISO 8601.

```json
{
  "legal_entity_number": 1,
  "number": "Y6712345678",
  "label": "RP principal CDMX",
  "risk_class": 1,
  "risk_premium": 0.005,
  "premium_effective_from": "2026-01-01",
  "is_active": true
}
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/employer-registrations" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "legal_entity_number": 1,
  "number": "Y6712345678",
  "label": "RP principal CDMX",
  "risk_class": 1,
  "risk_premium": 0.005,
  "premium_effective_from": "2026-01-01",
  "is_active": true
}'
```

**Respuesta**

```json
{
"employer_registration_number": 5,
"legal_entity_number": 1,
"number": "Y6712345678",
"label": "RP principal CDMX",
"risk_class": 1,
"risk_premium": "0.005",
"premium_effective_from": "2026-01-01T00:00:00.000Z",
"is_active": true,
"created_at": "2026-05-25T10:00:00.000Z",
"updated_at": "2026-05-25T10:00:00.000Z"
}
```

## Solicitud por lote (1–100 registros) [#solicitud-por-lote-1100-registros]

***

Envía un **arreglo** de hasta 100 registros en el mismo endpoint. Si **cualquier** fila falla la validación, **ningún** registro se crea y la respuesta lista los problemas por fila.

Un lote puede mezclar registros de distintas razones sociales — la unicidad se aplica por par `(legal_entity_number, number)`.

```json
[
  {
    "legal_entity_number": 1,
    "number": "Y6712345678",
    "risk_class": 1,
    "risk_premium": 0.005,
    "premium_effective_from": "2026-01-01"
  },
  {
    "legal_entity_number": 2,
    "number": "Y8898765432",
    "risk_class": 3,
    "risk_premium": 0.02513,
    "premium_effective_from": "2026-01-01"
  }
]
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/employer-registrations" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '[
  {
    "legal_entity_number": 1,
    "number": "Y6712345678",
    "risk_class": 1,
    "risk_premium": 0.005,
    "premium_effective_from": "2026-01-01"
  },
  {
    "legal_entity_number": 2,
    "number": "Y8898765432",
    "risk_class": 3,
    "risk_premium": 0.02513,
    "premium_effective_from": "2026-01-01"
  }
]'
```

**Respuesta**

```json
{
"summary": { "total": 2, "created": 2 },
"created": [
  {
    "employer_registration_number": 6,
    "legal_entity_number": 1,
    "number": "Y6712345678",
    "label": null,
    "risk_class": 1,
    "risk_premium": "0.005",
    "premium_effective_from": "2026-01-01T00:00:00.000Z",
    "is_active": true,
    "created_at": "2026-05-25T10:00:00.000Z",
    "updated_at": "2026-05-25T10:00:00.000Z"
  },
  {
    "employer_registration_number": 7,
    "legal_entity_number": 2,
    "number": "Y8898765432",
    "label": null,
    "risk_class": 3,
    "risk_premium": "0.02513",
    "premium_effective_from": "2026-01-01T00:00:00.000Z",
    "is_active": true,
    "created_at": "2026-05-25T10:00:00.000Z",
    "updated_at": "2026-05-25T10:00:00.000Z"
  }
]
}
```

## Reglas de los campos [#reglas-de-los-campos]

| Campo                    | Tipo                | Requerido | Notas                                                                                                                                                                                                                                |
| ------------------------ | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `legal_entity_number`    | integer positivo    | Sí        | Debe corresponder a una razón social existente en la misma organización.                                                                                                                                                             |
| `number`                 | string              | Sí        | Número IMSS del registro patronal. Máx. 40 caracteres. Único por razón social (no por organización).                                                                                                                                 |
| `label`                  | string              | No        | Etiqueta libre para referencia interna.                                                                                                                                                                                              |
| `risk_class`             | integer 1–5         | Sí        | Clase de riesgo IMSS vigente.                                                                                                                                                                                                        |
| `risk_premium`           | number 0–1          | Sí        | Prima IMSS como fracción (ej. `0.05448` para 5.448%). Se almacena como `Decimal(9,7)`, siete decimales de fracción (cinco del porcentaje que publica el IMSS), y se devuelve como string decimal. Con más de 7 decimales se rechaza. |
| `premium_effective_from` | string `YYYY-MM-DD` | Sí        | Fecha de entrada en vigor de la clase/prima. Abre la fila inicial del audit trail (`premium_history`).                                                                                                                               |
| `is_active`              | boolean             | No        | Por defecto `true`.                                                                                                                                                                                                                  |

## Forma de las respuestas [#forma-de-las-respuestas]

### `201` — solicitud única [#201--solicitud-única]

Cuando el cuerpo es **un objeto**, la respuesta es el objeto del registro creado.

```json
{
  "employer_registration_number": 5,
  "legal_entity_number": 1,
  "number": "Y6712345678",
  "label": "RP principal CDMX",
  "risk_class": 1,
  "risk_premium": "0.005",
  "premium_effective_from": "2026-01-01T00:00:00.000Z",
  "is_active": true,
  "created_at": "2026-05-25T10:00:00.000Z",
  "updated_at": "2026-05-25T10:00:00.000Z"
}
```

### `201` — solicitud por lote [#201--solicitud-por-lote]

Cuando el cuerpo es **un arreglo**, la respuesta envuelve los resultados en `summary` + `created[]`.

```json
{
  "summary": { "total": 2, "created": 2 },
  "created": [
    { "employer_registration_number": 6, "...": "..." },
    { "employer_registration_number": 7, "...": "..." }
  ]
}
```

## Errores [#errores]

### `400` — validación fallida (solicitud única) [#400--validación-fallida-solicitud-única]

Para fallas de validación de esquema (campo faltante, tipo incorrecto), `errors` es un objeto indexado por campo:

```json
{
  "message": "Validation failed.",
  "errors": { "risk_premium": ["La prima debe expresarse como fracción (0–1)."] }
}
```

### `400` — validación fallida (solicitud por lote) [#400--validación-fallida-solicitud-por-lote]

Reporte por fila. **Ningún** registro del lote fue creado.

```json
{
  "message": "Validation failed for 1 employer registration(s). No registrations were created.",
  "summary": { "total": 2, "with_errors": 1 },
  "errors": [
    {
      "index": 0,
      "employer_registration": { "legal_entity_number": 99, "number": "Y6712345678" },
      "issues": [
        {
          "field": "legal_entity_number",
          "code": "LEGAL_ENTITY_NOT_FOUND",
          "message": "No legal entity with number '99' in this organization."
        }
      ]
    }
  ]
}
```

* `index` — posición 0-based de la fila que falló dentro del arreglo enviado.
* `employer_registration.legal_entity_number` / `employer_registration.number` — extraídos de tu entrada para que identifiques la fila sin contar.
* `issues[]` — todos los problemas de esa fila listados juntos para corregirlos antes de reintentar.

### `409` — condición de carrera [#409--condición-de-carrera]

Otra solicitud reclamó el par `(legal_entity_id, number)` entre el momento en que validamos el tuyo y el momento en que escribimos. En modo lote, la transacción completa hace rollback — ningún registro es creado. Reintenta la misma solicitud.

## Vocabulario de códigos de error [#vocabulario-de-códigos-de-error]

Estos códigos aparecen dentro de `issues[].code` (o como `code` en el cuerpo de error en single) y son estables — tu cliente puede ramificar lógica con base en ellos:

| Codigo                      | Significado                                                                                         |
| --------------------------- | --------------------------------------------------------------------------------------------------- |
| `INVALID_INPUT`             | Falla genérica de validación de esquema (campo faltante, tipo incorrecto, fecha mal formada, etc.). |
| `LEGAL_ENTITY_NOT_FOUND`    | `legal_entity_number` no coincide con una razón social viva de la organización.                     |
| `DUPLICATE_NUMBER`          | Ya existe un registro patronal con ese `number` para la razón social indicada.                      |
| `DUPLICATE_NUMBER_IN_BATCH` | Dos o más filas del lote envían el mismo par `(legal_entity_number, number)`.                       |
| `CONCURRENT_MODIFICATION`   | Señal de reintento por condición de carrera (respuesta `409`).                                      |