# Crear (/docs/developers/api-reference/cost-centers/create)

## Descripcion general [#descripcion-general]

Este endpoint permite crear uno o varios centros de costos 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. Los campos obligatorios por fila son `code` y `name`; el resto son opcionales. Los centros de costos pueden anidarse mediante `parent_cost_center_code` para formar una jerarquía, y opcionalmente vincularse a un departamento existente vía `link_department_number` o crear uno nuevo inline mediante `department`. Una solicitud exitosa devuelve `201` con los centros de costos creados, incluyendo los campos generados por el servidor (`id`, `cost_center_number`, `parent_id`, `depth`, `created_at`, `updated_at`).

## Endpoint [#endpoint]

`POST https://app.integranom.com/api/v1/cost-centers`

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

***

Envía un objeto único con `code` y `name`. El centro de costos se crea como raíz (sin padre), sin departamento vinculado y activo por defecto.

```json
{ "code": "VEN-CC", "name": "Centro de costos Ventas" }
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/cost-centers" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "code": "VEN-CC", "name": "Centro de costos Ventas" }'
```

**Respuesta**

```json
{
"id": "ck...",
"cost_center_number": 5,
"parent_id": null,
"depth": 0,
"name": "Centro de costos Ventas",
"code": "VEN-CC",
"description": null,
"is_active": true,
"sort_order": 0,
"created_at": "2026-05-24T10:00:00.000Z",
"updated_at": "2026-05-24T10:00:00.000Z"
}
```

## Solicitud unica — vincular un departamento existente [#solicitud-unica--vincular-un-departamento-existente]

***

Usa `link_department_number` para asociar un departamento ya creado (y sin CC) al centro de costos nuevo. El departamento `5` recibe `costCenterId` apuntando al CC recién creado y sus campos `name`, `code`, `description`, `is_active`, `sort_order` se sobrescriben con los del CC.

Si el departamento ya está vinculado a otro CC, la solicitud falla con `DEPARTMENT_ALREADY_LINKED`.

```json
{
  "code": "VEN-CC",
  "name": "Centro de costos Ventas",
  "link_department_number": 5
}
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/cost-centers" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "code": "VEN-CC",
  "name": "Centro de costos Ventas",
  "link_department_number": 5
}'
```

**Respuesta**

```json
{
"id": "ck...",
"cost_center_number": 6,
"parent_id": null,
"depth": 0,
"name": "Centro de costos Ventas",
"code": "VEN-CC",
"description": null,
"is_active": true,
"sort_order": 0,
"created_at": "2026-05-24T10:00:00.000Z",
"updated_at": "2026-05-24T10:00:00.000Z"
}
```

## Solicitud unica — con departamento inline [#solicitud-unica--con-departamento-inline]

***

Usa `department` para crear de una sola vez un departamento nuevo vinculado al CC. Es **mutuamente excluyente** con `link_department_number` y solo está disponible en modo single (no batch).

El único campo significativo dentro de `department` es `parent_department_number`, que coloca el nuevo departamento bajo un departamento existente. Omítelo para crear un departamento raíz. Los demás campos (`name`, `code`, `description`, `is_active`, `sort_order`) se aceptan por simetría con `POST /api/v1/departments` pero se **sobrescriben silenciosamente** con los valores del CC.

```json
{
  "code": "MKT-CC",
  "name": "Marketing",
  "department": { "parent_department_number": 1 }
}
```

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/cost-centers" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "code": "MKT-CC",
  "name": "Marketing",
  "department": { "parent_department_number": 1 }
}'
```

**Respuesta**

```json
{
"id": "ck...",
"cost_center_number": 7,
"parent_id": null,
"depth": 0,
"name": "Marketing",
"code": "MKT-CC",
"description": null,
"is_active": true,
"sort_order": 0,
"created_at": "2026-05-24T10:00:00.000Z",
"updated_at": "2026-05-24T10:00:00.000Z"
}
```

## Solicitud por lote (1–100 centros de costos) [#solicitud-por-lote-1100-centros-de-costos]

***

Envía un **arreglo** de hasta 100 centros de costos en el mismo endpoint; el modo lote se activa al enviar un arreglo como cuerpo. Si **cualquier** fila falla la validación, **ningún** CC se crea y la respuesta lista los problemas por fila.

**Referencias entre filas no permitidas.** Una fila no puede usar `parent_cost_center_code` para apuntar a otra fila del mismo lote — el padre debe existir antes de la solicitud. Para construir árboles de varios niveles, crea las raíces en una primera solicitud y los hijos en una segunda.

El ejemplo de la derecha asume que `OPS` ya existe en la organización: si no existiera, la segunda fila fallaría con `COST_CENTER_PARENT_NOT_FOUND` y todo el lote se rechazaría.

```json
[
  { "code": "OPS", "name": "Operaciones" },
  { "code": "ADM", "name": "Administración", "parent_cost_center_code": "OPS" }
]
```

**Departamento inline no disponible en lote.** El campo `department` solo se acepta en modo single; en lote omítelo o usa `link_department_number`.

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/cost-centers" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '[
  { "code": "OPS", "name": "Operaciones" },
  { "code": "ADM", "name": "Administración", "parent_cost_center_code": "OPS" }
]'
```

**Respuesta**

