Crear
Crea uno o más centros de costos en tu organización.
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
https://app.integranom.com/api/v1/cost-centersSolicitud 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.
{ "code": "VEN-CC", "name": "Centro de costos Ventas" }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.
{
"code": "VEN-CC",
"name": "Centro de costos Ventas",
"link_department_number": 5
}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.
{
"code": "MKT-CC",
"name": "Marketing",
"department": { "parent_department_number": 1 }
}Solicitud por lote (1–100 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.
[
{ "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.
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)
| 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
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
201 — solicitud única
Cuando el cuerpo es un objeto, la respuesta es el objeto del centro de costos creado.
{
"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
Cuando el cuerpo es un arreglo, la respuesta envuelve los resultados en summary + created[].
{
"summary": { "total": 2, "created": 2 },
"created": [
{ "id": "ck...", "cost_center_number": 6, "...": "..." },
{ "id": "ck...", "cost_center_number": 7, "...": "..." }
]
}Errores
400 — validación fallida (solicitud única)
Para fallas de validación de campos, errors es un objeto indexado por campo:
{
"message": "Validation failed.",
"errors": { "code": ["Ingresa el código."] }
}400 — validación fallida (solicitud por lote)
Reporte por fila. Ningún centro de costos del lote fue creado.
{
"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
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
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). |