```json
{
"summary": { "total": 2, "created": 2 },
"created": [
  {
    "id": "ck...",
    "cost_center_number": 6,
    "parent_id": null,
    "depth": 0,
    "name": "Operaciones",
    "code": "OPS",
    "description": null,
    "is_active": true,
    "sort_order": 0,
    "created_at": "2026-05-24T10:00:00.000Z",
    "updated_at": "2026-05-24T10:00:00.000Z"
  },
  {
    "id": "ck...",
    "cost_center_number": 7,
    "parent_id": "ck...",
    "depth": 1,
    "name": "Administración",
    "code": "ADM",
    "description": null,
    "is_active": true,
    "sort_order": 0,
    "created_at": "2026-05-24T10:00:00.000Z",
    "updated_at": "2026-05-24T10:00:00.000Z"
  }
]
}
```

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

| Campo                     | Tipo             | Requerido | Notas                                                                                                                                  |
| ------------------------- | ---------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `code`                    | string           | Sí        | ≤ 60 caracteres, se almacena en mayúsculas, único por organización.                                                                    |
| `name`                    | string           | Sí        | No vacío tras recortar espacios.                                                                                                       |
| `description`             | string           | No        | Texto libre.                                                                                                                           |
| `parent_cost_center_code` | string           | No        | Debe ser el `code` de un CC existente en la misma organización. No se permiten referencias dentro del lote.                            |
| `is_active`               | boolean          | No        | Por defecto `true`. Independiente del borrado — usa `DELETE` para borrar.                                                              |
| `sort_order`              | integer ≥ 0      | No        | Por defecto `0`.                                                                                                                       |
| `link_department_number`  | integer positivo | No        | Número de un departamento existente y sin CC; quedará vinculado a este CC. Mutuamente excluyente con `department`.                     |
| `department`              | object           | No        | Crea un departamento nuevo vinculado a este CC (forma abajo). Solo en modo single. Mutuamente excluyente con `link_department_number`. |

### Forma de `department` (creación inline) [#forma-de-department-creación-inline]

| Campo                      | Tipo             | Requerido | Notas                                                                                                 |
| -------------------------- | ---------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `parent_department_number` | integer positivo | No        | Coloca el nuevo departamento bajo un departamento existente. Omítelo para crear un departamento raíz. |
| `name`                     | string           | No        | Se ignora — el departamento hereda el `name` del CC.                                                  |
| `code`                     | string           | No        | Se ignora — el departamento hereda el `code` del CC.                                                  |
| `description`              | string           | No        | Se ignora — el departamento hereda la `description` del CC.                                           |
| `is_active`                | boolean          | No        | Se ignora — el departamento hereda el `is_active` del CC.                                             |
| `sort_order`               | integer ≥ 0      | No        | Se ignora — el departamento hereda el `sort_order` del CC.                                            |

### Espejo de campos con el departamento [#espejo-de-campos-con-el-departamento]

Cuando un departamento queda vinculado a un CC (vía `link_department_number` o `department`), el **CC es la fuente de verdad** para `name`, `code`, `description`, `is_active`, `sort_order` del departamento. Esto se aplica en escritura: el departamento vinculado siempre refleja los valores del CC.

## 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 centro de costos creado.

```json
{
  "id": "ck...",
  "cost_center_number": 5,
  "parent_id": null,
  "depth": 0,
  "name": "Centro de costos Ventas",
  "code": "VEN-CC",
  "description": null,
  "is_active": true,
  "sort_order": 0,
  "created_at": "2026-05-24T10:00:00.000Z",
  "updated_at": "2026-05-24T10: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": [
    { "id": "ck...", "cost_center_number": 6, "...": "..." },
    { "id": "ck...", "cost_center_number": 7, "...": "..." }
  ]
}
```

## Errores [#errores]

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

Para fallas de validación de campos, `errors` es un objeto indexado por campo:

```json
{
  "message": "Validation failed.",
  "errors": { "code": ["Ingresa el código."] }
}
```

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

Reporte por fila. **Ningún** centro de costos del lote fue creado.

```json
{
  "message": "Validation failed for 2 cost center(s). No cost centers were created.",
  "summary": { "total": 3, "with_errors": 2 },
  "errors": [
    {
      "index": 0,
      "cost_center": { "name": "Ventas", "code": "VEN-CC" },
      "issues": [
        {
          "field": "link_department_number",
          "code": "DEPARTMENT_ALREADY_LINKED",
          "message": "Department '5' is already linked to another cost center."
        }
      ]
    }
  ]
}
```

* `index` — posición 0-based de la fila que falló dentro del arreglo enviado.
* `cost_center.name` / `cost_center.code` — 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]

Se devuelve cuando otra solicitud reclama un `code` 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 CC 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 campos (formato, longitud, tipo).                                                                          |
| `COST_CENTER_PARENT_NOT_FOUND`    | `parent_cost_center_code` no coincide con un CC existente.                                                                                 |
| `DEPARTMENT_PARENT_NOT_FOUND`     | `department.parent_department_number` no coincide con un departamento existente.                                                           |
| `LINK_DEPARTMENT_NOT_FOUND`       | `link_department_number` no coincide con un departamento existente.                                                                        |
| `DEPARTMENT_ALREADY_LINKED`       | El departamento referenciado por `link_department_number` ya tiene `costCenterId`, o dos filas del lote referencian el mismo departamento. |
| `DUPLICATE_CODE`                  | `code` ya existe en la base de datos para esta organización.                                                                               |
| `DUPLICATE_CODE_IN_BATCH`         | Dos o más filas del lote envían el mismo `code`.                                                                                           |
| `LINKED_DEPARTMENT_CODE_CONFLICT` | El departamento inline heredaría un `code` (el del CC) que ya está usado por otro departamento existente.                                  |
| `CONCURRENT_MODIFICATION`         | Señal de reintento por condición de carrera (respuesta `409`).                                                                             |