{
  "info": {
    "_postman_id": "6f1e2d3c-4b5a-4c7d-8e9f-0a1b2c3d4e5f",
    "name": "FileXpress API Externa",
    "description": "La API Externa de FileXpress permite que sistemas de terceros (POS, ERP, tiendas en línea, relojes biométricos, sistemas de nómina o de BI) se integren con un negocio de FileXpress: facturación electrónica, inventario, precios y promociones, caja, cuentas por cobrar y pagar, tesorería, contabilidad, proyectos y recursos humanos.\n\nEsta colección contiene todos los endpoints de la API Externa, agrupados por módulo, con cuerpos de ejemplo y respuestas guardadas. La documentación completa de cada endpoint está en la sección API de la documentación de FileXpress.\n\n## Configuración del entorno\n\n1. Importe la colección y el entorno `FileXpress API Externa` (archivo `FileXpress-API-Externa.postman_environment.json`).\n2. Seleccione el entorno en Postman.\n3. Complete `api_key` con la API Key de su integración (FileXpress: Integraciones > Nueva Integración).\n4. Ejecute `Generales y catálogos > Listar sucursales` y copie el `id` de la sucursal de trabajo en `branch_id`.\n5. Complete las demás variables de identificadores (`employee_id`, `sale_id`, `product_id`, etc.) a medida que las obtenga de las respuestas.\n\n`base_url` apunta a `https://api.filexpress.app/api/external/v1`. No existe una URL distinta para pruebas: el ambiente (pruebas o producción) lo define el negocio al que pertenece la integración. Use siempre la API Key de un negocio en ambiente de pruebas durante el desarrollo; las solicitudes de esta colección son reales.\n\n## Versionado y retiro de la URL sin versión\n\nTodas las solicitudes de esta colección usan la URL base versionada `https://api.filexpress.app/api/external/v1` (variable `base_url`).\n\n**Aviso de retiro:** a partir del **1 de enero de 2027** se elimina la ruta heredada sin prefijo de versión (`https://api.filexpress.app/api/external/...`). Las integraciones que aún la usen deben migrar a `/api/external/v1`: los endpoints, cuerpos, respuestas y permisos son los mismos; solo cambia la URL base. Si importó una versión anterior del entorno, actualice el valor de `base_url`.\n\nLa ruta `/api/external/v2` está reservada para cambios incompatibles futuros y por ahora solo expone `GET /health`.\n\n## Autenticación\n\nTodas las solicitudes, excepto `GET /health`, envían la API Key en el encabezado `X-API-Key`. La autenticación está definida a nivel de colección (tipo API Key, valor `{{api_key}}`) y todas las solicitudes la heredan. No se usa secreto adicional ni token de sesión.\n\n| Código | Causa |\n|---|---|\n| `401` | Falta el encabezado `X-API-Key` o la llave no existe. |\n| `403` | La integración está desactivada o no tiene el permiso del endpoint. |\n| `429` | Se superó el límite de peticiones de la integración. |\n\nGuarde la API Key como un secreto. Si se expone, regénerela desde FileXpress; la anterior deja de funcionar de inmediato.\n\n## Alcance de los datos\n\nCada integración pertenece a un negocio. Todas las consultas y escrituras se limitan a ese negocio: un identificador de otro negocio responde `404`, igual que uno inexistente.\n\n## Formato de respuestas\n\nLa mayoría de los módulos (ventas, compras, sucursales, inventario, precios, caja, cuentas por cobrar y pagar, tesorería, contabilidad, proyectos y recursos humanos) responden:\n\n```json\n{ \"status\": true, \"data\": { } }\n```\n\ny en error:\n\n```json\n{ \"status\": false, \"message\": \"Validation errors\", \"errors\": { \"start_date\": [\"The start date field is required.\"] } }\n```\n\nLos endpoints de clientes, proveedores, productos y catálogos usan el formato heredado `{ \"success\", \"message\", \"data\" }`. En ese formato, los errores de validación responden con código `404` y el detalle en `data`:\n\n```json\n{ \"success\": false, \"message\": \"Validation Error.\", \"data\": { \"email\": [\"The email field is required.\"] } }\n```\n\nLos listados paginados aceptan `per_page` y `page` y devuelven `data.data` (registros) y `data.pagination` (`current_page`, `last_page`, `per_page`, `total`).\n\n## Códigos de estado\n\n| Código | Significado |\n|---|---|\n| `200` / `201` | Operación correcta. |\n| `401` | API Key ausente o inválida. |\n| `403` | Integración desactivada o sin el permiso requerido. La respuesta incluye `required_scope`. |\n| `404` | Recurso inexistente o de otro negocio (y errores de validación en el formato heredado). |\n| `409` | Conflicto: estado que no permite la operación o `Idempotency-Key` reutilizada con otro cuerpo. |\n| `422` | Error de validación. El detalle por campo está en `errors`. |\n| `429` | Límite de peticiones excedido. |\n\n## Idempotencia\n\nLas operaciones que mueven saldos o existencias (inventario, caja, cobros y pagos) aceptan el encabezado opcional `Idempotency-Key` (máximo 100 caracteres, vigente 24 horas por integración). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original con el encabezado `Idempotent-Replayed: true`. En esas solicitudes el encabezado viene incluido pero deshabilitado, con el valor `{{$guid}}`.\n\n## API v2\n\nLa carpeta **API v2** contiene los endpoints de la versión 2 (monedas y tasas de cambio, ventas y compras con moneda extranjera) y usa la variable `base_url_v2` (`https://api.filexpress.app/api/external/v2`) con la misma API Key. Todo lo demás permanece en la URL v1 (`base_url`). Se sugiere migrar a las rutas v2 disponibles antes del 30 de marzo de 2027; la ruta sin versión (`/api/external`) se retira el 1 de enero de 2027.\n\n## Modelo de permisos\n\nCada integración solo puede usar los grupos de endpoints (scopes) que se le asignaron en FileXpress. Cada solicitud de esta colección indica en su descripción el permiso requerido. Si se llama a un endpoint sin el permiso, la API responde `403`:\n\n```json\n{ \"status\": false, \"message\": \"This integration does not have the 'hr.employees' permission.\", \"required_scope\": \"hr.employees\" }\n```\n\nLos permisos explícitos nunca se otorgan por defecto, ni siquiera a integraciones existentes con acceso total: el administrador del negocio debe habilitarlos uno por uno. Los catálogos de referencia, `GET /branches` y `GET /taxes/branch/{id}` no requieren permiso.\n\n| Módulo | Permiso | Alcance | Explícito |\n|---|---|---|---|\n| Facturación | `sales` | Crear y consultar ventas (DTE). | No |\n| Facturación | `expenses` | Crear y consultar compras. | No |\n| Facturación | `currencies` | Consultar monedas activas y tasas de cambio (API v2). | No |\n| Facturación | `countries` | Consultar capacidades y catálogos de un país (API v2). | No |\n| Facturación | `customers` | Crear y consultar clientes. | No |\n| Facturación | `providers` | Crear y consultar proveedores. | No |\n| Facturación | `products` | Crear, consultar, actualizar y eliminar productos. | No |\n| Caja y puntos de venta | `branches.write` | Crear y editar puntos de venta. | Sí |\n| Caja y puntos de venta | `cash_register` | Consultar caja abierta y cortes. | Sí |\n| Caja y puntos de venta | `cash_register.operate` | Abrir caja, registrar movimientos y cerrar con arqueo. | Sí |\n| Inventario | `inventory.read` | Existencias, movimientos, lotes, alertas y transferencias. | Sí |\n| Inventario | `inventory.adjustments` | Registrar ajustes de inventario. | Sí |\n| Inventario | `inventory.transfers` | Crear, completar y cancelar transferencias. | Sí |\n| Precios y promociones | `pricing` | Consultar listas de precios y promociones, calcular promociones. | Sí |\n| Precios y promociones | `pricing.write` | Actualizar en lote los precios de una lista. | Sí |\n| Cuentas por cobrar y pagar | `receivables` | Facturas con saldo, resumen e historial de cobros. | Sí |\n| Cuentas por cobrar y pagar | `receivables.payments` | Registrar y revertir cobros. | Sí |\n| Cuentas por cobrar y pagar | `payables` | Compras con saldo, resumen e historial de pagos. | Sí |\n| Cuentas por cobrar y pagar | `payables.payments` | Registrar y revertir pagos a proveedores. | Sí |\n| Tesorería | `treasury` | Consultar bancos, cajas chicas y chequeras. | Sí |\n| Tesorería | `treasury.write` | Crear y editar bancos, cajas chicas y chequeras. | Sí |\n| Contabilidad | `accounting.accounts` | Catálogo de cuentas y períodos contables. | Sí |\n| Contabilidad | `accounting.journal_entries` | Consultar partidas y crear partidas en borrador. | Sí |\n| Contabilidad | `accounting.reports` | Estados financieros y reportes por centro de costo. | Sí |\n| Contabilidad | `accounting.cost_centers` | Consultar centros de costo y distribuciones. | Sí |\n| Contabilidad | `accounting.cost_centers.write` | Gestionar centros de costo y distribuciones. | Sí |\n| Contabilidad | `accounting.budgets` | Consultar presupuestos y presupuesto vs real. | Sí |\n| Contabilidad | `accounting.budgets.write` | Gestionar presupuestos, líneas y estado. | Sí |\n| Proyectos | `projects` | Consultar proyectos y su resumen financiero. | Sí |\n| Proyectos | `projects.write` | Crear y actualizar proyectos y vincular documentos. | Sí |\n| Recursos Humanos | `hr.employees` | Consultar empleados y puestos de trabajo. | Sí |\n| Recursos Humanos | `hr.employees.write` | Crear y actualizar empleados. | Sí |\n| Recursos Humanos | `hr.attendances` | Enviar y consultar marcaciones. | Sí |\n| Recursos Humanos | `hr.attendance_results` | Resultados de asistencia, resumen y aprobaciones de horas extra (consulta). | Sí |\n| Recursos Humanos | `hr.overtime.approve` | Aprobar o rechazar horas extra. | Sí |\n| Recursos Humanos | `hr.labor_rules` | Consultar reglas laborales y plantillas por país. | Sí |\n| Recursos Humanos | `hr.labor_rules.write` | Crear y editar reglas laborales. | Sí |\n| Recursos Humanos | `hr.schedules` | Consultar horarios y asignaciones. | Sí |\n| Recursos Humanos | `hr.schedules.write` | Crear, editar y eliminar horarios y asignaciones. | Sí |\n| Recursos Humanos | `hr.holidays` | Consultar feriados y asuetos. | Sí |\n| Recursos Humanos | `hr.holidays.write` | Gestionar asuetos y excluir feriados del país. | Sí |\n| Recursos Humanos | `hr.leave_requests` | Crear y consultar solicitudes de permiso. | Sí |\n| Recursos Humanos | `hr.payrolls` | Consultar planillas. | Sí |\n| Recursos Humanos | `hr.payrolls.write` | Asignar centros de costo a planillas. | Sí |\n\n## Soporte\n\nEscriba a soporte@filexpress.app indicando el nombre de su integración y el módulo involucrado.\n",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-API-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "Generales y catálogos",
      "description": "Estado del servicio, sucursales, impuestos por sucursal y catálogos de referencia (países, departamentos, municipios, actividades económicas, categorías, unidades de medida, formas de pago e incoterms). No requieren permiso.",
      "item": [
        {
          "name": "Listar actividades económicas",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/activities",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "activities"
              ]
            },
            "description": "Catálogo de actividades económicas (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/activities",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "activities"
                  ]
                },
                "description": "Catálogo de actividades económicas (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"code\": \"46900\",\n      \"name\": \"Venta al por mayor de otros productos\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar sucursales",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/branches",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "branches"
              ]
            },
            "description": "Sucursales del negocio de la integración con su código de establecimiento (`establishment_code`) y sus puntos de venta (el predeterminado primero). Úsalo para obtener el `branch_id` que piden la mayoría de endpoints. `code` es solo lectura: establecimiento + punto de venta predeterminado.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `403`: Integración sin el permiso requerido o desactivada."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/branches",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "branches"
                  ]
                },
                "description": "Sucursales del negocio de la integración con su código de establecimiento (`establishment_code`) y sus puntos de venta (el predeterminado primero). Úsalo para obtener el `branch_id` que piden la mayoría de endpoints. `code` es solo lectura: establecimiento + punto de venta predeterminado.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `403`: Integración sin el permiso requerido o desactivada."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Casa Matriz\",\n      \"code\": \"M001P001\",\n      \"establishment_code\": \"M001\",\n      \"points_of_sale\": [\n        {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"P001\",\n          \"name\": \"Caja principal\",\n          \"is_default\": true,\n          \"is_active\": true\n        },\n        {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"P002\",\n          \"name\": \"Caja 2\",\n          \"is_default\": false,\n          \"is_active\": true\n        }\n      ]\n    }\n  ]\n}"
            }
          ]
        },
        {
          "name": "Listar municipios",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/cities",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "cities"
              ]
            },
            "description": "Catálogo de municipios (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cities",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cities"
                  ]
                },
                "description": "Catálogo de municipios (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"San Salvador Centro\",\n      \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar países",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/countries",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "countries"
              ]
            },
            "description": "Catálogo de países (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/countries",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "countries"
                  ]
                },
                "description": "Catálogo de países (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"El Salvador\",\n      \"code\": \"SV\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Verificar estado del servicio",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "text/plain"
              }
            ],
            "url": {
              "raw": "{{base_url}}/health",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "health"
              ]
            },
            "description": "Comprueba que la API Externa está disponible. Responde el texto plano `Working` con código 200.\n\nPermiso requerido: ninguno (este endpoint no exige API Key)."
          },
          "response": [
            {
              "name": "200 Servicio disponible",
              "originalRequest": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "text/plain"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/health",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "health"
                  ]
                },
                "description": "Comprueba que la API Externa está disponible. Responde el texto plano `Working` con código 200.\n\nPermiso requerido: ninguno (este endpoint no exige API Key)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "text",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/html; charset=UTF-8"
                }
              ],
              "body": "Working"
            }
          ]
        },
        {
          "name": "Listar incoterms",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/incoterms",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "incoterms"
              ]
            },
            "description": "Catálogo de incoterms (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/incoterms",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "incoterms"
                  ]
                },
                "description": "Catálogo de incoterms (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"code\": \"FOB\",\n      \"name\": \"Free On Board\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar formas de pago",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/payment-methods",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "payment-methods"
              ]
            },
            "description": "Catálogo de formas de pago (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payment-methods",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payment-methods"
                  ]
                },
                "description": "Catálogo de formas de pago (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"code\": \"01\",\n      \"name\": \"Billetes y monedas\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar categorías de producto",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/product-categories",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "product-categories"
              ]
            },
            "description": "Catálogo de categorías de producto (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-categories",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-categories"
                  ]
                },
                "description": "Catálogo de categorías de producto (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Bebidas\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar unidades de medida",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/product-measurements",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "product-measurements"
              ]
            },
            "description": "Catálogo de unidades de medida (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-measurements",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-measurements"
                  ]
                },
                "description": "Catálogo de unidades de medida (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Unidad\",\n      \"code\": \"59\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar departamentos",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/states",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "states"
              ]
            },
            "description": "Catálogo de departamentos (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/states",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "states"
                  ]
                },
                "description": "Catálogo de departamentos (solo lectura).\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"San Salvador\",\n      \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar actividad",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/activities/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "activities",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{activity_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) actividad.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/activities/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "activities",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{activity_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) actividad.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/activities/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "activities",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{activity_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) actividad.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar municipio",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/cities/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "cities",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{city_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) municipio.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cities/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cities",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{city_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) municipio.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cities/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cities",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{city_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) municipio.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar país",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/countries/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "countries",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{country_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) país.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/countries/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "countries",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{country_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) país.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/countries/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "countries",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{country_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) país.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar categoría",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/product-categories/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "product-categories",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{product_category_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) categoría.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-categories/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-categories",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_category_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) categoría.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-categories/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-categories",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_category_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) categoría.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar unidad de medida",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/product-measurements/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "product-measurements",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{product_measurement_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) unidad de medida.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-measurements/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-measurements",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_measurement_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) unidad de medida.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/product-measurements/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "product-measurements",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_measurement_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) unidad de medida.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar departamento",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/states/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "states",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{state_id}}",
                  "description": "ID del recurso (UUID)"
                }
              ]
            },
            "description": "Detalle de un(a) departamento.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/states/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "states",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{state_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) departamento.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"...\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/states/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "states",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{state_id}}",
                      "description": "ID del recurso (UUID)"
                    }
                  ]
                },
                "description": "Detalle de un(a) departamento.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        },
        {
          "name": "Listar municipios de un departamento",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/cities/state/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "cities",
                "state",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{state_id}}",
                  "description": "ID del departamento"
                }
              ]
            },
            "description": "Filtra municipios por departamento.\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cities/state/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cities",
                    "state",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{state_id}}",
                      "description": "ID del departamento"
                    }
                  ]
                },
                "description": "Filtra municipios por departamento.\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"San Salvador Centro\",\n      \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar departamentos de un país",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/states/country/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "states",
                "country",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{country_id}}",
                  "description": "ID del país"
                }
              ]
            },
            "description": "Filtra departamentos por país.\n\nPermiso requerido: ninguno (basta con una API Key válida)."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/states/country/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "states",
                    "country",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{country_id}}",
                      "description": "ID del país"
                    }
                  ]
                },
                "description": "Filtra departamentos por país.\n\nPermiso requerido: ninguno (basta con una API Key válida)."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"San Salvador\",\n      \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
            }
          ]
        },
        {
          "name": "Listar impuestos de una sucursal",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/taxes/branch/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "taxes",
                "branch",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{branch_id}}",
                  "description": "ID de la sucursal"
                }
              ]
            },
            "description": "Impuestos activos del país de la sucursal. Envía sus IDs en `tax_ids` al crear o actualizar productos.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `404`: Recurso inexistente o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/taxes/branch/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "taxes",
                    "branch",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Impuestos activos del país de la sucursal. Envía sus IDs en `tax_ids` al crear o actualizar productos.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"IVA\",\n      \"number_code\": \"20\",\n      \"tax_type\": \"percentage\",\n      \"percent\": 0.13,\n      \"value\": 0,\n      \"is_default\": true,\n      \"document_types\": null,\n      \"country_code\": \"SV\"\n    },\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"FOVIAL\",\n      \"number_code\": \"D1\",\n      \"tax_type\": \"fixed_unit\",\n      \"percent\": 0,\n      \"value\": 0.2,\n      \"is_default\": false,\n      \"document_types\": null,\n      \"country_code\": \"SV\"\n    }\n  ]\n}"
            },
            {
              "name": "404 Recurso inexistente o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/taxes/branch/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "taxes",
                    "branch",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Impuestos activos del país de la sucursal. Envía sus IDs en `tax_ids` al crear o actualizar productos.\n\nPermiso requerido: ninguno (basta con una API Key válida).\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Facturación",
      "description": "Ventas (documentos tributarios electrónicos), compras, clientes, proveedores y productos.",
      "item": [
        {
          "name": "Ventas",
          "item": [
            {
              "name": "Listar ventas",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/sales?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "sales"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                    },
                    {
                      "key": "document_type",
                      "value": "fc",
                      "description": "(Opcional) Tipo de documento (fc, ccf, fex, nc, nd...).",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "PROCESADO",
                      "description": "(Opcional) Estado del documento (máx. 30 caracteres).",
                      "disabled": true
                    },
                    {
                      "key": "payment_status",
                      "value": "pending",
                      "description": "(Opcional) Estado de pago.",
                      "disabled": true
                    },
                    {
                      "key": "customer_id",
                      "value": "{{customer_id}}",
                      "description": "(Opcional) Filtra por cliente.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "100",
                      "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Ventas de una sucursal en un rango de hasta 93 días, para conciliar con un ERP.\n\nPermiso requerido: `sales`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `document_type` | string | No | Tipo de documento (fc, ccf, fex, nc, nd...). |\n| `status` | string | No | Estado del documento (máx. 30 caracteres). |\n| `payment_status` | string: `pending`, `partial`, `payed` | No | Estado de pago. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "document_type",
                          "value": "fc",
                          "description": "(Opcional) Tipo de documento (fc, ccf, fex, nc, nd...).",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "PROCESADO",
                          "description": "(Opcional) Estado del documento (máx. 30 caracteres).",
                          "disabled": true
                        },
                        {
                          "key": "payment_status",
                          "value": "pending",
                          "description": "(Opcional) Estado de pago.",
                          "disabled": true
                        },
                        {
                          "key": "customer_id",
                          "value": "{{customer_id}}",
                          "description": "(Opcional) Filtra por cliente.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "100",
                          "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Ventas de una sucursal en un rango de hasta 93 días, para conciliar con un ERP.\n\nPermiso requerido: `sales`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `document_type` | string | No | Tipo de documento (fc, ccf, fex, nc, nd...). |\n| `status` | string | No | Estado del documento (máx. 30 caracteres). |\n| `payment_status` | string: `pending`, `partial`, `payed` | No | Estado de pago. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n        \"control_number\": \"DTE-01-M001P001-000000000000001\",\n        \"document_type\": \"fc\",\n        \"status\": \"PROCESADO\",\n        \"issue_time\": \"2026-10-01T10:30:00-06:00\",\n        \"payment_status\": \"payed\",\n        \"is_credit\": false,\n        \"nullified\": false,\n        \"customer\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"name\": \"Razón Social S.A. de C.V.\"\n        },\n        \"totals\": {\n          \"sale_total\": 22.6,\n          \"sale_to_payment\": 22.6\n        }\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 100,\n      \"total\": 1\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación o rango mayor a 93 días",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "document_type",
                          "value": "fc",
                          "description": "(Opcional) Tipo de documento (fc, ccf, fex, nc, nd...).",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "PROCESADO",
                          "description": "(Opcional) Estado del documento (máx. 30 caracteres).",
                          "disabled": true
                        },
                        {
                          "key": "payment_status",
                          "value": "pending",
                          "description": "(Opcional) Estado de pago.",
                          "disabled": true
                        },
                        {
                          "key": "customer_id",
                          "value": "{{customer_id}}",
                          "description": "(Opcional) Filtra por cliente.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "100",
                          "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Ventas de una sucursal en un rango de hasta 93 días, para conciliar con un ERP.\n\nPermiso requerido: `sales`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `document_type` | string | No | Tipo de documento (fc, ccf, fex, nc, nd...). |\n| `status` | string | No | Estado del documento (máx. 30 caracteres). |\n| `payment_status` | string: `pending`, `partial`, `payed` | No | Estado de pago. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"The date range cannot exceed 93 days.\"\n}"
                }
              ]
            },
            {
              "name": "Crear venta",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/sales",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "sales"
                  ]
                },
                "description": "Emite un documento de venta. El sistema externo debe enviar los desgloses fiscales y totales calculados. El número de control usa el punto de venta del turno de caja de la venta, o `point_of_sale_id`, o el predeterminado de la sucursal. Un `point_of_sale_id` de otra sucursal o inactivo responde 422 y la venta no se transmite.\n\nPermiso requerido: `sales`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string: `fc`, `ccf`, `fex`, `nc`, `nd`, `nr`, `inv`, `cm`, `dm` | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array de object | Sí |  |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"point_of_sale_id\": \"{{point_of_sale_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"fc\",\n  \"date\": \"2026-10-01T10:00:00\",\n  \"observation\": \"Entrega en bodega central\",\n  \"cost_center_id\": \"{{cost_center_id}}\",\n  \"cost_center_distribution_id\": null,\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"payment_details\": [\n    {\n      \"code\": \"01\",\n      \"payment_method\": \"Efectivo\",\n      \"amount\": 22.6,\n      \"reference\": \"\"\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"sku\": \"PRD-001\",\n      \"name\": \"Producto A\",\n      \"quantity\": 2,\n      \"price_before_taxes\": 10,\n      \"sale_not_suject\": 0,\n      \"sale_exent\": 0,\n      \"sale_taxed\": 20,\n      \"subtotal\": 20,\n      \"discount\": 0,\n      \"type\": \"phisical\",\n      \"cost_center_id\": null,\n      \"cost_center_distribution_id\": null\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 20,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 20,\n    \"totalTax\": 2.6,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"freight\": 0,\n    \"insurance\": 0,\n    \"saleTotalToPayment\": 22.6\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Documento emitido",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "description": "Emite un documento de venta. El sistema externo debe enviar los desgloses fiscales y totales calculados. El número de control usa el punto de venta del turno de caja de la venta, o `point_of_sale_id`, o el predeterminado de la sucursal. Un `point_of_sale_id` de otra sucursal o inactivo responde 422 y la venta no se transmite.\n\nPermiso requerido: `sales`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string: `fc`, `ccf`, `fex`, `nc`, `nd`, `nr`, `inv`, `cm`, `dm` | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array de object | Sí |  |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"fc\",\n  \"date\": \"2026-10-01T10:00:00\",\n  \"observation\": \"Entrega en bodega central\",\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"payment_details\": [\n    {\n      \"code\": \"01\",\n      \"payment_method\": \"Efectivo\",\n      \"amount\": 22.6,\n      \"reference\": \"\"\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"sku\": \"PRD-001\",\n      \"name\": \"Producto A\",\n      \"quantity\": 2,\n      \"price_before_taxes\": 10.0,\n      \"sale_not_suject\": 0,\n      \"sale_exent\": 0,\n      \"sale_taxed\": 20.0,\n      \"subtotal\": 20.0,\n      \"discount\": 0,\n      \"type\": \"phisical\"\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 20.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 20.0,\n    \"totalTax\": 2.6,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"freight\": 0,\n    \"insurance\": 0,\n    \"saleTotalToPayment\": 22.6\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"message\": \"Invoice created successfully\",\n  \"data\": {\n    \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n    \"control_number\": \"DTE-01-M001P001-000000000000001\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-01 10:30:00\",\n    \"stamp\": \"2026A1B2C3D4E5F6\",\n    \"point_of_sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"establishment_code\": \"M001\",\n    \"point_of_sale_code\": \"P001\",\n    \"total\": 22.6\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "description": "Emite un documento de venta. El sistema externo debe enviar los desgloses fiscales y totales calculados. El número de control usa el punto de venta del turno de caja de la venta, o `point_of_sale_id`, o el predeterminado de la sucursal. Un `point_of_sale_id` de otra sucursal o inactivo responde 422 y la venta no se transmite.\n\nPermiso requerido: `sales`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string: `fc`, `ccf`, `fex`, `nc`, `nd`, `nr`, `inv`, `cm`, `dm` | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array de object | Sí |  |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"fc\",\n  \"date\": \"2026-10-01T10:00:00\",\n  \"observation\": \"Entrega en bodega central\",\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"payment_details\": [\n    {\n      \"code\": \"01\",\n      \"payment_method\": \"Efectivo\",\n      \"amount\": 22.6,\n      \"reference\": \"\"\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"sku\": \"PRD-001\",\n      \"name\": \"Producto A\",\n      \"quantity\": 2,\n      \"price_before_taxes\": 10.0,\n      \"sale_not_suject\": 0,\n      \"sale_exent\": 0,\n      \"sale_taxed\": 20.0,\n      \"subtotal\": 20.0,\n      \"discount\": 0,\n      \"type\": \"phisical\"\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 20.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 20.0,\n    \"totalTax\": 2.6,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"freight\": 0,\n    \"insurance\": 0,\n    \"saleTotalToPayment\": 22.6\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"branch_id\": [\n      \"The branch id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar venta",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/sales/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "sales",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{sale_id}}",
                      "description": "ID de la venta"
                    }
                  ]
                },
                "description": "Estado y detalle de una venta.\n\nPermiso requerido: `sales`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{sale_id}}",
                          "description": "ID de la venta"
                        }
                      ]
                    },
                    "description": "Estado y detalle de una venta.\n\nPermiso requerido: `sales`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"6F1E2D3C-...\",\n    \"control_number\": \"DTE-01-M001P001-000000000000001\",\n    \"document_type\": \"fc\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-01 10:30:00\",\n    \"stamp\": \"2026A1B2...\",\n    \"payment_status\": \"paid\",\n    \"is_credit\": false,\n    \"customer\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"legal_name\": \"Razón Social S.A. de C.V.\",\n      \"customer_name\": \"Nombre Comercial\"\n    },\n    \"totals\": {\n      \"sale_total\": 22.6,\n      \"sale_to_payment\": 22.6\n    },\n    \"products\": [\n      {\n        \"name\": \"Producto A\",\n        \"quantity\": 2,\n        \"individual_price\": 10.0,\n        \"subtotal\": 20.0\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/sales/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "sales",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{sale_id}}",
                          "description": "ID de la venta"
                        }
                      ]
                    },
                    "description": "Estado y detalle de una venta.\n\nPermiso requerido: `sales`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `sales` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Compras y gastos",
          "item": [
            {
              "name": "Registrar compra",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/expenses",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "expenses"
                  ]
                },
                "description": "Registra una compra de proveedor con desgloses fiscales calculados.\n\nPermiso requerido: `expenses`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string: `ccf`, `fse`, `ticket` | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-01\",\n  \"observation\": \"Compra de insumos\",\n  \"cost_center_id\": \"{{cost_center_id}}\",\n  \"cost_center_distribution_id\": null,\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-...\",\n  \"stamp\": \"2026XYZ...\",\n  \"products\": [\n    {\n      \"sku\": \"INS-001\",\n      \"name\": \"Insumo A\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 8,\n      \"expense_not_suject\": 0,\n      \"expense_exent\": 0,\n      \"expense_taxed\": 40,\n      \"subtotal\": 40,\n      \"cost_center_id\": null,\n      \"cost_center_distribution_id\": null\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 40,\n    \"charge_1\": 0,\n    \"charge_2\": 0,\n    \"expenseTotalTax\": 40,\n    \"totalRent\": 0,\n    \"totalTax\": 5.2,\n    \"totalRetein\": 0,\n    \"expenseTotalToPayment\": 45.2\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Compra registrada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/expenses",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "description": "Registra una compra de proveedor con desgloses fiscales calculados.\n\nPermiso requerido: `expenses`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string: `ccf`, `fse`, `ticket` | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-01\",\n  \"observation\": \"Compra de insumos\",\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-...\",\n  \"stamp\": \"2026XYZ...\",\n  \"products\": [\n    {\n      \"sku\": \"INS-001\",\n      \"name\": \"Insumo A\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 8.0,\n      \"expense_not_suject\": 0,\n      \"expense_exent\": 0,\n      \"expense_taxed\": 40.0,\n      \"subtotal\": 40.0\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 40.0,\n    \"charge_1\": 0,\n    \"charge_2\": 0,\n    \"expenseTotalTax\": 40.0,\n    \"totalRent\": 0,\n    \"totalTax\": 5.2,\n    \"totalRetein\": 0,\n    \"expenseTotalToPayment\": 45.2\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"message\": \"Expense created successfully\",\n  \"data\": {\n    \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"A1B2C3D4-...\",\n    \"control_number\": \"DTE-03-M001P001-000000000000123\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-01 10:00:00\",\n    \"total\": 45.2\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/expenses",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "description": "Registra una compra de proveedor con desgloses fiscales calculados.\n\nPermiso requerido: `expenses`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string: `ccf`, `fse`, `ticket` | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array de object | Sí |  |\n| `totals` | object | Sí |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-01\",\n  \"observation\": \"Compra de insumos\",\n  \"is_credit\": false,\n  \"credit_days\": 0,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-...\",\n  \"stamp\": \"2026XYZ...\",\n  \"products\": [\n    {\n      \"sku\": \"INS-001\",\n      \"name\": \"Insumo A\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 8.0,\n      \"expense_not_suject\": 0,\n      \"expense_exent\": 0,\n      \"expense_taxed\": 40.0,\n      \"subtotal\": 40.0\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 40.0,\n    \"charge_1\": 0,\n    \"charge_2\": 0,\n    \"expenseTotalTax\": 40.0,\n    \"totalRent\": 0,\n    \"totalTax\": 5.2,\n    \"totalRetein\": 0,\n    \"expenseTotalToPayment\": 45.2\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"branch_id\": [\n      \"The branch id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar compra",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/expenses/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "expenses",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{expense_id}}",
                      "description": "ID de la compra"
                    }
                  ]
                },
                "description": "Estado y detalle de una compra.\n\nPermiso requerido: `expenses`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/expenses/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "expenses",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{expense_id}}",
                          "description": "ID de la compra"
                        }
                      ]
                    },
                    "description": "Estado y detalle de una compra.\n\nPermiso requerido: `expenses`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"A1B2C3D4-...\",\n    \"control_number\": \"DTE-03-...\",\n    \"document_type\": \"ccf\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-01 10:00:00\",\n    \"payment_status\": \"pending\",\n    \"is_credit\": true,\n    \"provider\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n      \"provider_name\": \"Distribuidora XYZ\"\n    },\n    \"totals\": {\n      \"expense_total\": 45.2,\n      \"expense_to_payment\": 45.2\n    },\n    \"products\": [\n      {\n        \"sku\": \"INS-001\",\n        \"name\": \"Insumo A\",\n        \"quantity\": 5,\n        \"individual_price\": 8.0,\n        \"subtotal\": 40.0\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/expenses/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "expenses",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{expense_id}}",
                          "description": "ID de la compra"
                        }
                      ]
                    },
                    "description": "Estado y detalle de una compra.\n\nPermiso requerido: `expenses`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `expenses` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Clientes",
          "item": [
            {
              "name": "Crear cliente",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/customers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "customers"
                  ]
                },
                "description": "Crea un cliente. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `customer_name` | string | Sí |  |\n| `legal_name` | string | No |  |\n| `register_number` | string | No | NRC. |\n| `tax_number` | string | No | NIT. |\n| `document_type` | string | No | Código de tipo de documento (13 = DUI, 36 = NIT...). |\n| `document_number` | string | No |  |\n| `address` | string | Sí |  |\n| `country_id` | string (uuid) | Sí |  |\n| `state_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `city_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `activity_id` | string (uuid) | No |  |\n| `phone` | string | Sí |  |\n| `email` | string | Sí |  |\n| `business_type` | string: `non-business`, `natural`, `legal` | Sí | Tipo de cliente. |\n| `branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"customer_name\": \"Juan Pérez\",\n  \"legal_name\": \"Juan Antonio Pérez García\",\n  \"register_number\": \"12345-6\",\n  \"tax_number\": \"0614-000101-000-0\",\n  \"document_type\": \"13\",\n  \"document_number\": \"00000000-0\",\n  \"address\": \"Col. San Benito, Av. La Revolución #123\",\n  \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"7777-1234\",\n  \"email\": \"juan@example.com\",\n  \"business_type\": \"natural\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Cliente creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers"
                      ]
                    },
                    "description": "Crea un cliente. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `customer_name` | string | Sí |  |\n| `legal_name` | string | No |  |\n| `register_number` | string | No | NRC. |\n| `tax_number` | string | No | NIT. |\n| `document_type` | string | No | Código de tipo de documento (13 = DUI, 36 = NIT...). |\n| `document_number` | string | No |  |\n| `address` | string | Sí |  |\n| `country_id` | string (uuid) | Sí |  |\n| `state_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `city_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `activity_id` | string (uuid) | No |  |\n| `phone` | string | Sí |  |\n| `email` | string | Sí |  |\n| `business_type` | string: `non-business`, `natural`, `legal` | Sí | Tipo de cliente. |\n| `branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"customer_name\": \"Juan Pérez\",\n  \"legal_name\": \"Juan Antonio Pérez García\",\n  \"register_number\": \"12345-6\",\n  \"tax_number\": \"0614-000101-000-0\",\n  \"document_type\": \"13\",\n  \"document_number\": \"00000000-0\",\n  \"address\": \"Col. San Benito, Av. La Revolución #123\",\n  \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"7777-1234\",\n  \"email\": \"juan@example.com\",\n  \"business_type\": \"natural\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"customer_name\": \"Juan Pérez\",\n    \"legal_name\": \"Juan Antonio Pérez García\",\n    \"register_number\": \"12345-6\",\n    \"tax_number\": \"0614-000101-000-0\",\n    \"document_type\": \"13\",\n    \"document_number\": \"00000000-0\",\n    \"address\": \"Col. San Benito, Av. La Revolución #123\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"7777-1234\",\n    \"email\": \"juan@example.com\",\n    \"business_type\": \"natural\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Error de validación (formato heredado)",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers"
                      ]
                    },
                    "description": "Crea un cliente. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `customer_name` | string | Sí |  |\n| `legal_name` | string | No |  |\n| `register_number` | string | No | NRC. |\n| `tax_number` | string | No | NIT. |\n| `document_type` | string | No | Código de tipo de documento (13 = DUI, 36 = NIT...). |\n| `document_number` | string | No |  |\n| `address` | string | Sí |  |\n| `country_id` | string (uuid) | Sí |  |\n| `state_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `city_id` | string (uuid) | Sí (El Salvador) | Opcional si `country_id` es otro país. |\n| `state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `activity_id` | string (uuid) | No |  |\n| `phone` | string | Sí |  |\n| `email` | string | Sí |  |\n| `business_type` | string: `non-business`, `natural`, `legal` | Sí | Tipo de cliente. |\n| `branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"customer_name\": \"Juan Pérez\",\n  \"legal_name\": \"Juan Antonio Pérez García\",\n  \"register_number\": \"12345-6\",\n  \"tax_number\": \"0614-000101-000-0\",\n  \"document_type\": \"13\",\n  \"document_number\": \"00000000-0\",\n  \"address\": \"Col. San Benito, Av. La Revolución #123\",\n  \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"7777-1234\",\n  \"email\": \"juan@example.com\",\n  \"business_type\": \"natural\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": false,\n  \"message\": \"Validation Error.\",\n  \"data\": {\n    \"customer_name\": [\n      \"The customer name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear cliente (otro país)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/customers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "customers"
                  ]
                },
                "description": "Crea un cliente de un país distinto de El Salvador. Si `country_id` no es El Salvador, `state_id` y `city_id` son opcionales y `state_name` y `city_name` (texto libre, máximo 120 caracteres) son obligatorios. Para El Salvador siguen siendo obligatorios `state_id` y `city_id`. Lo mismo aplica a proveedores. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"customer_name\": \"Comercial Maya\",\n  \"legal_name\": \"Comercial Maya, S.A.\",\n  \"register_number\": null,\n  \"tax_number\": \"1234567-8\",\n  \"document_type\": \"37\",\n  \"document_number\": \"1234567-8\",\n  \"address\": \"6a Avenida 10-25, Zona 1\",\n  \"country_id\": \"{{country_id_gt}}\",\n  \"state_name\": \"Guatemala\",\n  \"city_name\": \"Ciudad de Guatemala\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"+502 2222-3333\",\n  \"email\": \"compras@comercialmaya.example\",\n  \"business_type\": \"legal\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Cliente creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers"
                      ]
                    },
                    "description": "Crea un cliente de un país distinto de El Salvador. Si `country_id` no es El Salvador, `state_id` y `city_id` son opcionales y `state_name` y `city_name` (texto libre, máximo 120 caracteres) son obligatorios. Para El Salvador siguen siendo obligatorios `state_id` y `city_id`. Lo mismo aplica a proveedores. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"customer_name\": \"Comercial Maya\",\n  \"legal_name\": \"Comercial Maya, S.A.\",\n  \"register_number\": null,\n  \"tax_number\": \"1234567-8\",\n  \"document_type\": \"37\",\n  \"document_number\": \"1234567-8\",\n  \"address\": \"6a Avenida 10-25, Zona 1\",\n  \"country_id\": \"{{country_id_gt}}\",\n  \"state_name\": \"Guatemala\",\n  \"city_name\": \"Ciudad de Guatemala\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"+502 2222-3333\",\n  \"email\": \"compras@comercialmaya.example\",\n  \"business_type\": \"legal\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"customer_name\": \"Comercial Maya\",\n    \"legal_name\": \"Comercial Maya, S.A.\",\n    \"register_number\": null,\n    \"tax_number\": \"1234567-8\",\n    \"document_type\": \"37\",\n    \"document_number\": \"1234567-8\",\n    \"address\": \"6a Avenida 10-25, Zona 1\",\n    \"country_id\": \"{{country_id_gt}}\",\n    \"state_id\": null,\n    \"city_id\": null,\n    \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"+502 2222-3333\",\n    \"email\": \"compras@comercialmaya.example\",\n    \"business_type\": \"legal\",\n    \"state_name\": \"Guatemala\",\n    \"city_name\": \"Ciudad de Guatemala\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Error de validación (formato heredado)",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers"
                      ]
                    },
                    "description": "Crea un cliente de un país distinto de El Salvador. Si `country_id` no es El Salvador, `state_id` y `city_id` son opcionales y `state_name` y `city_name` (texto libre, máximo 120 caracteres) son obligatorios. Para El Salvador siguen siendo obligatorios `state_id` y `city_id`. Lo mismo aplica a proveedores. Formato de respuesta heredado `{ success, data, message }`.\n\nPermiso requerido: `customers`",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"customer_name\": \"Comercial Maya\",\n  \"legal_name\": \"Comercial Maya, S.A.\",\n  \"register_number\": null,\n  \"tax_number\": \"1234567-8\",\n  \"document_type\": \"37\",\n  \"document_number\": \"1234567-8\",\n  \"address\": \"6a Avenida 10-25, Zona 1\",\n  \"country_id\": \"{{country_id_gt}}\",\n  \"state_name\": \"Guatemala\",\n  \"city_name\": \"Ciudad de Guatemala\",\n  \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"phone\": \"+502 2222-3333\",\n  \"email\": \"compras@comercialmaya.example\",\n  \"business_type\": \"legal\",\n  \"branch_id\": \"{{branch_id}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": false,\n  \"message\": \"Validation Error.\",\n  \"data\": {\n    \"customer_name\": [\n      \"The customer name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar cliente",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/customers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "customers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{customer_id}}",
                      "description": "ID del cliente"
                    }
                  ]
                },
                "description": "Detalle de un cliente.\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{customer_id}}",
                          "description": "ID del cliente"
                        }
                      ]
                    },
                    "description": "Detalle de un cliente.\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"customer_name\": \"Juan Pérez\",\n    \"legal_name\": \"Juan Antonio Pérez García\",\n    \"register_number\": \"12345-6\",\n    \"tax_number\": \"0614-000101-000-0\",\n    \"document_type\": \"13\",\n    \"document_number\": \"00000000-0\",\n    \"address\": \"Col. San Benito, Av. La Revolución #123\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"7777-1234\",\n    \"email\": \"juan@example.com\",\n    \"business_type\": \"natural\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{customer_id}}",
                          "description": "ID del cliente"
                        }
                      ]
                    },
                    "description": "Detalle de un cliente.\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Listar clientes de una sucursal",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/customers/branch/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "customers",
                    "branch",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Clientes activos de la sucursal (sin paginar).\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Clientes activos de la sucursal (sin paginar).\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"customer_name\": \"Juan Pérez\",\n      \"legal_name\": \"Juan Antonio Pérez García\",\n      \"register_number\": \"12345-6\",\n      \"tax_number\": \"0614-000101-000-0\",\n      \"document_type\": \"13\",\n      \"document_number\": \"00000000-0\",\n      \"address\": \"Col. San Benito, Av. La Revolución #123\",\n      \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"activity_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"phone\": \"7777-1234\",\n      \"email\": \"juan@example.com\",\n      \"business_type\": \"natural\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/customers/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "customers",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Clientes activos de la sucursal (sin paginar).\n\nPermiso requerido: `customers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `customers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Proveedores",
          "item": [
            {
              "name": "Crear proveedor",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/providers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "providers"
                  ]
                },
                "description": "Crea un proveedor. **El cuerpo va dentro de la clave `data`.**\n\nPermiso requerido: `providers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `data.provider_name` | string | Sí |  |\n| `data.legal_name` | string | No |  |\n| `data.register_number` | string | No |  |\n| `data.tax_number` | string | No |  |\n| `data.address` | string | Sí |  |\n| `data.country_id` | string (uuid) | Sí |  |\n| `data.state_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.city_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `data.city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `data.phone` | string | Sí |  |\n| `data.email` | string | Sí |  |\n| `data.business_type` | string: `natural`, `legal` | Sí | Tipo. |\n| `data.branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"data\": {\n    \"provider_name\": \"Distribuidora XYZ\",\n    \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n    \"register_number\": \"54321-0\",\n    \"tax_number\": \"0614-000000-000-0\",\n    \"address\": \"San Salvador\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"2222-3333\",\n    \"email\": \"ventas@xyz.com\",\n    \"business_type\": \"legal\",\n    \"branch_id\": \"{{branch_id}}\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Proveedor creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/providers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "providers"
                      ]
                    },
                    "description": "Crea un proveedor. **El cuerpo va dentro de la clave `data`.**\n\nPermiso requerido: `providers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `data.provider_name` | string | Sí |  |\n| `data.legal_name` | string | No |  |\n| `data.register_number` | string | No |  |\n| `data.tax_number` | string | No |  |\n| `data.address` | string | Sí |  |\n| `data.country_id` | string (uuid) | Sí |  |\n| `data.state_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.city_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `data.city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `data.phone` | string | Sí |  |\n| `data.email` | string | Sí |  |\n| `data.business_type` | string: `natural`, `legal` | Sí | Tipo. |\n| `data.branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"data\": {\n    \"provider_name\": \"Distribuidora XYZ\",\n    \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n    \"register_number\": \"54321-0\",\n    \"tax_number\": \"0614-000000-000-0\",\n    \"address\": \"San Salvador\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"2222-3333\",\n    \"email\": \"ventas@xyz.com\",\n    \"business_type\": \"legal\",\n    \"branch_id\": \"{{branch_id}}\"\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"provider_name\": \"Distribuidora XYZ\",\n    \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n    \"register_number\": \"54321-0\",\n    \"tax_number\": \"0614-000000-000-0\",\n    \"address\": \"San Salvador\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"2222-3333\",\n    \"email\": \"ventas@xyz.com\",\n    \"business_type\": \"legal\"\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Error de validación (formato heredado)",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/providers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "providers"
                      ]
                    },
                    "description": "Crea un proveedor. **El cuerpo va dentro de la clave `data`.**\n\nPermiso requerido: `providers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `data.provider_name` | string | Sí |  |\n| `data.legal_name` | string | No |  |\n| `data.register_number` | string | No |  |\n| `data.tax_number` | string | No |  |\n| `data.address` | string | Sí |  |\n| `data.country_id` | string (uuid) | Sí |  |\n| `data.state_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.city_id` | string (uuid) | Sí (El Salvador) | Opcional si `data.country_id` es otro país. |\n| `data.state_name` | string | Si el país no es El Salvador | Departamento o estado en texto libre (máximo 120). |\n| `data.city_name` | string | Si el país no es El Salvador | Ciudad o municipio en texto libre (máximo 120). |\n| `data.phone` | string | Sí |  |\n| `data.email` | string | Sí |  |\n| `data.business_type` | string: `natural`, `legal` | Sí | Tipo. |\n| `data.branch_id` | string (uuid) | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"data\": {\n    \"provider_name\": \"Distribuidora XYZ\",\n    \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n    \"register_number\": \"54321-0\",\n    \"tax_number\": \"0614-000000-000-0\",\n    \"address\": \"San Salvador\",\n    \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"phone\": \"2222-3333\",\n    \"email\": \"ventas@xyz.com\",\n    \"business_type\": \"legal\",\n    \"branch_id\": \"{{branch_id}}\"\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": false,\n  \"message\": \"Validation Error.\",\n  \"data\": {\n    \"data.provider_name\": [\n      \"The data.provider name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar proveedores de una sucursal",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/providers/branch/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "providers",
                    "branch",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Proveedores activos de la sucursal (sin paginar).\n\nPermiso requerido: `providers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/providers/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "providers",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Proveedores activos de la sucursal (sin paginar).\n\nPermiso requerido: `providers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"provider_name\": \"Distribuidora XYZ\",\n      \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n      \"register_number\": \"54321-0\",\n      \"tax_number\": \"0614-000000-000-0\",\n      \"address\": \"San Salvador\",\n      \"country_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"state_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"city_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"phone\": \"2222-3333\",\n      \"email\": \"ventas@xyz.com\",\n      \"business_type\": \"legal\"\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/providers/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "providers",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Proveedores activos de la sucursal (sin paginar).\n\nPermiso requerido: `providers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `providers` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Productos",
          "item": [
            {
              "name": "Crear producto",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/products",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "products"
                  ]
                },
                "description": "Crea un producto simple, con porciones o con receta.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Producto creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products"
                      ]
                    },
                    "description": "Crea un producto simple, con porciones o con receta.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Refresco 350ml\",\n    \"sku\": \"BEB-001\",\n    \"price_before_taxes\": 1.11,\n    \"cost\": 0.7,\n    \"tax_method\": \"is_taxed\",\n    \"composition_type\": \"simple\",\n    \"product_type\": \"phisical\",\n    \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"availability\": 100,\n    \"limit_availability\": 10,\n    \"taxes\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"name\": \"IVA\",\n        \"number_code\": \"20\",\n        \"tax_type\": \"percentage\",\n        \"percent\": 0.13\n      }\n    ]\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Error de validación (formato heredado)",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products"
                      ]
                    },
                    "description": "Crea un producto simple, con porciones o con receta.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Error de validación (formato heredado: responde 404).",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": false,\n  \"message\": \"Validation Error.\",\n  \"data\": {\n    \"name\": [\n      \"The name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar producto",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/products/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "products",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_id}}",
                      "description": "ID del producto"
                    }
                  ]
                },
                "description": "Detalle con porciones y componentes.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Detalle con porciones y componentes.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Refresco 350ml\",\n    \"sku\": \"BEB-001\",\n    \"price_before_taxes\": 1.11,\n    \"cost\": 0.7,\n    \"tax_method\": \"is_taxed\",\n    \"composition_type\": \"simple\",\n    \"product_type\": \"phisical\",\n    \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"availability\": 100,\n    \"limit_availability\": 10,\n    \"taxes\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"name\": \"IVA\",\n        \"number_code\": \"20\",\n        \"tax_type\": \"percentage\",\n        \"percent\": 0.13\n      }\n    ]\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Detalle con porciones y componentes.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Actualizar producto",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/products/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "products",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_id}}",
                      "description": "ID del producto"
                    }
                  ]
                },
                "description": "Mismos campos que la creación. Un cambio de `availability` genera un ajuste de inventario.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Producto actualizado",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Mismos campos que la creación. Un cambio de `availability` genera un ajuste de inventario.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Refresco 350ml\",\n    \"sku\": \"BEB-001\",\n    \"price_before_taxes\": 1.11,\n    \"cost\": 0.7,\n    \"tax_method\": \"is_taxed\",\n    \"composition_type\": \"simple\",\n    \"product_type\": \"phisical\",\n    \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"availability\": 100,\n    \"limit_availability\": 10,\n    \"taxes\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"name\": \"IVA\",\n        \"number_code\": \"20\",\n        \"tax_type\": \"percentage\",\n        \"percent\": 0.13\n      }\n    ]\n  },\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Mismos campos que la creación. Un cambio de `availability` genera un ajuste de inventario.\n\nPermiso requerido: `products`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `sku` | string | No |  |\n| `price_before_taxes` | number | Sí |  |\n| `cost` | number | No |  |\n| `tax_method` | string: `is_taxed`, `is_exent`, `is_not_subject` | Sí | Tratamiento de IVA. |\n| `composition_type` | string: `simple`, `with_portions`, `with_recipe` | Sí | Composición. |\n| `product_type` | string: `phisical`, `service`, `both` | Sí | Tipo. |\n| `product_category_id` | string (uuid) | Sí |  |\n| `product_measurement_id` | string (uuid) | Sí |  |\n| `branch_id` | string (uuid) | Sí |  |\n| `availability` | number | Sí | Existencia. |\n| `limit_availability` | number | Sí | Existencia mínima. |\n| `tax_ids` | array de string | No | Impuestos del producto (GET /taxes/branch/{branch_id}). En gravados envía al menos el IVA. En actualización: omitido = se conservan; [] = se quitan. |\n| `base_unit_quantity` | number | No | Requerido con porciones. |\n| `base_unit` | string | No | Requerido con porciones. |\n| `portions` | array de object | No |  |\n| `components` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Refresco 350ml\",\n  \"sku\": \"BEB-001\",\n  \"price_before_taxes\": 1.11,\n  \"cost\": 0.7,\n  \"tax_method\": \"is_taxed\",\n  \"composition_type\": \"simple\",\n  \"product_type\": \"phisical\",\n  \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"availability\": 100,\n  \"limit_availability\": 10,\n  \"tax_ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Eliminar producto",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/products/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "products",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{product_id}}",
                      "description": "ID del producto"
                    }
                  ]
                },
                "description": "Eliminación lógica.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Producto eliminado",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Eliminación lógica.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": [],\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{product_id}}",
                          "description": "ID del producto"
                        }
                      ]
                    },
                    "description": "Eliminación lógica.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Listar productos de una sucursal",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/products/branch/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "products",
                    "branch",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Productos activos con unidad, categoría y porciones.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Productos activos con unidad, categoría y porciones.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Refresco 350ml\",\n      \"sku\": \"BEB-001\",\n      \"price_before_taxes\": 1.11,\n      \"cost\": 0.7,\n      \"tax_method\": \"is_taxed\",\n      \"composition_type\": \"simple\",\n      \"product_type\": \"phisical\",\n      \"product_category_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"product_measurement_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"availability\": 100,\n      \"limit_availability\": 10,\n      \"taxes\": [\n        {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"name\": \"IVA\",\n          \"number_code\": \"20\",\n          \"tax_type\": \"percentage\",\n          \"percent\": 0.13\n        }\n      ]\n    }\n  ],\n  \"message\": \"Data retrieved successfully.\"\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/products/branch/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "products",
                        "branch",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Productos activos con unidad, categoría y porciones.\n\nPermiso requerido: `products`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `products` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "Inventario",
      "description": "Existencias, movimientos, lotes, alertas, ajustes y transferencias entre sucursales.",
      "item": [
        {
          "name": "Registrar ajuste",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/adjustments",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "adjustments"
              ]
            },
            "description": "Entrada (`in`) o salida (`out`) manual de inventario; devuelve la existencia actualizada.\n\nPermiso requerido: `inventory.adjustments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `product_id` | string (uuid) | Sí | Producto de esa sucursal. |\n| `type` | string: `in`, `out` | Sí | Entrada o salida. |\n| `quantity` | number | Sí |  |\n| `reason` | string | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `inventory.adjustments` o desactivada.\n- `404`: Sucursal o producto inexistente.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o existencia insuficiente.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"product_id\": \"{{product_id}}\",\n  \"type\": \"out\",\n  \"quantity\": 2,\n  \"reason\": \"Merma\",\n  \"notes\": \"Botellas dañadas\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Ajuste registrado",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/adjustments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "adjustments"
                  ]
                },
                "description": "Entrada (`in`) o salida (`out`) manual de inventario; devuelve la existencia actualizada.\n\nPermiso requerido: `inventory.adjustments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `product_id` | string (uuid) | Sí | Producto de esa sucursal. |\n| `type` | string: `in`, `out` | Sí | Entrada o salida. |\n| `quantity` | number | Sí |  |\n| `reason` | string | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `inventory.adjustments` o desactivada.\n- `404`: Sucursal o producto inexistente.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o existencia insuficiente.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"product_id\": \"{{product_id}}\",\n  \"type\": \"out\",\n  \"quantity\": 2,\n  \"reason\": \"Merma\",\n  \"notes\": \"Botellas dañadas\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"adjustment\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"product\": {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\"\n      },\n      \"type\": \"out\",\n      \"quantity\": 2,\n      \"unit_cost\": 0.7,\n      \"source\": \"adjustment\",\n      \"reason\": \"Merma\",\n      \"notes\": \"Botellas dañadas\",\n      \"branch_transfer_id\": null,\n      \"created_at\": \"2026-10-01T10:15:00-06:00\"\n    },\n    \"stock\": {\n      \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"sku\": \"BEB-001\",\n      \"barcode\": \"7401234567890\",\n      \"name\": \"Refresco 350ml\",\n      \"availability\": 6,\n      \"min_stock\": 10,\n      \"is_low_stock\": true,\n      \"unit_cost\": 0.7\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación o existencia insuficiente",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/adjustments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "adjustments"
                  ]
                },
                "description": "Entrada (`in`) o salida (`out`) manual de inventario; devuelve la existencia actualizada.\n\nPermiso requerido: `inventory.adjustments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `product_id` | string (uuid) | Sí | Producto de esa sucursal. |\n| `type` | string: `in`, `out` | Sí | Entrada o salida. |\n| `quantity` | number | Sí |  |\n| `reason` | string | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `inventory.adjustments` o desactivada.\n- `404`: Sucursal o producto inexistente.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o existencia insuficiente.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"product_id\": \"{{product_id}}\",\n  \"type\": \"out\",\n  \"quantity\": 2,\n  \"reason\": \"Merma\",\n  \"notes\": \"Botellas dañadas\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"type\": [\n      \"The selected type is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar alertas de inventario",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/alerts?branch_id={{branch_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "alerts"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                },
                {
                  "key": "days",
                  "value": "30",
                  "description": "(Opcional) Ventana de vencimiento (1-365, por defecto 30).",
                  "disabled": true
                }
              ]
            },
            "description": "Stock bajo (existencia <= mínimo), lotes por vencer en `days` días y lotes vencidos. Máximo 500 de cada tipo.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `days` | integer | No | Ventana de vencimiento (1-365, por defecto 30). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/alerts?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "alerts"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "days",
                      "value": "30",
                      "description": "(Opcional) Ventana de vencimiento (1-365, por defecto 30).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Stock bajo (existencia <= mínimo), lotes por vencer en `days` días y lotes vencidos. Máximo 500 de cada tipo.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `days` | integer | No | Ventana de vencimiento (1-365, por defecto 30). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"days\": 30,\n    \"low_stock\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"barcode\": \"7401234567890\",\n        \"name\": \"Refresco 350ml\",\n        \"availability\": 8,\n        \"min_stock\": 10,\n        \"is_low_stock\": true,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"expiring_batches\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"product\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"sku\": \"BEB-001\",\n          \"name\": \"Refresco 350ml\"\n        },\n        \"batch_number\": \"L-2026-09\",\n        \"expiration_date\": \"2026-10-20\",\n        \"days_to_expire\": 14,\n        \"quantity\": 48,\n        \"available_quantity\": 30,\n        \"is_expired\": false,\n        \"is_removed\": false\n      }\n    ],\n    \"expired_batches\": []\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/alerts?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "alerts"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "days",
                      "value": "30",
                      "description": "(Opcional) Ventana de vencimiento (1-365, por defecto 30).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Stock bajo (existencia <= mínimo), lotes por vencer en `days` días y lotes vencidos. Máximo 500 de cada tipo.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `days` | integer | No | Ventana de vencimiento (1-365, por defecto 30). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"days\": [\n      \"The days must not be greater than 365.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar lotes",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/batches?branch_id={{branch_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "batches"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                },
                {
                  "key": "product_id",
                  "value": "{{product_id}}",
                  "description": "(Opcional) Filtra por producto.",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "available",
                  "description": "(Opcional) `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos.",
                  "disabled": true
                },
                {
                  "key": "days",
                  "value": "30",
                  "description": "(Opcional) Ventana para `expiring` (1-365, por defecto 30).",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "50",
                  "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ]
            },
            "description": "Lotes de la sucursal ordenados por vencimiento, paginado.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `status` | string: `available`, `expiring`, `expired` | No | `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos. |\n| `days` | integer | No | Ventana para `expiring` (1-365, por defecto 30). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/batches?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "batches"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "product_id",
                      "value": "{{product_id}}",
                      "description": "(Opcional) Filtra por producto.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "available",
                      "description": "(Opcional) `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos.",
                      "disabled": true
                    },
                    {
                      "key": "days",
                      "value": "30",
                      "description": "(Opcional) Ventana para `expiring` (1-365, por defecto 30).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Lotes de la sucursal ordenados por vencimiento, paginado.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `status` | string: `available`, `expiring`, `expired` | No | `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos. |\n| `days` | integer | No | Ventana para `expiring` (1-365, por defecto 30). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"product\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"sku\": \"BEB-001\",\n          \"name\": \"Refresco 350ml\"\n        },\n        \"batch_number\": \"L-2026-09\",\n        \"expiration_date\": \"2026-10-20\",\n        \"days_to_expire\": 14,\n        \"quantity\": 48,\n        \"available_quantity\": 30,\n        \"is_expired\": false,\n        \"is_removed\": false\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/batches?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "batches"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "product_id",
                      "value": "{{product_id}}",
                      "description": "(Opcional) Filtra por producto.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "available",
                      "description": "(Opcional) `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos.",
                      "disabled": true
                    },
                    {
                      "key": "days",
                      "value": "30",
                      "description": "(Opcional) Ventana para `expiring` (1-365, por defecto 30).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Lotes de la sucursal ordenados por vencimiento, paginado.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `status` | string: `available`, `expiring`, `expired` | No | `available` con existencia, `expiring` por vencer en `days` días, `expired` vencidos. |\n| `days` | integer | No | Ventana para `expiring` (1-365, por defecto 30). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar movimientos de inventario",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/movements?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "movements"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                },
                {
                  "key": "start_date",
                  "value": "2026-10-01",
                  "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                },
                {
                  "key": "end_date",
                  "value": "2026-10-08",
                  "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                },
                {
                  "key": "product_id",
                  "value": "{{product_id}}",
                  "description": "(Opcional) Filtra por producto.",
                  "disabled": true
                },
                {
                  "key": "source",
                  "value": "adjustment",
                  "description": "(Opcional) Origen del movimiento.",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "100",
                  "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ]
            },
            "description": "Kardex de la sucursal en el rango (máximo 93 días), del más reciente al más antiguo. `source`: `adjustment`, `transfer`, `sale` o `purchase`.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `source` | string: `adjustment`, `transfer` | No | Origen del movimiento. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/movements?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "movements"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                    },
                    {
                      "key": "product_id",
                      "value": "{{product_id}}",
                      "description": "(Opcional) Filtra por producto.",
                      "disabled": true
                    },
                    {
                      "key": "source",
                      "value": "adjustment",
                      "description": "(Opcional) Origen del movimiento.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "100",
                      "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Kardex de la sucursal en el rango (máximo 93 días), del más reciente al más antiguo. `source`: `adjustment`, `transfer`, `sale` o `purchase`.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `source` | string: `adjustment`, `transfer` | No | Origen del movimiento. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"product\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"sku\": \"BEB-001\",\n          \"name\": \"Refresco 350ml\"\n        },\n        \"type\": \"out\",\n        \"quantity\": 2,\n        \"unit_cost\": 0.7,\n        \"source\": \"adjustment\",\n        \"reason\": \"Merma\",\n        \"notes\": \"Botellas dañadas\",\n        \"branch_transfer_id\": null,\n        \"created_at\": \"2026-10-01T10:15:00-06:00\"\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 100,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación o rango mayor a 93 días",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/movements?branch_id={{branch_id}}&start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "movements"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD). Rango máximo 93 días."
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                    },
                    {
                      "key": "product_id",
                      "value": "{{product_id}}",
                      "description": "(Opcional) Filtra por producto.",
                      "disabled": true
                    },
                    {
                      "key": "source",
                      "value": "adjustment",
                      "description": "(Opcional) Origen del movimiento.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "100",
                      "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Kardex de la sucursal en el rango (máximo 93 días), del más reciente al más antiguo. `source`: `adjustment`, `transfer`, `sale` o `purchase`.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). Rango máximo 93 días. |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `product_id` | string (uuid) | No | Filtra por producto. |\n| `source` | string: `adjustment`, `transfer` | No | Origen del movimiento. |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o rango mayor a 93 días."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"The date range cannot exceed 93 days.\"\n}"
            }
          ]
        },
        {
          "name": "Consultar existencias",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/stock?branch_id={{branch_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "stock"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                },
                {
                  "key": "search",
                  "value": "",
                  "description": "(Opcional) Busca por nombre, SKU o código de barras (máx. 100).",
                  "disabled": true
                },
                {
                  "key": "low_stock",
                  "value": "true",
                  "description": "(Opcional) 1 = solo productos en o bajo el mínimo.",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "50",
                  "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ]
            },
            "description": "Existencias de los productos físicos de una sucursal, paginado. `is_low_stock` indica existencia menor o igual al mínimo configurado (`min_stock` > 0).\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `search` | string | No | Busca por nombre, SKU o código de barras (máx. 100). |\n| `low_stock` | boolean | No | 1 = solo productos en o bajo el mínimo. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/stock?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "stock"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre, SKU o código de barras (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "low_stock",
                      "value": "true",
                      "description": "(Opcional) 1 = solo productos en o bajo el mínimo.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Existencias de los productos físicos de una sucursal, paginado. `is_low_stock` indica existencia menor o igual al mínimo configurado (`min_stock` > 0).\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `search` | string | No | Busca por nombre, SKU o código de barras (máx. 100). |\n| `low_stock` | boolean | No | 1 = solo productos en o bajo el mínimo. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"barcode\": \"7401234567890\",\n        \"name\": \"Refresco 350ml\",\n        \"availability\": 8,\n        \"min_stock\": 10,\n        \"is_low_stock\": true,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/stock?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "stock"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre, SKU o código de barras (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "low_stock",
                      "value": "true",
                      "description": "(Opcional) 1 = solo productos en o bajo el mínimo.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Existencias de los productos físicos de una sucursal, paginado. `is_low_stock` indica existencia menor o igual al mínimo configurado (`min_stock` > 0).\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `search` | string | No | Busca por nombre, SKU o código de barras (máx. 100). |\n| `low_stock` | boolean | No | 1 = solo productos en o bajo el mínimo. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"per_page\": [\n      \"The per page must not be greater than 200.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar transferencias",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/transfers",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "transfers"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "pending",
                  "description": "(Opcional) Estado.",
                  "disabled": true
                },
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Opcional) Sucursal de origen o destino.",
                  "disabled": true
                },
                {
                  "key": "start_date",
                  "value": "2026-10-01",
                  "description": "(Opcional) Desde (YYYY-MM-DD).",
                  "disabled": true
                },
                {
                  "key": "end_date",
                  "value": "2026-10-08",
                  "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "50",
                  "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ]
            },
            "description": "Transferencias entre sucursales del negocio, paginado. `branch_id` filtra por origen o destino.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `pending`, `completed`, `cancelled` | No | Estado. |\n| `branch_id` | string (uuid) | No | Sucursal de origen o destino. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers"
                  ],
                  "query": [
                    {
                      "key": "status",
                      "value": "pending",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Sucursal de origen o destino.",
                      "disabled": true
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Opcional) Desde (YYYY-MM-DD).",
                      "disabled": true
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Transferencias entre sucursales del negocio, paginado. `branch_id` filtra por origen o destino.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `pending`, `completed`, `cancelled` | No | Estado. |\n| `branch_id` | string (uuid) | No | Sucursal de origen o destino. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"reference_number\": \"TR-0042\",\n        \"status\": \"pending\",\n        \"origin_branch\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"name\": \"Casa Matriz\"\n        },\n        \"destination_branch\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"name\": \"Sucursal Centro\"\n        },\n        \"notes\": \"Reabastecimiento semanal\",\n        \"items\": [\n          {\n            \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n            \"sku\": \"BEB-001\",\n            \"name\": \"Refresco 350ml\",\n            \"quantity\": 24,\n            \"unit_cost\": 0.7\n          }\n        ],\n        \"total_cost\": 16.8,\n        \"created_at\": \"2026-10-01T09:00:00-06:00\",\n        \"transferred_at\": null\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers"
                  ],
                  "query": [
                    {
                      "key": "status",
                      "value": "pending",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Sucursal de origen o destino.",
                      "disabled": true
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Opcional) Desde (YYYY-MM-DD).",
                      "disabled": true
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Transferencias entre sucursales del negocio, paginado. `branch_id` filtra por origen o destino.\n\nPermiso requerido: `inventory.read`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `pending`, `completed`, `cancelled` | No | Estado. |\n| `branch_id` | string (uuid) | No | Sucursal de origen o destino. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Crear transferencia",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/transfers",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "transfers"
              ]
            },
            "description": "Crea una transferencia `pending`; con `complete: true` también la ejecuta (todo o nada).\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `origin_branch_id` | string (uuid) | Sí |  |\n| `destination_branch_id` | string (uuid) | Sí | Distinta de la de origen. |\n| `products` | array de object | Sí |  |\n| `notes` | string | No |  |\n| `reference_number` | string | No |  |\n| `complete` | boolean | No | true = crear y completar en la misma operación. |\n| `cost_center_id` | string | No | Centro de costo para la contabilización (opcional). Se usa si la transferencia se completa al crearse. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: Producto no encontrado en la sucursal origen.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"origin_branch_id\": \"{{branch_id}}\",\n  \"destination_branch_id\": \"{{destination_branch_id}}\",\n  \"products\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 24\n    }\n  ],\n  \"notes\": \"Reabastecimiento semanal\",\n  \"reference_number\": \"TR-0042\",\n  \"complete\": false,\n  \"cost_center_id\": null\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Transferencia creada",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers"
                  ]
                },
                "description": "Crea una transferencia `pending`; con `complete: true` también la ejecuta (todo o nada).\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `origin_branch_id` | string (uuid) | Sí |  |\n| `destination_branch_id` | string (uuid) | Sí | Distinta de la de origen. |\n| `products` | array de object | Sí |  |\n| `notes` | string | No |  |\n| `reference_number` | string | No |  |\n| `complete` | boolean | No | true = crear y completar en la misma operación. |\n| `cost_center_id` | string | No | Centro de costo para la contabilización (opcional). Se usa si la transferencia se completa al crearse. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: Producto no encontrado en la sucursal origen.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"origin_branch_id\": \"{{branch_id}}\",\n  \"destination_branch_id\": \"{{destination_branch_id}}\",\n  \"products\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 24\n    }\n  ],\n  \"notes\": \"Reabastecimiento semanal\",\n  \"reference_number\": \"TR-0042\",\n  \"complete\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"reference_number\": \"TR-0042\",\n    \"status\": \"pending\",\n    \"origin_branch\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Casa Matriz\"\n    },\n    \"destination_branch\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Sucursal Centro\"\n    },\n    \"notes\": \"Reabastecimiento semanal\",\n    \"items\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\",\n        \"quantity\": 24,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"total_cost\": 16.8,\n    \"created_at\": \"2026-10-01T09:00:00-06:00\",\n    \"transferred_at\": null\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers"
                  ]
                },
                "description": "Crea una transferencia `pending`; con `complete: true` también la ejecuta (todo o nada).\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `origin_branch_id` | string (uuid) | Sí |  |\n| `destination_branch_id` | string (uuid) | Sí | Distinta de la de origen. |\n| `products` | array de object | Sí |  |\n| `notes` | string | No |  |\n| `reference_number` | string | No |  |\n| `complete` | boolean | No | true = crear y completar en la misma operación. |\n| `cost_center_id` | string | No | Centro de costo para la contabilización (opcional). Se usa si la transferencia se completa al crearse. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: Producto no encontrado en la sucursal origen.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"origin_branch_id\": \"{{branch_id}}\",\n  \"destination_branch_id\": \"{{destination_branch_id}}\",\n  \"products\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 24\n    }\n  ],\n  \"notes\": \"Reabastecimiento semanal\",\n  \"reference_number\": \"TR-0042\",\n  \"complete\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"destination_branch_id\": [\n      \"The destination branch id field and origin branch id must be different.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Consultar transferencia",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/transfers/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "transfers",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{transfer_id}}",
                  "description": "ID de la transferencia"
                }
              ]
            },
            "description": "Detalle de una transferencia con sus productos.\n\nPermiso requerido: `inventory.read`\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Detalle de una transferencia con sus productos.\n\nPermiso requerido: `inventory.read`\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"reference_number\": \"TR-0042\",\n    \"status\": \"pending\",\n    \"origin_branch\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Casa Matriz\"\n    },\n    \"destination_branch\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Sucursal Centro\"\n    },\n    \"notes\": \"Reabastecimiento semanal\",\n    \"items\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\",\n        \"quantity\": 24,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"total_cost\": 16.8,\n    \"created_at\": \"2026-10-01T09:00:00-06:00\",\n    \"transferred_at\": null\n  }\n}"
            },
            {
              "name": "404 No encontrado o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Detalle de una transferencia con sus productos.\n\nPermiso requerido: `inventory.read`\n\n**Notas**\n\n- `403`: Integración sin el permiso `inventory.read` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Transfer not found\"\n}"
            }
          ]
        },
        {
          "name": "Cancelar transferencia",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/transfers/:id/cancel",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "transfers",
                ":id",
                "cancel"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{transfer_id}}",
                  "description": "ID de la transferencia"
                }
              ]
            },
            "description": "Cancela una transferencia `pending` (no mueve inventario).\n\nPermiso requerido: `inventory.transfers`\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id/cancel",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id",
                    "cancel"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Cancela una transferencia `pending` (no mueve inventario).\n\nPermiso requerido: `inventory.transfers`\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"reference_number\": \"TR-0042\",\n    \"status\": \"cancelled\",\n    \"origin_branch\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Casa Matriz\"\n    },\n    \"destination_branch\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Sucursal Centro\"\n    },\n    \"notes\": \"Reabastecimiento semanal\",\n    \"items\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\",\n        \"quantity\": 24,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"total_cost\": 16.8,\n    \"created_at\": \"2026-10-01T09:00:00-06:00\",\n    \"transferred_at\": null\n  }\n}"
            },
            {
              "name": "404 No encontrado o de otro negocio",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id/cancel",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id",
                    "cancel"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Cancela una transferencia `pending` (no mueve inventario).\n\nPermiso requerido: `inventory.transfers`\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Transfer not found\"\n}"
            }
          ]
        },
        {
          "name": "Completar transferencia",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
              }
            ],
            "url": {
              "raw": "{{base_url}}/inventory/transfers/:id/complete",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventory",
                "transfers",
                ":id",
                "complete"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{transfer_id}}",
                  "description": "ID de la transferencia"
                }
              ]
            },
            "description": "Descuenta la existencia en origen y la suma en destino. Solo transferencias `pending`.\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de costo de la transferencia (hoja y activo). Se guarda para trazabilidad. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Centro de costo inválido.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id/complete",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id",
                    "complete"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Descuenta la existencia en origen y la suma en destino. Solo transferencias `pending`.\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de costo de la transferencia (hoja y activo). Se guarda para trazabilidad. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Centro de costo inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"reference_number\": \"TR-0042\",\n    \"status\": \"completed\",\n    \"origin_branch\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Casa Matriz\"\n    },\n    \"destination_branch\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Sucursal Centro\"\n    },\n    \"notes\": \"Reabastecimiento semanal\",\n    \"items\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\",\n        \"quantity\": 24,\n        \"unit_cost\": 0.7\n      }\n    ],\n    \"total_cost\": 16.8,\n    \"created_at\": \"2026-10-01T09:00:00-06:00\",\n    \"transferred_at\": \"2026-10-01T15:30:00-06:00\"\n  }\n}"
            },
            {
              "name": "422 Centro de costo inválido",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/inventory/transfers/:id/complete",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "inventory",
                    "transfers",
                    ":id",
                    "complete"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{transfer_id}}",
                      "description": "ID de la transferencia"
                    }
                  ]
                },
                "description": "Descuenta la existencia en origen y la suma en destino. Solo transferencias `pending`.\n\nPermiso requerido: `inventory.transfers`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de costo de la transferencia (hoja y activo). Se guarda para trazabilidad. |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `400`: Operación no permitida (existencia insuficiente, estado inválido, producto no físico...).\n- `403`: Integración sin el permiso `inventory.transfers` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Centro de costo inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"El centro de costo no existe o no pertenece a esta empresa.\"\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Precios y promociones",
      "description": "Listas de precios, sincronización de precios y cálculo de promociones sobre un carrito.",
      "item": [
        {
          "name": "Listar listas de precios",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/pricing/price-lists?branch_id={{branch_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "pricing",
                "price-lists"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                }
              ]
            },
            "description": "Listas de precios de la sucursal (la predeterminada primero).\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    }
                  ]
                },
                "description": "Listas de precios de la sucursal (la predeterminada primero).\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Tienda en línea\",\n      \"description\": \"Precios web\",\n      \"is_default\": false,\n      \"products_count\": 120\n    }\n  ]\n}"
            },
            {
              "name": "404 No encontrado o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    }
                  ]
                },
                "description": "Listas de precios de la sucursal (la predeterminada primero).\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
            }
          ]
        },
        {
          "name": "Listar promociones",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/pricing/promotions?branch_id={{branch_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "pricing",
                "promotions"
              ],
              "query": [
                {
                  "key": "branch_id",
                  "value": "{{branch_id}}",
                  "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                },
                {
                  "key": "active_only",
                  "value": "true",
                  "description": "(Opcional) Solo promociones vigentes (por defecto true).",
                  "disabled": true
                }
              ]
            },
            "description": "Promociones de la sucursal. Por defecto solo las vigentes (`active_only=true`); con `false` devuelve todas por prioridad.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `active_only` | boolean | No | Solo promociones vigentes (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/promotions?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "promotions"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "active_only",
                      "value": "true",
                      "description": "(Opcional) Solo promociones vigentes (por defecto true).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Promociones de la sucursal. Por defecto solo las vigentes (`active_only=true`); con `false` devuelve todas por prioridad.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `active_only` | boolean | No | Solo promociones vigentes (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"2x1 en bebidas\",\n      \"description\": \"Fin de semana\",\n      \"discount_type\": \"percentage\",\n      \"discount_value\": 10.0,\n      \"combo_price\": null,\n      \"apply_on\": \"unit_price\",\n      \"min_quantity\": 1,\n      \"start_date\": \"2026-10-01\",\n      \"end_date\": \"2026-10-31\",\n      \"is_active\": true,\n      \"priority\": 10,\n      \"conditions\": [\n        {\n          \"type\": \"category\",\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n        }\n      ]\n    }\n  ]\n}"
            },
            {
              "name": "404 No encontrado o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/promotions?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "promotions"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "active_only",
                      "value": "true",
                      "description": "(Opcional) Solo promociones vigentes (por defecto true).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Promociones de la sucursal. Por defecto solo las vigentes (`active_only=true`); con `false` devuelve todas por prioridad.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `active_only` | boolean | No | Solo promociones vigentes (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
            }
          ]
        },
        {
          "name": "Evaluar promociones",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/pricing/promotions/evaluate",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "pricing",
                "promotions",
                "evaluate"
              ]
            },
            "description": "Calcula las promociones sobre un carrito con el mismo motor del POS, sin registrar nada.\n\nPermiso requerido: `pricing`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `items` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"items\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 2,\n      \"unit_price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 1,\n      \"unit_price\": 12.0\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/promotions/evaluate",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "promotions",
                    "evaluate"
                  ]
                },
                "description": "Calcula las promociones sobre un carrito con el mismo motor del POS, sin registrar nada.\n\nPermiso requerido: `pricing`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `items` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"items\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 2,\n      \"unit_price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 1,\n      \"unit_price\": 12.0\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"items\": [\n      {\n        \"product_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"quantity\": 2,\n        \"unit_price\": 1.25,\n        \"promo_discount\": 0.125,\n        \"promo_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"promo_name\": \"2x1 en bebidas\",\n        \"promo_type\": \"percentage\"\n      }\n    ],\n    \"order_discounts\": [\n      {\n        \"promo_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"promo_name\": \"Combo desayuno\",\n        \"promo_type\": \"combo\",\n        \"discount\": 1.0\n      }\n    ],\n    \"totals\": {\n      \"subtotal\": 14.5,\n      \"item_discounts\": 0.25,\n      \"order_discounts\": 1.0,\n      \"total\": 13.25\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/promotions/evaluate",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "promotions",
                    "evaluate"
                  ]
                },
                "description": "Calcula las promociones sobre un carrito con el mismo motor del POS, sin registrar nada.\n\nPermiso requerido: `pricing`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `items` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"items\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 2,\n      \"unit_price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"quantity\": 1,\n      \"unit_price\": 12.0\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"items\": [\n      \"The items field is required.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar precios de una lista",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/pricing/price-lists/:id/prices",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "pricing",
                "price-lists",
                ":id",
                "prices"
              ],
              "query": [
                {
                  "key": "search",
                  "value": "",
                  "description": "(Opcional) Busca por nombre o SKU (máx. 100).",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "100",
                  "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{price_list_id}}",
                  "description": "ID de la lista de precios"
                }
              ]
            },
            "description": "Precios por producto de la lista, paginado. `base_price` es el precio sin impuestos del producto.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `search` | string | No | Busca por nombre o SKU (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists/:id/prices",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists",
                    ":id",
                    "prices"
                  ],
                  "query": [
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre o SKU (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "100",
                      "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{price_list_id}}",
                      "description": "ID de la lista de precios"
                    }
                  ]
                },
                "description": "Precios por producto de la lista, paginado. `base_price` es el precio sin impuestos del producto.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `search` | string | No | Busca por nombre o SKU (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"price_list\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Tienda en línea\",\n      \"is_default\": false\n    },\n    \"data\": [\n      {\n        \"product_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"sku\": \"BEB-001\",\n        \"name\": \"Refresco 350ml\",\n        \"price\": 1.25,\n        \"base_price\": 1.11,\n        \"updated_at\": \"2026-10-01T08:00:00-06:00\"\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 100,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists/:id/prices",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists",
                    ":id",
                    "prices"
                  ],
                  "query": [
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre o SKU (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "100",
                      "description": "(Opcional) Resultados por página (1-500, por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{price_list_id}}",
                      "description": "ID de la lista de precios"
                    }
                  ]
                },
                "description": "Precios por producto de la lista, paginado. `base_price` es el precio sin impuestos del producto.\n\nPermiso requerido: `pricing`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `search` | string | No | Busca por nombre o SKU (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-500, por defecto 100). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"per_page\": [\n      \"The per page must not be greater than 500.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Sincronizar precios",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/pricing/price-lists/:id/prices",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "pricing",
                "price-lists",
                ":id",
                "prices"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{price_list_id}}",
                  "description": "ID de la lista de precios"
                }
              ]
            },
            "description": "Crea o actualiza en lote (hasta 1000) los precios de la lista.\n\nPermiso requerido: `pricing.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `prices` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"prices\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 2.5\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists/:id/prices",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists",
                    ":id",
                    "prices"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{price_list_id}}",
                      "description": "ID de la lista de precios"
                    }
                  ]
                },
                "description": "Crea o actualiza en lote (hasta 1000) los precios de la lista.\n\nPermiso requerido: `pricing.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `prices` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"prices\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 2.5\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"updated\": 2,\n    \"rejected\": [\n      \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n    ]\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/pricing/price-lists/:id/prices",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "pricing",
                    "price-lists",
                    ":id",
                    "prices"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{price_list_id}}",
                      "description": "ID de la lista de precios"
                    }
                  ]
                },
                "description": "Crea o actualiza en lote (hasta 1000) los precios de la lista.\n\nPermiso requerido: `pricing.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `prices` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `pricing.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"prices\": [\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 1.25\n    },\n    {\n      \"product_id\": \"{{product_id}}\",\n      \"price\": 2.5\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"prices.0.price\": [\n      \"The prices.0.price must be at least 0.\"\n    ]\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Caja y puntos de venta",
      "description": "Apertura, movimientos y cierre de caja con arqueo; alta y edición de puntos de venta.",
      "item": [
        {
          "name": "Caja",
          "item": [
            {
              "name": "Listar cortes de caja",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "status",
                      "value": "open",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Opcional) Desde (YYYY-MM-DD).",
                      "disabled": true
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Cajas de la sucursal (abiertas y cerradas) del ambiente activo, de la más reciente a la más antigua. Paginado.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `status` | string: `open`, `closed` | No | Estado. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "status",
                          "value": "open",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Opcional) Desde (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Cajas de la sucursal (abiertas y cerradas) del ambiente activo, de la más reciente a la más antigua. Paginado.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `status` | string: `open`, `closed` | No | Estado. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"point_of_sale\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"P001\",\n          \"name\": \"Caja principal\"\n        },\n        \"opened_by_user\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"name\": \"Ana Martínez\"\n        },\n        \"closed_by_user\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"name\": \"Luis Pérez\"\n        },\n        \"status\": \"closed\",\n        \"cashier\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"name\": \"Ana Martínez\"\n        },\n        \"opening_date\": \"2026-10-06T08:00:00-06:00\",\n        \"closing_date\": \"2026-10-06T18:00:00-06:00\",\n        \"opening_amount\": 100.0,\n        \"declared_amount\": 295.0,\n        \"difference_amount\": 0.0,\n        \"total_sales\": 410.0,\n        \"total_cash_sales\": 215.0,\n        \"total_card_sales\": 180.0,\n        \"total_other_sales\": 15.0,\n        \"total_expenses\": 20.0,\n        \"total_other_incomes\": 0.0,\n        \"notes\": null,\n        \"opened_by\": \"API: Mi POS\",\n        \"closed_by\": \"API: Mi POS\"\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "status",
                          "value": "open",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Opcional) Desde (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Hasta (YYYY-MM-DD), mayor o igual que start_date.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Cajas de la sucursal (abiertas y cerradas) del ambiente activo, de la más reciente a la más antigua. Paginado.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `status` | string: `open`, `closed` | No | Estado. |\n| `start_date` | string (date) | No | Desde (YYYY-MM-DD). |\n| `end_date` | string (date) | No | Hasta (YYYY-MM-DD), mayor o igual que start_date. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar caja",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cash_register_id}}",
                      "description": "ID de la caja"
                    }
                  ]
                },
                "description": "Detalle de una caja con su resumen y sus movimientos manuales.\n\nPermiso requerido: `cash_register`\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Detalle de una caja con su resumen y sus movimientos manuales.\n\nPermiso requerido: `cash_register`\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"point_of_sale\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"code\": \"P001\",\n      \"name\": \"Caja principal\"\n    },\n    \"opened_by_user\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"closed_by_user\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Luis Pérez\"\n    },\n    \"status\": \"closed\",\n    \"cashier\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"opening_date\": \"2026-10-06T08:00:00-06:00\",\n    \"closing_date\": \"2026-10-06T18:00:00-06:00\",\n    \"opening_amount\": 100.0,\n    \"declared_amount\": 295.0,\n    \"difference_amount\": 0.0,\n    \"total_sales\": 410.0,\n    \"total_cash_sales\": 215.0,\n    \"total_card_sales\": 180.0,\n    \"total_other_sales\": 15.0,\n    \"total_expenses\": 20.0,\n    \"total_other_incomes\": 0.0,\n    \"notes\": null,\n    \"opened_by\": \"API: Mi POS\",\n    \"closed_by\": \"API: Mi POS\",\n    \"summary\": {\n      \"total_sales\": 410.0,\n      \"total_cash\": 215.0,\n      \"total_card\": 180.0,\n      \"total_other\": 15.0,\n      \"total_expenses\": 20.0,\n      \"more_income\": 0.0,\n      \"sales_count\": 37,\n      \"cash_movements\": 1,\n      \"expected_cash\": 295.0\n    },\n    \"movements\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"type\": \"expense\",\n        \"amount\": 20.0,\n        \"description\": \"Compra de hielo\",\n        \"reference\": \"REC-12\",\n        \"sale_id\": null,\n        \"created_by\": \"API: Mi POS\",\n        \"created_at\": \"2026-10-06T12:30:00-06:00\"\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Detalle de una caja con su resumen y sus movimientos manuales.\n\nPermiso requerido: `cash_register`\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Cash register not found\"\n}"
                }
              ]
            },
            {
              "name": "Consultar caja abierta",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers/current?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers",
                    "current"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "point_of_sale_id",
                      "value": "{{point_of_sale_id}}",
                      "description": "(Opcional) Punto de venta. Si se omite, el turno abierto más reciente de la sucursal.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Caja abierta de la sucursal (o del punto de venta indicado) con su resumen en vivo. Si no hay caja abierta, `data` es `null`.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Si se omite, el turno abierto más reciente de la sucursal. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/current?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        "current"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "point_of_sale_id",
                          "value": "{{point_of_sale_id}}",
                          "description": "(Opcional) Punto de venta. Si se omite, el turno abierto más reciente de la sucursal.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Caja abierta de la sucursal (o del punto de venta indicado) con su resumen en vivo. Si no hay caja abierta, `data` es `null`.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Si se omite, el turno abierto más reciente de la sucursal. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"point_of_sale\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"code\": \"P001\",\n      \"name\": \"Caja principal\"\n    },\n    \"opened_by_user\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"closed_by_user\": null,\n    \"status\": \"open\",\n    \"cashier\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"opening_date\": \"2026-10-06T08:00:00-06:00\",\n    \"closing_date\": null,\n    \"opening_amount\": 100.0,\n    \"declared_amount\": null,\n    \"difference_amount\": null,\n    \"total_sales\": null,\n    \"total_cash_sales\": null,\n    \"total_card_sales\": null,\n    \"total_other_sales\": null,\n    \"total_expenses\": null,\n    \"total_other_incomes\": null,\n    \"notes\": null,\n    \"opened_by\": \"API: Mi POS\",\n    \"closed_by\": null,\n    \"summary\": {\n      \"total_sales\": 410.0,\n      \"total_cash\": 215.0,\n      \"total_card\": 180.0,\n      \"total_other\": 15.0,\n      \"total_expenses\": 20.0,\n      \"more_income\": 0.0,\n      \"sales_count\": 37,\n      \"cash_movements\": 1,\n      \"expected_cash\": 295.0\n    }\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/current?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        "current"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "point_of_sale_id",
                          "value": "{{point_of_sale_id}}",
                          "description": "(Opcional) Punto de venta. Si se omite, el turno abierto más reciente de la sucursal.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Caja abierta de la sucursal (o del punto de venta indicado) con su resumen en vivo. Si no hay caja abierta, `data` es `null`.\n\nPermiso requerido: `cash_register`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Si se omite, el turno abierto más reciente de la sucursal. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `cash_register` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
                }
              ]
            },
            {
              "name": "Abrir caja",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers/open",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers",
                    "open"
                  ]
                },
                "description": "Abre la caja de la sucursal para un cajero (`user_id`, usuario de FileXpress con acceso a la sucursal). Un turno abierto por punto de venta: `point_of_sale_id` es obligatorio si la sucursal tiene más de un punto de venta activo. `user_id` queda como quien abrió (`opened_by_user`).\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `user_id` | string (uuid) | Sí | Cajero: usuario de FileXpress con acceso a la sucursal. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Obligatorio si la sucursal tiene más de uno activo. |\n| `opening_amount` | number | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Ya hay una caja abierta o conflicto de idempotencia.\n- `422`: Validación, punto de venta o cajero inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"user_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"point_of_sale_id\": \"{{point_of_sale_id}}\",\n  \"opening_amount\": 100.0,\n  \"notes\": \"Turno mañana\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Caja abierta",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/open",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        "open"
                      ]
                    },
                    "description": "Abre la caja de la sucursal para un cajero (`user_id`, usuario de FileXpress con acceso a la sucursal). Un turno abierto por punto de venta: `point_of_sale_id` es obligatorio si la sucursal tiene más de un punto de venta activo. `user_id` queda como quien abrió (`opened_by_user`).\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `user_id` | string (uuid) | Sí | Cajero: usuario de FileXpress con acceso a la sucursal. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Obligatorio si la sucursal tiene más de uno activo. |\n| `opening_amount` | number | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Ya hay una caja abierta o conflicto de idempotencia.\n- `422`: Validación, punto de venta o cajero inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"user_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"point_of_sale_id\": \"{{point_of_sale_id}}\",\n  \"opening_amount\": 100.0,\n  \"notes\": \"Turno mañana\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"point_of_sale\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"code\": \"P001\",\n      \"name\": \"Caja principal\"\n    },\n    \"opened_by_user\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"closed_by_user\": null,\n    \"status\": \"open\",\n    \"cashier\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"opening_date\": \"2026-10-06T08:00:00-06:00\",\n    \"closing_date\": null,\n    \"opening_amount\": 100.0,\n    \"declared_amount\": null,\n    \"difference_amount\": null,\n    \"total_sales\": null,\n    \"total_cash_sales\": null,\n    \"total_card_sales\": null,\n    \"total_other_sales\": null,\n    \"total_expenses\": null,\n    \"total_other_incomes\": null,\n    \"notes\": null,\n    \"opened_by\": \"API: Mi POS\",\n    \"closed_by\": null\n  }\n}"
                },
                {
                  "name": "422 Validación, punto de venta o cajero inválido",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/open",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        "open"
                      ]
                    },
                    "description": "Abre la caja de la sucursal para un cajero (`user_id`, usuario de FileXpress con acceso a la sucursal). Un turno abierto por punto de venta: `point_of_sale_id` es obligatorio si la sucursal tiene más de un punto de venta activo. `user_id` queda como quien abrió (`opened_by_user`).\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `user_id` | string (uuid) | Sí | Cajero: usuario de FileXpress con acceso a la sucursal. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta. Obligatorio si la sucursal tiene más de uno activo. |\n| `opening_amount` | number | Sí |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Ya hay una caja abierta o conflicto de idempotencia.\n- `422`: Validación, punto de venta o cajero inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"user_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"point_of_sale_id\": \"{{point_of_sale_id}}\",\n  \"opening_amount\": 100.0,\n  \"notes\": \"Turno mañana\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"The user does not exist or has no access to this branch.\"\n}"
                }
              ]
            },
            {
              "name": "Cerrar caja",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers/:id/close",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers",
                    ":id",
                    "close"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cash_register_id}}",
                      "description": "ID de la caja"
                    }
                  ]
                },
                "description": "Cierra la caja con el efectivo declarado y calcula la diferencia contra lo esperado. Registra como quien cerró (`closed_by_user`) al `user_id` enviado o, si se omite, al cajero del turno.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `declared_amount` | number | Sí | Efectivo contado. |\n| `user_id` | string (uuid) | No | Usuario que cierra (con acceso a la sucursal). Por defecto, el cajero del turno. |\n| `notes` | string | No |  |\n| `cash_count_breakdown` | object | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja ya cerrada o conflicto de idempotencia.\n- `422`: Validación, arqueo que no cuadra o usuario sin acceso.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"declared_amount\": 295.0,\n  \"user_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"notes\": \"Sin novedades\",\n  \"cash_count_breakdown\": {\n    \"bills\": {\n      \"hundred\": 0,\n      \"fifty\": 0,\n      \"twenty\": 12,\n      \"ten\": 5,\n      \"five\": 0,\n      \"one\": 0\n    },\n    \"coins\": {\n      \"quarter\": 20,\n      \"dime\": 0,\n      \"nickel\": 0,\n      \"penny\": 0\n    },\n    \"total\": 295.0\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Caja cerrada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id/close",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id",
                        "close"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Cierra la caja con el efectivo declarado y calcula la diferencia contra lo esperado. Registra como quien cerró (`closed_by_user`) al `user_id` enviado o, si se omite, al cajero del turno.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `declared_amount` | number | Sí | Efectivo contado. |\n| `user_id` | string (uuid) | No | Usuario que cierra (con acceso a la sucursal). Por defecto, el cajero del turno. |\n| `notes` | string | No |  |\n| `cash_count_breakdown` | object | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja ya cerrada o conflicto de idempotencia.\n- `422`: Validación, arqueo que no cuadra o usuario sin acceso.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"declared_amount\": 295.0,\n  \"user_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"notes\": \"Sin novedades\",\n  \"cash_count_breakdown\": {\n    \"bills\": {\n      \"hundred\": 0,\n      \"fifty\": 0,\n      \"twenty\": 12,\n      \"ten\": 5,\n      \"five\": 0,\n      \"one\": 0\n    },\n    \"coins\": {\n      \"quarter\": 20,\n      \"dime\": 0,\n      \"nickel\": 0,\n      \"penny\": 0\n    },\n    \"total\": 295.0\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"point_of_sale\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"code\": \"P001\",\n      \"name\": \"Caja principal\"\n    },\n    \"opened_by_user\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"closed_by_user\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Luis Pérez\"\n    },\n    \"status\": \"closed\",\n    \"cashier\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Ana Martínez\"\n    },\n    \"opening_date\": \"2026-10-06T08:00:00-06:00\",\n    \"closing_date\": \"2026-10-06T18:00:00-06:00\",\n    \"opening_amount\": 100.0,\n    \"declared_amount\": 295.0,\n    \"difference_amount\": 0.0,\n    \"total_sales\": 410.0,\n    \"total_cash_sales\": 215.0,\n    \"total_card_sales\": 180.0,\n    \"total_other_sales\": 15.0,\n    \"total_expenses\": 20.0,\n    \"total_other_incomes\": 0.0,\n    \"notes\": null,\n    \"opened_by\": \"API: Mi POS\",\n    \"closed_by\": \"API: Mi POS\"\n  }\n}"
                },
                {
                  "name": "422 Validación, arqueo que no cuadra o usuario sin acceso",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id/close",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id",
                        "close"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Cierra la caja con el efectivo declarado y calcula la diferencia contra lo esperado. Registra como quien cerró (`closed_by_user`) al `user_id` enviado o, si se omite, al cajero del turno.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `declared_amount` | number | Sí | Efectivo contado. |\n| `user_id` | string (uuid) | No | Usuario que cierra (con acceso a la sucursal). Por defecto, el cajero del turno. |\n| `notes` | string | No |  |\n| `cash_count_breakdown` | object | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja ya cerrada o conflicto de idempotencia.\n- `422`: Validación, arqueo que no cuadra o usuario sin acceso.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"declared_amount\": 295.0,\n  \"user_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"notes\": \"Sin novedades\",\n  \"cash_count_breakdown\": {\n    \"bills\": {\n      \"hundred\": 0,\n      \"fifty\": 0,\n      \"twenty\": 12,\n      \"ten\": 5,\n      \"five\": 0,\n      \"one\": 0\n    },\n    \"coins\": {\n      \"quarter\": 20,\n      \"dime\": 0,\n      \"nickel\": 0,\n      \"penny\": 0\n    },\n    \"total\": 295.0\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"The cash count breakdown total does not match the declared amount.\"\n}"
                }
              ]
            },
            {
              "name": "Registrar movimiento",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/cash-registers/:id/movements",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "cash-registers",
                    ":id",
                    "movements"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cash_register_id}}",
                      "description": "ID de la caja"
                    }
                  ]
                },
                "description": "Ingreso (`income`) o gasto (`expense`) de efectivo en una caja abierta. Devuelve el resumen actualizado.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `income`, `expense` | Sí | Tipo. |\n| `amount` | number | Sí |  |\n| `description` | string | Sí |  |\n| `reference` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja no abierta o conflicto de idempotencia.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"expense\",\n  \"amount\": 20.0,\n  \"description\": \"Compra de hielo\",\n  \"reference\": \"REC-12\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Movimiento registrado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id/movements",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id",
                        "movements"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Ingreso (`income`) o gasto (`expense`) de efectivo en una caja abierta. Devuelve el resumen actualizado.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `income`, `expense` | Sí | Tipo. |\n| `amount` | number | Sí |  |\n| `description` | string | Sí |  |\n| `reference` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja no abierta o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"type\": \"expense\",\n  \"amount\": 20.0,\n  \"description\": \"Compra de hielo\",\n  \"reference\": \"REC-12\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"type\": \"expense\",\n    \"amount\": 20.0,\n    \"description\": \"Compra de hielo\",\n    \"reference\": \"REC-12\",\n    \"summary\": {\n      \"total_sales\": 410.0,\n      \"total_cash\": 215.0,\n      \"total_card\": 180.0,\n      \"total_other\": 15.0,\n      \"total_expenses\": 20.0,\n      \"more_income\": 0.0,\n      \"sales_count\": 37,\n      \"cash_movements\": 1,\n      \"expected_cash\": 295.0\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/cash-registers/:id/movements",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "cash-registers",
                        ":id",
                        "movements"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cash_register_id}}",
                          "description": "ID de la caja"
                        }
                      ]
                    },
                    "description": "Ingreso (`income`) o gasto (`expense`) de efectivo en una caja abierta. Devuelve el resumen actualizado.\n\nPermiso requerido: `cash_register.operate`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `income`, `expense` | Sí | Tipo. |\n| `amount` | number | Sí |  |\n| `description` | string | Sí |  |\n| `reference` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `cash_register.operate` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Caja no abierta o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"type\": \"expense\",\n  \"amount\": 20.0,\n  \"description\": \"Compra de hielo\",\n  \"reference\": \"REC-12\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"amount\": [\n      \"The amount must be at least 0.01.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Puntos de venta",
          "item": [
            {
              "name": "Editar punto de venta",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/points-of-sale/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "points-of-sale",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{point_of_sale_id}}",
                      "description": "ID del punto de venta"
                    }
                  ]
                },
                "description": "Cambia el nombre o activa/desactiva el punto de venta. El código no cambia; los documentos emitidos no se modifican.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `is_active` | boolean | No | false para desactivar (no aplica al predeterminado ni con turno abierto). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: No se puede desactivar el predeterminado ni uno con turno abierto.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"is_active\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/points-of-sale/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "points-of-sale",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{point_of_sale_id}}",
                          "description": "ID del punto de venta"
                        }
                      ]
                    },
                    "description": "Cambia el nombre o activa/desactiva el punto de venta. El código no cambia; los documentos emitidos no se modifican.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `is_active` | boolean | No | false para desactivar (no aplica al predeterminado ni con turno abierto). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: No se puede desactivar el predeterminado ni uno con turno abierto.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"code\": \"P002\",\n    \"name\": \"Caja 2\",\n    \"is_default\": false,\n    \"is_active\": false,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"current_session\": null,\n    \"last_session\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"status\": \"closed\",\n      \"opening_date\": \"2026-10-08T08:00:00.000000Z\",\n      \"closing_date\": \"2026-10-08T18:00:00.000000Z\",\n      \"opened_by_user\": {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"name\": \"Ana Martínez\"\n      },\n      \"closed_by_user\": {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"name\": \"Luis Pérez\"\n      }\n    }\n  }\n}"
                },
                {
                  "name": "422 No se puede desactivar el predeterminado ni uno con turno abierto",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/points-of-sale/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "points-of-sale",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{point_of_sale_id}}",
                          "description": "ID del punto de venta"
                        }
                      ]
                    },
                    "description": "Cambia el nombre o activa/desactiva el punto de venta. El código no cambia; los documentos emitidos no se modifican.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `is_active` | boolean | No | false para desactivar (no aplica al predeterminado ni con turno abierto). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: No se puede desactivar el predeterminado ni uno con turno abierto.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Errores de validación\",\n  \"errors\": {\n    \"is_active\": [\n      \"No se puede desactivar el punto de venta predeterminado.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear punto de venta",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/branches/:id/points-of-sale",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "branches",
                    ":id",
                    "points-of-sale"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{branch_id}}",
                      "description": "ID de la sucursal"
                    }
                  ]
                },
                "description": "Crea un punto de venta en la sucursal con su numeración propia (empieza en 1) para cada tipo de DTE del año en curso.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en la sucursal. |\n| `name` | string | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Código inválido o duplicado.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"code\": \"P002\",\n  \"name\": \"Caja 2\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Punto de venta creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/branches/:id/points-of-sale",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "branches",
                        ":id",
                        "points-of-sale"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Crea un punto de venta en la sucursal con su numeración propia (empieza en 1) para cada tipo de DTE del año en curso.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en la sucursal. |\n| `name` | string | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Código inválido o duplicado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"P002\",\n  \"name\": \"Caja 2\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"branch_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"code\": \"P002\",\n    \"name\": \"Caja 2\",\n    \"is_default\": false,\n    \"is_active\": true,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"current_session\": null,\n    \"last_session\": null\n  }\n}"
                },
                {
                  "name": "422 Código inválido o duplicado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/branches/:id/points-of-sale",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "branches",
                        ":id",
                        "points-of-sale"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{branch_id}}",
                          "description": "ID de la sucursal"
                        }
                      ]
                    },
                    "description": "Crea un punto de venta en la sucursal con su numeración propia (empieza en 1) para cada tipo de DTE del año en curso.\n\nPermiso requerido: `branches.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en la sucursal. |\n| `name` | string | Sí |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `branches.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Código inválido o duplicado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"P002\",\n  \"name\": \"Caja 2\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Errores de validación\",\n  \"errors\": {\n    \"code\": [\n      \"Ya existe un punto de venta con ese código en la sucursal.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "Cuentas por cobrar y pagar",
      "description": "Saldos pendientes, resúmenes vigente/vencido, registro y reversión de cobros y pagos.",
      "item": [
        {
          "name": "Cuentas por cobrar",
          "item": [
            {
              "name": "Listar facturas pendientes",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/receivables?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "receivables"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "customer_id",
                      "value": "{{customer_id}}",
                      "description": "(Opcional) Filtra por cliente.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Facturas (CCF, FC, FEX) procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "customer_id",
                          "value": "{{customer_id}}",
                          "description": "(Opcional) Filtra por cliente.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Facturas (CCF, FC, FEX) procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n        \"document_type\": \"ccf\",\n        \"issue_date\": \"2026-09-01\",\n        \"due_date\": \"2026-10-01\",\n        \"days_overdue\": 5,\n        \"customer_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"customer_name\": \"Grupo ABC S.A. de C.V.\",\n        \"total_amount\": 1130.0,\n        \"amount_paid\": 500.0,\n        \"pending_amount\": 630.0,\n        \"payment_status\": \"partial\"\n      }\n    ],\n    \"total_pending\": 630.0\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "customer_id",
                          "value": "{{customer_id}}",
                          "description": "(Opcional) Filtra por cliente.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Facturas (CCF, FC, FEX) procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"branch_id\": [\n      \"The branch id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Registrar cobro",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/receivables/payments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "receivables",
                    "payments"
                  ]
                },
                "description": "Aplica un cobro por factura (`allocations`) o repartido de la factura más antigua a la más reciente; todo o nada. Si se indica `bank_id` se registra el depósito (GET /treasury/banks); con `petty_cash_id` (solo efectivo, excluyente con `bank_id`) el cobro ingresa a esa caja chica. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `customer_id` | string (uuid) | No | Cliente (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica que recibe el cobro (GET /treasury/petty-cashes). Solo con método efectivo y sin bank_id. |\n| `allocations` | array de object | No | Monto por factura (o usa customer_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: Factura o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"petty_cash_id\": null,\n  \"cost_center_id\": null,\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Cobro parcial\",\n  \"allocations\": [\n    {\n      \"sale_id\": \"{{sale_id}}\",\n      \"amount\": 300\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Cobro aplicado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "payments"
                      ]
                    },
                    "description": "Aplica un cobro por factura (`allocations`) o repartido de la factura más antigua a la más reciente; todo o nada. Si se indica `bank_id` se registra el depósito (GET /treasury/banks); con `petty_cash_id` (solo efectivo, excluyente con `bank_id`) el cobro ingresa a esa caja chica. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `customer_id` | string (uuid) | No | Cliente (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica que recibe el cobro (GET /treasury/petty-cashes). Solo con método efectivo y sin bank_id. |\n| `allocations` | array de object | No | Monto por factura (o usa customer_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: Factura o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Cobro parcial\",\n  \"allocations\": [\n    {\n      \"sale_id\": \"{{sale_id}}\",\n      \"amount\": 300.0\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"payments\": [\n      {\n        \"payment_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n        \"amount\": 300.0,\n        \"pending_amount\": 330.0,\n        \"payment_status\": \"partial\"\n      }\n    ],\n    \"total_applied\": 300.0\n  }\n}"
                },
                {
                  "name": "422 Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "payments"
                      ]
                    },
                    "description": "Aplica un cobro por factura (`allocations`) o repartido de la factura más antigua a la más reciente; todo o nada. Si se indica `bank_id` se registra el depósito (GET /treasury/banks); con `petty_cash_id` (solo efectivo, excluyente con `bank_id`) el cobro ingresa a esa caja chica. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `customer_id` | string (uuid) | No | Cliente (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica que recibe el cobro (GET /treasury/petty-cashes). Solo con método efectivo y sin bank_id. |\n| `allocations` | array de object | No | Monto por factura (o usa customer_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: Factura o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Cobro parcial\",\n  \"allocations\": [\n    {\n      \"sale_id\": \"{{sale_id}}\",\n      \"amount\": 300.0\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"The amount exceeds the customer pending balance.\"\n}"
                }
              ]
            },
            {
              "name": "Obtener resumen de cuentas por cobrar",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/receivables/summary?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "receivables",
                    "summary"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    }
                  ]
                },
                "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de facturas.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/summary?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        }
                      ]
                    },
                    "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de facturas.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"total\": 1630.0,\n    \"current\": 1000.0,\n    \"overdue\": 630.0,\n    \"current_count\": 2,\n    \"overdue_count\": 1\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/summary?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        }
                      ]
                    },
                    "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de facturas.\n\nPermiso requerido: `receivables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
                }
              ]
            },
            {
              "name": "Listar cobros de una venta",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/receivables/:saleId/payments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "receivables",
                    ":saleId",
                    "payments"
                  ],
                  "variable": [
                    {
                      "key": "saleId",
                      "value": "{{sale_id}}",
                      "description": "ID de la factura"
                    }
                  ]
                },
                "description": "Cobros de una factura, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `receivables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/:saleId/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        ":saleId",
                        "payments"
                      ],
                      "variable": [
                        {
                          "key": "saleId",
                          "value": "{{sale_id}}",
                          "description": "ID de la factura"
                        }
                      ]
                    },
                    "description": "Cobros de una factura, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `receivables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"amount\": 500.0,\n      \"pay_date\": \"2026-09-15 10:00:00\",\n      \"reference\": \"TRF-88231\",\n      \"status\": \"applied\",\n      \"payment_method_name\": \"Transferencia\",\n      \"bank_name\": \"Banco Agrícola\"\n    }\n  ]\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/:saleId/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        ":saleId",
                        "payments"
                      ],
                      "variable": [
                        {
                          "key": "saleId",
                          "value": "{{sale_id}}",
                          "description": "ID de la factura"
                        }
                      ]
                    },
                    "description": "Cobros de una factura, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `receivables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `receivables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Invoice not found\"\n}"
                }
              ]
            },
            {
              "name": "Revertir cobro",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/receivables/payments/:paymentId/reverse",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "receivables",
                    "payments",
                    ":paymentId",
                    "reverse"
                  ],
                  "variable": [
                    {
                      "key": "paymentId",
                      "value": "{{receivable_payment_id}}",
                      "description": "ID del cobro"
                    }
                  ]
                },
                "description": "Revierte un cobro aplicado y recalcula el estado de pago de la factura.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Cobro ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/payments/:paymentId/reverse",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "payments",
                        ":paymentId",
                        "reverse"
                      ],
                      "variable": [
                        {
                          "key": "paymentId",
                          "value": "{{receivable_payment_id}}",
                          "description": "ID del cobro"
                        }
                      ]
                    },
                    "description": "Revierte un cobro aplicado y recalcula el estado de pago de la factura.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Cobro ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"reversed_payment\": {\n      \"payment_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"original_amount\": 300.0,\n      \"reversal_reason\": \"Pago duplicado\",\n      \"reversed_at\": \"2026-10-06T16:00:00-06:00\"\n    },\n    \"sale_info\": {\n      \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n      \"total_amount\": 1130.0,\n      \"total_paid\": 500.0,\n      \"pending_amount\": 630.0,\n      \"payment_status\": \"partial\"\n    },\n    \"accounting\": {\n      \"action\": \"reversed\",\n      \"journal_entry_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"entry_code\": \"DIA-000145\",\n      \"status\": \"PROCESADA\"\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/receivables/payments/:paymentId/reverse",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "receivables",
                        "payments",
                        ":paymentId",
                        "reverse"
                      ],
                      "variable": [
                        {
                          "key": "paymentId",
                          "value": "{{receivable_payment_id}}",
                          "description": "ID del cobro"
                        }
                      ]
                    },
                    "description": "Revierte un cobro aplicado y recalcula el estado de pago de la factura.\n\nPermiso requerido: `receivables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `receivables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Cobro ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"reason\": [\n      \"The reason must not be greater than 500 characters.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Cuentas por pagar",
          "item": [
            {
              "name": "Listar compras pendientes",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payables?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payables"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    },
                    {
                      "key": "provider_id",
                      "value": "{{provider_id}}",
                      "description": "(Opcional) Filtra por proveedor.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Compras procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `provider_id` | string (uuid) | No | Filtra por proveedor. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "provider_id",
                          "value": "{{provider_id}}",
                          "description": "(Opcional) Filtra por proveedor.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Compras procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `provider_id` | string (uuid) | No | Filtra por proveedor. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"generation_code\": \"A1B2C3D4-0000-4C5D-9E6F-0A1B2C3D4E5F\",\n        \"document_type\": \"ccf\",\n        \"issue_date\": \"2026-09-05\",\n        \"due_date\": \"2026-10-05\",\n        \"days_overdue\": 1,\n        \"provider_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"provider_name\": \"Distribuidora XYZ S.A. de C.V.\",\n        \"total_amount\": 452.0,\n        \"amount_paid\": 0,\n        \"pending_amount\": 452.0,\n        \"payment_status\": \"pending\"\n      }\n    ],\n    \"total_pending\": 452.0\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        },
                        {
                          "key": "provider_id",
                          "value": "{{provider_id}}",
                          "description": "(Opcional) Filtra por proveedor.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Compras procesadas con saldo pendiente de la sucursal, de la más antigua a la más reciente.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n| `provider_id` | string (uuid) | No | Filtra por proveedor. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"branch_id\": [\n      \"The branch id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Registrar pago",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payables/payments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payables",
                    "payments"
                  ]
                },
                "description": "Aplica un pago por compra (`allocations`) o repartido de la compra más antigua a la más reciente; todo o nada. Según el método de pago se afecta el banco (`bank_id`), la caja chica (`petty_cash_id`) o la chequera (`checkbook_id` + `check_number`); obtén sus IDs en Tesorería. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `provider_id` | string (uuid) | No | Proveedor (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica (GET /treasury/petty-cashes). |\n| `checkbook_id` | string (uuid) | No | Chequera (GET /treasury/checkbooks). |\n| `check_number` | string | No |  |\n| `allocations` | array de object | No | Monto por compra (o usa provider_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: Compra o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"petty_cash_id\": null,\n  \"cost_center_id\": null,\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Pago parcial\",\n  \"allocations\": [\n    {\n      \"expense_id\": \"{{expense_id}}\",\n      \"amount\": 300\n    }\n  ],\n  \"checkbook_id\": \"{{checkbook_id}}\",\n  \"check_number\": \"000123\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Pago aplicado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "payments"
                      ]
                    },
                    "description": "Aplica un pago por compra (`allocations`) o repartido de la compra más antigua a la más reciente; todo o nada. Según el método de pago se afecta el banco (`bank_id`), la caja chica (`petty_cash_id`) o la chequera (`checkbook_id` + `check_number`); obtén sus IDs en Tesorería. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `provider_id` | string (uuid) | No | Proveedor (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica (GET /treasury/petty-cashes). |\n| `checkbook_id` | string (uuid) | No | Chequera (GET /treasury/checkbooks). |\n| `check_number` | string | No |  |\n| `allocations` | array de object | No | Monto por compra (o usa provider_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: Compra o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Pago parcial\",\n  \"allocations\": [\n    {\n      \"expense_id\": \"{{expense_id}}\",\n      \"amount\": 300.0\n    }\n  ],\n  \"checkbook_id\": \"{{checkbook_id}}\",\n  \"check_number\": \"000123\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"payments\": [\n      {\n        \"payment_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"generation_code\": \"A1B2C3D4-0000-4C5D-9E6F-0A1B2C3D4E5F\",\n        \"amount\": 300.0,\n        \"pending_amount\": 152.0,\n        \"payment_status\": \"partial\"\n      }\n    ],\n    \"total_applied\": 300.0\n  }\n}"
                },
                {
                  "name": "422 Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "payments"
                      ]
                    },
                    "description": "Aplica un pago por compra (`allocations`) o repartido de la compra más antigua a la más reciente; todo o nada. Según el método de pago se afecta el banco (`bank_id`), la caja chica (`petty_cash_id`) o la chequera (`checkbook_id` + `check_number`); obtén sus IDs en Tesorería. `cost_center_id` (opcional) toma por defecto el del documento.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `payment_method_id` | string (uuid) | Sí | Forma de pago (GET /payment-methods). |\n| `bank_id` | string (uuid) | No | Banco (GET /treasury/banks). |\n| `cost_center_id` | string (uuid) | No | Centro de costo del pago (hoja y activo; GET /accounting/cost-centers). Si falta, el del documento. Solo pasa a líneas de cuentas de resultado al contabilizar. |\n| `reference_number` | string | No | Referencia (máx. 255). |\n| `payment_date` | string (date) | Sí | Fecha del pago. |\n| `notes` | string | No | Notas (máx. 500). |\n| `branch_id` | string (uuid) | No | Requerido junto con el tercero (modo automático). |\n| `amount` | number | No | Monto a repartir (modo automático). |\n| `provider_id` | string (uuid) | No | Proveedor (modo automático, en lugar de allocations). |\n| `petty_cash_id` | string (uuid) | No | Caja chica (GET /treasury/petty-cashes). |\n| `checkbook_id` | string (uuid) | No | Chequera (GET /treasury/checkbooks). |\n| `check_number` | string | No |  |\n| `allocations` | array de object | No | Monto por compra (o usa provider_id). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: Compra o sucursal inexistente o de otro negocio.\n- `409`: Conflicto de idempotencia.\n- `422`: Validación, método/banco inexistente, monto mayor al saldo o documento ya pagado.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"reference_number\": \"TRF-88231\",\n  \"payment_date\": \"2026-10-06\",\n  \"notes\": \"Pago parcial\",\n  \"allocations\": [\n    {\n      \"expense_id\": \"{{expense_id}}\",\n      \"amount\": 300.0\n    }\n  ],\n  \"checkbook_id\": \"{{checkbook_id}}\",\n  \"check_number\": \"000123\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"The amount exceeds the provider pending balance.\"\n}"
                }
              ]
            },
            {
              "name": "Obtener resumen de cuentas por pagar",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payables/summary?branch_id={{branch_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payables",
                    "summary"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                    }
                  ]
                },
                "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de compras.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/summary?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        }
                      ]
                    },
                    "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de compras.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"total\": 1630.0,\n    \"current\": 1000.0,\n    \"overdue\": 630.0,\n    \"current_count\": 2,\n    \"overdue_count\": 1\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/summary?branch_id={{branch_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal (GET /branches). De otro negocio -> 404."
                        }
                      ]
                    },
                    "description": "Saldo pendiente total de la sucursal separado en vigente y vencido, con conteo de compras.\n\nPermiso requerido: `payables`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal (GET /branches). De otro negocio -> 404. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
                }
              ]
            },
            {
              "name": "Listar pagos de una compra",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payables/:expenseId/payments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payables",
                    ":expenseId",
                    "payments"
                  ],
                  "variable": [
                    {
                      "key": "expenseId",
                      "value": "{{expense_id}}",
                      "description": "ID de la compra"
                    }
                  ]
                },
                "description": "Pagos de una compra, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `payables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/:expenseId/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        ":expenseId",
                        "payments"
                      ],
                      "variable": [
                        {
                          "key": "expenseId",
                          "value": "{{expense_id}}",
                          "description": "ID de la compra"
                        }
                      ]
                    },
                    "description": "Pagos de una compra, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `payables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"amount\": 500.0,\n      \"pay_date\": \"2026-09-15 10:00:00\",\n      \"reference\": \"TRF-88231\",\n      \"status\": \"applied\",\n      \"payment_method_name\": \"Transferencia\",\n      \"bank_name\": \"Banco Agrícola\"\n    }\n  ]\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/:expenseId/payments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        ":expenseId",
                        "payments"
                      ],
                      "variable": [
                        {
                          "key": "expenseId",
                          "value": "{{expense_id}}",
                          "description": "ID de la compra"
                        }
                      ]
                    },
                    "description": "Pagos de una compra, incluidos los revertidos (`status: reversed`).\n\nPermiso requerido: `payables`\n\n**Notas**\n\n- `403`: Integración sin el permiso `payables` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Bill not found\"\n}"
                }
              ]
            },
            {
              "name": "Revertir pago",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/payables/payments/:paymentId/reverse",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "payables",
                    "payments",
                    ":paymentId",
                    "reverse"
                  ],
                  "variable": [
                    {
                      "key": "paymentId",
                      "value": "{{payable_payment_id}}",
                      "description": "ID del pago"
                    }
                  ]
                },
                "description": "Revierte un pago aplicado y recalcula el estado de pago de la compra.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Pago ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/payments/:paymentId/reverse",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "payments",
                        ":paymentId",
                        "reverse"
                      ],
                      "variable": [
                        {
                          "key": "paymentId",
                          "value": "{{payable_payment_id}}",
                          "description": "ID del pago"
                        }
                      ]
                    },
                    "description": "Revierte un pago aplicado y recalcula el estado de pago de la compra.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Pago ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"reversed_payment\": {\n      \"payment_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"original_amount\": 300.0,\n      \"reversal_reason\": \"Pago duplicado\",\n      \"reversed_at\": \"2026-10-06T16:00:00-06:00\"\n    },\n    \"expense_info\": {\n      \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"generation_code\": \"A1B2C3D4-0000-4C5D-9E6F-0A1B2C3D4E5F\",\n      \"total_amount\": 452.0,\n      \"total_paid\": 0,\n      \"pending_amount\": 452.0,\n      \"payment_status\": \"pending\"\n    },\n    \"accounting\": {\n      \"action\": \"reversed\",\n      \"journal_entry_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"entry_code\": \"DIA-000145\",\n      \"status\": \"PROCESADA\"\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/payables/payments/:paymentId/reverse",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "payables",
                        "payments",
                        ":paymentId",
                        "reverse"
                      ],
                      "variable": [
                        {
                          "key": "paymentId",
                          "value": "{{payable_payment_id}}",
                          "description": "ID del pago"
                        }
                      ]
                    },
                    "description": "Revierte un pago aplicado y recalcula el estado de pago de la compra.\n\nPermiso requerido: `payables.payments`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `reason` | string | No | Motivo (por defecto \"Payment reversed\"). |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `payables.payments` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `409`: Pago ya revertido o conflicto de idempotencia.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"reason\": \"Pago duplicado\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"reason\": [\n      \"The reason must not be greater than 500 characters.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "Tesorería",
      "description": "Bancos, cajas chicas y chequeras. Sus identificadores se usan al registrar cobros y pagos.",
      "item": [
        {
          "name": "Listar bancos",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/banks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "banks"
              ]
            },
            "description": "Cuentas bancarias del negocio. Su `id` es el `bank_id` de los cobros y pagos.\n\nPermiso requerido: `treasury`\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/banks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "banks"
                  ]
                },
                "description": "Cuentas bancarias del negocio. Su `id` es el `bank_id` de los cobros y pagos.\n\nPermiso requerido: `treasury`\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Banco Agrícola\",\n      \"account_number\": \"3000123456\",\n      \"balance\": 15230.45\n    }\n  ]\n}"
            }
          ]
        },
        {
          "name": "Crear banco",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/banks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "banks"
              ]
            },
            "description": "Crea una cuenta bancaria. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `account_number` | string | Sí | No puede repetirse. |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Banco Agrícola - Corriente\",\n  \"account_number\": \"0012-345678-9\",\n  \"balance\": 15000.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Banco creado",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/banks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "banks"
                  ]
                },
                "description": "Crea una cuenta bancaria. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `account_number` | string | Sí | No puede repetirse. |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Banco Agrícola - Corriente\",\n  \"account_number\": \"0012-345678-9\",\n  \"balance\": 15000.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Banco Agrícola - Corriente\",\n    \"account_number\": \"0012-345678-9\",\n    \"balance\": 15000.0,\n    \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  }\n}"
            },
            {
              "name": "422 Validación o cuenta contable inválida",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/banks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "banks"
                  ]
                },
                "description": "Crea una cuenta bancaria. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `account_number` | string | Sí | No puede repetirse. |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Banco Agrícola - Corriente\",\n  \"account_number\": \"0012-345678-9\",\n  \"balance\": 15000.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"account_id\": \"La cuenta 1101 tiene subcuentas; use una cuenta de movimiento.\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar chequeras",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/checkbooks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "checkbooks"
              ],
              "query": [
                {
                  "key": "bank_id",
                  "value": "{{bank_id}}",
                  "description": "(Opcional) Filtra por banco.",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "ACTIVE",
                  "description": "(Opcional) Estado.",
                  "disabled": true
                }
              ]
            },
            "description": "Chequeras del negocio. Su `id` es el `checkbook_id` de POST /payables/payments.\n\nPermiso requerido: `treasury`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | No | Filtra por banco. |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks"
                  ],
                  "query": [
                    {
                      "key": "bank_id",
                      "value": "{{bank_id}}",
                      "description": "(Opcional) Filtra por banco.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "ACTIVE",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Chequeras del negocio. Su `id` es el `checkbook_id` de POST /payables/payments.\n\nPermiso requerido: `treasury`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | No | Filtra por banco. |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"bank_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Chequera operativa\",\n      \"code\": \"CHQ-01\",\n      \"start_number\": 1,\n      \"end_number\": 100,\n      \"current_number\": 23,\n      \"status\": \"ACTIVE\"\n    }\n  ]\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks"
                  ],
                  "query": [
                    {
                      "key": "bank_id",
                      "value": "{{bank_id}}",
                      "description": "(Opcional) Filtra por banco.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "ACTIVE",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Chequeras del negocio. Su `id` es el `checkbook_id` de POST /payables/payments.\n\nPermiso requerido: `treasury`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | No | Filtra por banco. |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Crear chequera",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/checkbooks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "checkbooks"
              ]
            },
            "description": "Crea una chequera `ACTIVE` de un banco del negocio; `current_number` empieza en `start_number`.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | Sí | Banco del negocio. |\n| `start_number` | integer | Sí |  |\n| `end_number` | integer | Sí | Mayor que start_number. |\n| `name` | string | No |  |\n| `code` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"bank_id\": \"{{bank_id}}\",\n  \"name\": \"Chequera 2027\",\n  \"code\": \"B\",\n  \"start_number\": 101,\n  \"end_number\": 200\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Chequera creada",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks"
                  ]
                },
                "description": "Crea una chequera `ACTIVE` de un banco del negocio; `current_number` empieza en `start_number`.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | Sí | Banco del negocio. |\n| `start_number` | integer | Sí |  |\n| `end_number` | integer | Sí | Mayor que start_number. |\n| `name` | string | No |  |\n| `code` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"bank_id\": \"{{bank_id}}\",\n  \"name\": \"Chequera 2027\",\n  \"code\": \"B\",\n  \"start_number\": 101,\n  \"end_number\": 200\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"bank_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Chequera 2027\",\n    \"code\": \"B\",\n    \"start_number\": 101,\n    \"end_number\": 200,\n    \"current_number\": 101,\n    \"status\": \"ACTIVE\"\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks"
                  ]
                },
                "description": "Crea una chequera `ACTIVE` de un banco del negocio; `current_number` empieza en `start_number`.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `bank_id` | string (uuid) | Sí | Banco del negocio. |\n| `start_number` | integer | Sí |  |\n| `end_number` | integer | Sí | Mayor que start_number. |\n| `name` | string | No |  |\n| `code` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"bank_id\": \"{{bank_id}}\",\n  \"name\": \"Chequera 2027\",\n  \"code\": \"B\",\n  \"start_number\": 101,\n  \"end_number\": 200\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"end_number\": [\n      \"The end number field must be greater than start number.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Listar cajas chicas",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/petty-cashes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "petty-cashes"
              ]
            },
            "description": "Cajas chicas del negocio. Su `id` es el `petty_cash_id` de POST /payables/payments.\n\nPermiso requerido: `treasury`\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/petty-cashes",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "petty-cashes"
                  ]
                },
                "description": "Cajas chicas del negocio. Su `id` es el `petty_cash_id` de POST /payables/payments.\n\nPermiso requerido: `treasury`\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury` o desactivada."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Caja chica oficina\",\n      \"balance\": 150.0\n    }\n  ]\n}"
            }
          ]
        },
        {
          "name": "Crear caja chica",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/petty-cashes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "petty-cashes"
              ]
            },
            "description": "Crea una caja chica. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Caja chica Sucursal Centro\",\n  \"balance\": 250.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"observations\": \"Administración\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Caja chica creada",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/petty-cashes",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "petty-cashes"
                  ]
                },
                "description": "Crea una caja chica. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Caja chica Sucursal Centro\",\n  \"balance\": 250.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"observations\": \"Administración\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Caja chica Sucursal Centro\",\n    \"balance\": 250.0,\n    \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"observations\": \"Administración\"\n  }\n}"
            },
            {
              "name": "422 Validación o cuenta contable inválida",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/petty-cashes",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "petty-cashes"
                  ]
                },
                "description": "Crea una caja chica. `account_id` debe ser una cuenta contable de movimiento del negocio.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `balance` | number | No | Saldo inicial (por defecto 0). |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Caja chica Sucursal Centro\",\n  \"balance\": 250.0,\n  \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"observations\": \"Administración\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"account_id\": \"La cuenta 1101 tiene subcuentas; use una cuenta de movimiento.\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Editar banco",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/banks/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "banks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{bank_id}}",
                  "description": "ID del banco"
                }
              ]
            },
            "description": "Actualiza nombre, número de cuenta o cuenta contable. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_number` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Banco Agrícola - Planillas\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/banks/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "banks",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{bank_id}}",
                      "description": "ID del banco"
                    }
                  ]
                },
                "description": "Actualiza nombre, número de cuenta o cuenta contable. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_number` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Banco Agrícola - Planillas\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Banco Agrícola - Corriente\",\n    \"account_number\": \"0012-345678-9\",\n    \"balance\": 15000.0,\n    \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  }\n}"
            },
            {
              "name": "422 Validación o cuenta contable inválida",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/banks/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "banks",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{bank_id}}",
                      "description": "ID del banco"
                    }
                  ]
                },
                "description": "Actualiza nombre, número de cuenta o cuenta contable. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_number` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento del negocio. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Banco Agrícola - Planillas\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"account_id\": \"La cuenta 1101 tiene subcuentas; use una cuenta de movimiento.\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Editar chequera",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/checkbooks/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "checkbooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{checkbook_id}}",
                  "description": "ID de la chequera"
                }
              ]
            },
            "description": "Actualiza nombre, código o estado. El rango y el banco no cambian.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No |  |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"CANCELLED\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{checkbook_id}}",
                      "description": "ID de la chequera"
                    }
                  ]
                },
                "description": "Actualiza nombre, código o estado. El rango y el banco no cambian.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No |  |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"CANCELLED\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"bank_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Chequera 2027\",\n    \"code\": \"B\",\n    \"start_number\": 101,\n    \"end_number\": 200,\n    \"current_number\": 101,\n    \"status\": \"CANCELLED\"\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/checkbooks/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "checkbooks",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{checkbook_id}}",
                      "description": "ID de la chequera"
                    }
                  ]
                },
                "description": "Actualiza nombre, código o estado. El rango y el banco no cambian.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No |  |\n| `status` | string: `ACTIVE`, `EXHAUSTED`, `CANCELLED` | No | Estado. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"CANCELLED\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Editar caja chica",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/treasury/petty-cashes/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "treasury",
                "petty-cashes",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{petty_cash_id}}",
                  "description": "ID de la caja chica"
                }
              ]
            },
            "description": "Actualiza nombre, cuenta contable u observaciones. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"observations\": \"Responsable: gerencia\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/petty-cashes/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "petty-cashes",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{petty_cash_id}}",
                      "description": "ID de la caja chica"
                    }
                  ]
                },
                "description": "Actualiza nombre, cuenta contable u observaciones. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"observations\": \"Responsable: gerencia\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Caja chica Sucursal Centro\",\n    \"balance\": 250.0,\n    \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"observations\": \"Administración\"\n  }\n}"
            },
            {
              "name": "422 Validación o cuenta contable inválida",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/treasury/petty-cashes/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "treasury",
                    "petty-cashes",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{petty_cash_id}}",
                      "description": "ID de la caja chica"
                    }
                  ]
                },
                "description": "Actualiza nombre, cuenta contable u observaciones. El saldo no se edita.\n\nPermiso requerido: `treasury.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `account_id` | string (uuid) | No | Cuenta contable de movimiento. |\n| `observations` | string | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `treasury.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o cuenta contable inválida.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"observations\": \"Responsable: gerencia\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"account_id\": \"La cuenta 1101 tiene subcuentas; use una cuenta de movimiento.\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Contabilidad",
      "description": "Catálogo de cuentas, centros de costo, partidas, presupuestos y estados financieros.",
      "item": [
        {
          "name": "Catálogo de cuentas y períodos",
          "item": [
            {
              "name": "Listar catálogo de cuentas",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/accounts",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "accounts"
                  ],
                  "query": [
                    {
                      "key": "only_movement_accounts",
                      "value": "true",
                      "description": "(Opcional) 1 = solo cuentas sin subcuentas.",
                      "disabled": true
                    },
                    {
                      "key": "type",
                      "value": "asset",
                      "description": "(Opcional) Tipo de cuenta.",
                      "disabled": true
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Código o nombre.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Plan de cuentas del negocio.\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `only_movement_accounts` | boolean | No | 1 = solo cuentas sin subcuentas. |\n| `type` | string: `asset`, `liability`, `equity`, `revenue`, `expense` | No | Tipo de cuenta. |\n| `search` | string | No | Código o nombre. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/accounts",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "accounts"
                      ],
                      "query": [
                        {
                          "key": "only_movement_accounts",
                          "value": "true",
                          "description": "(Opcional) 1 = solo cuentas sin subcuentas.",
                          "disabled": true
                        },
                        {
                          "key": "type",
                          "value": "asset",
                          "description": "(Opcional) Tipo de cuenta.",
                          "disabled": true
                        },
                        {
                          "key": "search",
                          "value": "",
                          "description": "(Opcional) Código o nombre.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Plan de cuentas del negocio.\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `only_movement_accounts` | boolean | No | 1 = solo cuentas sin subcuentas. |\n| `type` | string: `asset`, `liability`, `equity`, `revenue`, `expense` | No | Tipo de cuenta. |\n| `search` | string | No | Código o nombre. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"code\": \"110101\",\n      \"name\": \"Caja general\",\n      \"type\": \"asset\",\n      \"level\": 4,\n      \"parent_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"accepts_movements\": true\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/accounts",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "accounts"
                      ],
                      "query": [
                        {
                          "key": "only_movement_accounts",
                          "value": "true",
                          "description": "(Opcional) 1 = solo cuentas sin subcuentas.",
                          "disabled": true
                        },
                        {
                          "key": "type",
                          "value": "asset",
                          "description": "(Opcional) Tipo de cuenta.",
                          "disabled": true
                        },
                        {
                          "key": "search",
                          "value": "",
                          "description": "(Opcional) Código o nombre.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Plan de cuentas del negocio.\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `only_movement_accounts` | boolean | No | 1 = solo cuentas sin subcuentas. |\n| `type` | string: `asset`, `liability`, `equity`, `revenue`, `expense` | No | Tipo de cuenta. |\n| `search` | string | No | Código o nombre. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar períodos contables",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/periods",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "periods"
                  ],
                  "query": [
                    {
                      "key": "year",
                      "value": "2026",
                      "description": "(Opcional) Año.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Períodos y su estado (ABIERTO, CERRADO, BLOQUEADO).\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/periods",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "periods"
                      ],
                      "query": [
                        {
                          "key": "year",
                          "value": "2026",
                          "description": "(Opcional) Año.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Períodos y su estado (ABIERTO, CERRADO, BLOQUEADO).\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"year\": 2026,\n      \"month\": 10,\n      \"status\": \"ABIERTO\"\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/periods",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "periods"
                      ],
                      "query": [
                        {
                          "key": "year",
                          "value": "2026",
                          "description": "(Opcional) Año.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Períodos y su estado (ABIERTO, CERRADO, BLOQUEADO).\n\nPermiso requerido: `accounting.accounts`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.accounts` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Centros de costo y distribuciones",
          "item": [
            {
              "name": "Listar distribuciones",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-center-distributions",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-center-distributions"
                  ],
                  "query": [
                    {
                      "key": "include_inactive",
                      "value": "false",
                      "description": "(Opcional) true = incluye las desactivadas.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Distribuciones porcentuales entre centros de costo, por código.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye las desactivadas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions"
                      ],
                      "query": [
                        {
                          "key": "include_inactive",
                          "value": "false",
                          "description": "(Opcional) true = incluye las desactivadas.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Distribuciones porcentuales entre centros de costo, por código.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye las desactivadas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"code\": \"ALQ\",\n      \"name\": \"Alquiler oficina central\",\n      \"is_active\": true,\n      \"lines\": [\n        {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"percentage\": 60.0,\n          \"cost_center\": {\n            \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n            \"code\": \"0101\",\n            \"name\": \"Ventas San Salvador\"\n          }\n        },\n        {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"cost_center_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"percentage\": 40.0,\n          \"cost_center\": {\n            \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n            \"code\": \"0201\",\n            \"name\": \"Administración\"\n          }\n        }\n      ],\n      \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n      \"updated_at\": \"2026-10-08T15:00:00.000000Z\"\n    }\n  ]\n}"
                }
              ]
            },
            {
              "name": "Crear distribución",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-center-distributions",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-center-distributions"
                  ]
                },
                "description": "Al menos 2 centros hoja activos, sin repetir, con porcentajes > 0 que sumen exactamente 100.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `is_active` | boolean | No | Por defecto true. |\n| `lines` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación de la distribución.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"code\": \"ALQ\",\n  \"name\": \"Alquiler oficina central\",\n  \"is_active\": true,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 60\n    },\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 40\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Distribución creada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions"
                      ]
                    },
                    "description": "Al menos 2 centros hoja activos, sin repetir, con porcentajes > 0 que sumen exactamente 100.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `is_active` | boolean | No | Por defecto true. |\n| `lines` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación de la distribución.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"ALQ\",\n  \"name\": \"Alquiler oficina central\",\n  \"is_active\": true,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 60\n    },\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 40\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"code\": \"ALQ\",\n    \"name\": \"Alquiler oficina central\",\n    \"is_active\": true,\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"percentage\": 60.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        }\n      },\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"percentage\": 40.0,\n        \"cost_center\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"0201\",\n          \"name\": \"Administración\"\n        }\n      }\n    ],\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\"\n  }\n}"
                },
                {
                  "name": "422 Validación de la distribución",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions"
                      ]
                    },
                    "description": "Al menos 2 centros hoja activos, sin repetir, con porcentajes > 0 que sumen exactamente 100.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `is_active` | boolean | No | Por defecto true. |\n| `lines` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación de la distribución.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"ALQ\",\n  \"name\": \"Alquiler oficina central\",\n  \"is_active\": true,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 60\n    },\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"percentage\": 40\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"lines\": [\n      \"Los porcentajes deben sumar exactamente 100 (suman 90).\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar centros de costo",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-centers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-centers"
                  ],
                  "query": [
                    {
                      "key": "include_inactive",
                      "value": "false",
                      "description": "(Opcional) true = incluye los centros desactivados.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Lista plana (por código) y árbol de los centros de costo del negocio. Solo los centros hoja (`is_leaf: true`) y activos se asignan a documentos y partidas.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye los centros desactivados. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers"
                      ],
                      "query": [
                        {
                          "key": "include_inactive",
                          "value": "false",
                          "description": "(Opcional) true = incluye los centros desactivados.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Lista plana (por código) y árbol de los centros de costo del negocio. Solo los centros hoja (`is_leaf: true`) y activos se asignan a documentos y partidas.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye los centros desactivados. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"list\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"code\": \"01\",\n        \"name\": \"Ventas\",\n        \"description\": null,\n        \"parent_id\": null,\n        \"level\": 1,\n        \"full_code\": \"01\",\n        \"is_active\": true,\n        \"is_leaf\": false\n      },\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"code\": \"0101\",\n        \"name\": \"Ventas San Salvador\",\n        \"description\": null,\n        \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"level\": 2,\n        \"full_code\": \"01.0101\",\n        \"is_active\": true,\n        \"is_leaf\": true\n      }\n    ],\n    \"tree\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"code\": \"01\",\n        \"name\": \"Ventas\",\n        \"description\": null,\n        \"parent_id\": null,\n        \"level\": 1,\n        \"full_code\": \"01\",\n        \"is_active\": true,\n        \"is_leaf\": false,\n        \"children\": [\n          {\n            \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n            \"code\": \"0101\",\n            \"name\": \"Ventas San Salvador\",\n            \"description\": null,\n            \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n            \"level\": 2,\n            \"full_code\": \"01.0101\",\n            \"is_active\": true,\n            \"is_leaf\": true,\n            \"children\": []\n          }\n        ]\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers"
                      ],
                      "query": [
                        {
                          "key": "include_inactive",
                          "value": "false",
                          "description": "(Opcional) true = incluye los centros desactivados.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Lista plana (por código) y árbol de los centros de costo del negocio. Solo los centros hoja (`is_leaf: true`) y activos se asignan a documentos y partidas.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye los centros desactivados. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"include_inactive\": [\n      \"The include inactive field must be true or false.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear centro de costo",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-centers",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-centers"
                  ]
                },
                "description": "Crea un centro de costo; con `parent_id` es un subcentro (su padre deja de ser hoja).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación, código repetido o padre inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"code\": \"0101\",\n  \"name\": \"Ventas San Salvador\",\n  \"description\": \"Equipo comercial\",\n  \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"is_active\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Centro creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers"
                      ]
                    },
                    "description": "Crea un centro de costo; con `parent_id` es un subcentro (su padre deja de ser hoja).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación, código repetido o padre inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"0101\",\n  \"name\": \"Ventas San Salvador\",\n  \"description\": \"Equipo comercial\",\n  \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"is_active\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"0101\",\n    \"name\": \"Ventas San Salvador\",\n    \"description\": \"Equipo comercial\",\n    \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"level\": 2,\n    \"full_code\": \"01.0101\",\n    \"is_active\": true,\n    \"is_leaf\": true\n  }\n}"
                },
                {
                  "name": "422 Validación, código repetido o padre inválido",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers"
                      ]
                    },
                    "description": "Crea un centro de costo; con `parent_id` es un subcentro (su padre deja de ser hoja).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Único en el negocio. |\n| `name` | string | Sí |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `422`: Validación, código repetido o padre inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"0101\",\n  \"name\": \"Ventas San Salvador\",\n  \"description\": \"Equipo comercial\",\n  \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n  \"is_active\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"code\": \"Ya existe un centro de costos con este código.\"\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar distribución",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-center-distributions",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{distribution_id}}",
                      "description": "ID de la distribución"
                    }
                  ]
                },
                "description": "Detalle de una distribución.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Detalle de una distribución.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"code\": \"ALQ\",\n    \"name\": \"Alquiler oficina central\",\n    \"is_active\": true,\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"percentage\": 60.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        }\n      },\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"percentage\": 40.0,\n        \"cost_center\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"0201\",\n          \"name\": \"Administración\"\n        }\n      }\n    ],\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\"\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Detalle de una distribución.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Distribution not found\"\n}"
                }
              ]
            },
            {
              "name": "Editar distribución",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-center-distributions",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{distribution_id}}",
                      "description": "ID de la distribución"
                    }
                  ]
                },
                "description": "Campos opcionales; si se envía `lines`, reemplaza todas las líneas. No modifica partidas ya generadas.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No |  |\n| `name` | string | No |  |\n| `is_active` | boolean | No |  |\n| `lines` | array de object | No | Si se envía, reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación de la distribución.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Alquiler oficina\",\n  \"is_active\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Campos opcionales; si se envía `lines`, reemplaza todas las líneas. No modifica partidas ya generadas.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No |  |\n| `name` | string | No |  |\n| `is_active` | boolean | No |  |\n| `lines` | array de object | No | Si se envía, reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación de la distribución.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Alquiler oficina\",\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"code\": \"ALQ\",\n    \"name\": \"Alquiler oficina central\",\n    \"is_active\": true,\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"percentage\": 60.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        }\n      },\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"percentage\": 40.0,\n        \"cost_center\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"0201\",\n          \"name\": \"Administración\"\n        }\n      }\n    ],\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\"\n  }\n}"
                },
                {
                  "name": "422 Validación de la distribución",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Campos opcionales; si se envía `lines`, reemplaza todas las líneas. No modifica partidas ya generadas.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No |  |\n| `name` | string | No |  |\n| `is_active` | boolean | No |  |\n| `lines` | array de object | No | Si se envía, reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación de la distribución.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Alquiler oficina\",\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"lines\": [\n      \"Los porcentajes deben sumar exactamente 100 (suman 90).\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Eliminar distribución",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-center-distributions",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{distribution_id}}",
                      "description": "ID de la distribución"
                    }
                  ]
                },
                "description": "Sin uso se elimina (`deleted: true`); usada en documentos o partidas se desactiva (`deleted: false, deactivated: true`).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Sin uso se elimina (`deleted: true`); usada en documentos o partidas se desactiva (`deleted: false, deactivated: true`).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"deleted\": false,\n    \"deactivated\": true\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-center-distributions/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-center-distributions",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{distribution_id}}",
                          "description": "ID de la distribución"
                        }
                      ]
                    },
                    "description": "Sin uso se elimina (`deleted: true`); usada en documentos o partidas se desactiva (`deleted: false, deactivated: true`).\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Distribution not found\"\n}"
                }
              ]
            },
            {
              "name": "Consultar centro de costo",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-centers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-centers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cost_center_id}}",
                      "description": "ID del centro de costo"
                    }
                  ]
                },
                "description": "Detalle de un centro de costo.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Detalle de un centro de costo.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"0101\",\n    \"name\": \"Ventas San Salvador\",\n    \"description\": null,\n    \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"level\": 2,\n    \"full_code\": \"01.0101\",\n    \"is_active\": true,\n    \"is_leaf\": true\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Detalle de un centro de costo.\n\nPermiso requerido: `accounting.cost_centers`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Cost center not found\"\n}"
                }
              ]
            },
            {
              "name": "Editar centro de costo",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-centers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-centers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cost_center_id}}",
                      "description": "ID del centro de costo"
                    }
                  ]
                },
                "description": "Actualiza solo los campos enviados. Cambiar `parent_id` recalcula el nivel del subárbol; un centro no puede depender de sí mismo ni de un subcentro suyo.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No | Único en el negocio. |\n| `name` | string | No |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, código repetido o padre inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Ventas Occidente\",\n  \"is_active\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Actualiza solo los campos enviados. Cambiar `parent_id` recalcula el nivel del subárbol; un centro no puede depender de sí mismo ni de un subcentro suyo.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No | Único en el negocio. |\n| `name` | string | No |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, código repetido o padre inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Ventas Occidente\",\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"0101\",\n    \"name\": \"Ventas Occidente\",\n    \"description\": null,\n    \"parent_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"level\": 2,\n    \"full_code\": \"01.0101\",\n    \"is_active\": true,\n    \"is_leaf\": true\n  }\n}"
                },
                {
                  "name": "422 Validación, código repetido o padre inválido",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Actualiza solo los campos enviados. Cambiar `parent_id` recalcula el nivel del subárbol; un centro no puede depender de sí mismo ni de un subcentro suyo.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | No | Único en el negocio. |\n| `name` | string | No |  |\n| `description` | string | No |  |\n| `parent_id` | string (uuid) | No | Centro padre del mismo negocio (null = raíz). |\n| `is_active` | boolean | No | Por defecto true. |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, código repetido o padre inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Ventas Occidente\",\n  \"is_active\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"parent_id\": \"Un centro de costos no puede depender de sí mismo ni de un subcentro suyo.\"\n  }\n}"
                }
              ]
            },
            {
              "name": "Eliminar centro de costo",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/cost-centers/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "cost-centers",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{cost_center_id}}",
                      "description": "ID del centro de costo"
                    }
                  ]
                },
                "description": "Elimina el centro si no tiene movimientos ni documentos; si los tiene, lo desactiva (`deleted: false, deactivated: true`). Con subcentros responde 422.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Tiene subcentros."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Elimina el centro si no tiene movimientos ni documentos; si los tiene, lo desactiva (`deleted: false, deactivated: true`). Con subcentros responde 422.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Tiene subcentros."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"deleted\": false,\n    \"deactivated\": true\n  }\n}"
                },
                {
                  "name": "422 Tiene subcentros",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/cost-centers/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "cost-centers",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{cost_center_id}}",
                          "description": "ID del centro de costo"
                        }
                      ]
                    },
                    "description": "Elimina el centro si no tiene movimientos ni documentos; si los tiene, lo desactiva (`deleted: false, deactivated: true`). Con subcentros responde 422.\n\nPermiso requerido: `accounting.cost_centers.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `accounting.cost_centers.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Tiene subcentros."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"El centro de costo tiene subcentros; elimínelos o muévalos primero.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Tipos de partida",
          "description": "Catálogo de tipos de partida (el mismo de la pantalla de nueva partida). Lectura con `accounting.journal_entries`; escritura con `accounting.entry_types.write`.",
          "item": [
            {
              "name": "Listar tipos de partida",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/entry-types",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "entry-types"
                  ],
                  "query": [
                    {
                      "key": "include_inactive",
                      "value": "false",
                      "description": "(Opcional) true = incluye los tipos desactivados.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Tipos de partida del negocio: el mismo catálogo que usa la pantalla de nueva partida. El `code` es el valor de `entry_type` en Crear partida. Por defecto solo los activos.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye los tipos desactivados. |"
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types"
                      ],
                      "query": [
                        {
                          "key": "include_inactive",
                          "value": "false",
                          "description": "(Opcional) true = incluye los tipos desactivados.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Tipos de partida del negocio: el mismo catálogo que usa la pantalla de nueva partida. El `code` es el valor de `entry_type` en Crear partida. Por defecto solo los activos.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `include_inactive` | boolean | No | true = incluye los tipos desactivados. |"
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"list\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"code\": \"PROV\",\n        \"name\": \"Provisiones\",\n        \"description\": \"Provisiones mensuales\",\n        \"prefix\": \"PRV\",\n        \"requires_approval\": false,\n        \"is_active\": true\n      }\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar tipo de partida",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "entry-types",
                    "{{entry_type_id}}"
                  ]
                },
                "description": "Detalle de un tipo de partida. Un tipo de otro negocio responde 404.\n\nPermiso requerido: `accounting.journal_entries`"
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Detalle de un tipo de partida. Un tipo de otro negocio responde 404.\n\nPermiso requerido: `accounting.journal_entries`"
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"PROV\",\n    \"name\": \"Provisiones\",\n    \"description\": \"Provisiones mensuales\",\n    \"prefix\": \"PRV\",\n    \"requires_approval\": false,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "404 Tipo no encontrado",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Detalle de un tipo de partida. Un tipo de otro negocio responde 404.\n\nPermiso requerido: `accounting.journal_entries`"
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Entry type not found\"\n}"
                }
              ]
            },
            {
              "name": "Crear tipo de partida",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/entry-types",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "entry-types"
                  ]
                },
                "description": "Crea un tipo de partida. El código se guarda en mayúsculas y debe ser único en el negocio; si ese código se eliminó antes, se restaura con los datos enviados.\n\nPermiso requerido: `accounting.entry_types.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Máximo 20 caracteres (letras, números, `-` y `_`). |\n| `name` | string | Sí | Máximo 100 caracteres. |\n| `description` | string | No | Máximo 1000 caracteres. |\n| `prefix` | string | Sí | Prefijo del correlativo (máximo 10 caracteres). |\n| `requires_approval` | boolean | No | Por defecto false. |\n| `is_active` | boolean | No | Por defecto true. |",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"code\": \"PROV\",\n  \"name\": \"Provisiones\",\n  \"description\": \"Provisiones mensuales\",\n  \"prefix\": \"PRV\",\n  \"requires_approval\": false,\n  \"is_active\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Tipo creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types"
                      ]
                    },
                    "description": "Crea un tipo de partida. El código se guarda en mayúsculas y debe ser único en el negocio; si ese código se eliminó antes, se restaura con los datos enviados.\n\nPermiso requerido: `accounting.entry_types.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Máximo 20 caracteres (letras, números, `-` y `_`). |\n| `name` | string | Sí | Máximo 100 caracteres. |\n| `description` | string | No | Máximo 1000 caracteres. |\n| `prefix` | string | Sí | Prefijo del correlativo (máximo 10 caracteres). |\n| `requires_approval` | boolean | No | Por defecto false. |\n| `is_active` | boolean | No | Por defecto true. |",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"PROV\",\n  \"name\": \"Provisiones\",\n  \"description\": \"Provisiones mensuales\",\n  \"prefix\": \"PRV\",\n  \"requires_approval\": false,\n  \"is_active\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"PROV\",\n    \"name\": \"Provisiones\",\n    \"description\": \"Provisiones mensuales\",\n    \"prefix\": \"PRV\",\n    \"requires_approval\": false,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "422 Código repetido",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types"
                      ]
                    },
                    "description": "Crea un tipo de partida. El código se guarda en mayúsculas y debe ser único en el negocio; si ese código se eliminó antes, se restaura con los datos enviados.\n\nPermiso requerido: `accounting.entry_types.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `code` | string | Sí | Máximo 20 caracteres (letras, números, `-` y `_`). |\n| `name` | string | Sí | Máximo 100 caracteres. |\n| `description` | string | No | Máximo 1000 caracteres. |\n| `prefix` | string | Sí | Prefijo del correlativo (máximo 10 caracteres). |\n| `requires_approval` | boolean | No | Por defecto false. |\n| `is_active` | boolean | No | Por defecto true. |",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"code\": \"PROV\",\n  \"name\": \"Provisiones\",\n  \"description\": \"Provisiones mensuales\",\n  \"prefix\": \"PRV\",\n  \"requires_approval\": false,\n  \"is_active\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"code\": [\n      \"Entry type PROV already exists.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Editar tipo de partida",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "entry-types",
                    "{{entry_type_id}}"
                  ]
                },
                "description": "Actualiza solo los campos enviados (`name`, `description`, `prefix`, `requires_approval`, `is_active`). El código no se puede cambiar: enviarlo responde 422.\n\nPermiso requerido: `accounting.entry_types.write`",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Provisiones mensuales\",\n  \"requires_approval\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Actualiza solo los campos enviados (`name`, `description`, `prefix`, `requires_approval`, `is_active`). El código no se puede cambiar: enviarlo responde 422.\n\nPermiso requerido: `accounting.entry_types.write`",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Provisiones mensuales\",\n  \"requires_approval\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"code\": \"PROV\",\n    \"name\": \"Provisiones mensuales\",\n    \"description\": \"Provisiones mensuales\",\n    \"prefix\": \"PRV\",\n    \"requires_approval\": true,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "422 Cambio de código",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Actualiza solo los campos enviados (`name`, `description`, `prefix`, `requires_approval`, `is_active`). El código no se puede cambiar: enviarlo responde 422.\n\nPermiso requerido: `accounting.entry_types.write`",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Provisiones mensuales\",\n  \"requires_approval\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"code\": [\n      \"The code cannot be changed; create a new entry type instead.\"\n    ]\n  }\n}"
                },
                {
                  "name": "404 Tipo no encontrado",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Actualiza solo los campos enviados (`name`, `description`, `prefix`, `requires_approval`, `is_active`). El código no se puede cambiar: enviarlo responde 422.\n\nPermiso requerido: `accounting.entry_types.write`",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Provisiones mensuales\",\n  \"requires_approval\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Entry type not found\"\n}"
                }
              ]
            },
            {
              "name": "Eliminar tipo de partida",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "entry-types",
                    "{{entry_type_id}}"
                  ]
                },
                "description": "Elimina el tipo si ninguna partida lo usa; si alguna lo usa, solo lo desactiva (`deleted: false`, `deactivated: true`).\n\nPermiso requerido: `accounting.entry_types.write`"
              },
              "response": [
                {
                  "name": "200 Desactivado (tiene partidas)",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Elimina el tipo si ninguna partida lo usa; si alguna lo usa, solo lo desactiva (`deleted: false`, `deactivated: true`).\n\nPermiso requerido: `accounting.entry_types.write`"
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"deleted\": false,\n    \"deactivated\": true\n  }\n}"
                },
                {
                  "name": "200 Eliminado",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Elimina el tipo si ninguna partida lo usa; si alguna lo usa, solo lo desactiva (`deleted: false`, `deactivated: true`).\n\nPermiso requerido: `accounting.entry_types.write`"
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"deleted\": true,\n    \"deactivated\": false\n  }\n}"
                },
                {
                  "name": "404 Tipo no encontrado",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/entry-types/{{entry_type_id}}",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "entry-types",
                        "{{entry_type_id}}"
                      ]
                    },
                    "description": "Elimina el tipo si ninguna partida lo usa; si alguna lo usa, solo lo desactiva (`deleted: false`, `deactivated: true`).\n\nPermiso requerido: `accounting.entry_types.write`"
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Entry type not found\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Partidas",
          "item": [
            {
              "name": "Listar partidas",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/journal-entries?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "journal-entries"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "status",
                      "value": "BORRADOR",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) 1-200.",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Partidas del rango (máximo 370 días), paginado.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `BORRADOR`, `PROCESADA` | No | Estado. |\n| `branch_id` | string | No | Sucursal. |\n| `per_page` | integer | No | 1-200. |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "status",
                          "value": "BORRADOR",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) 1-200.",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Partidas del rango (máximo 370 días), paginado.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `BORRADOR`, `PROCESADA` | No | Estado. |\n| `branch_id` | string | No | Sucursal. |\n| `per_page` | integer | No | 1-200. |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"entry_code\": null,\n        \"entry_type\": \"DIA\",\n        \"entry_date\": \"2026-10-31\",\n        \"description\": \"Comisiones de ventas octubre [Ref: COM-2026-10] (API: Mi ERP)\",\n        \"status\": \"BORRADOR\",\n        \"reference_type\": \"external_integration\",\n        \"total_debit\": 1250.0,\n        \"total_credit\": 1250.0,\n        \"is_balanced\": true,\n        \"details\": [\n          {\n            \"account_code\": \"510201\",\n            \"account_name\": \"Comisiones sobre ventas\",\n            \"debit\": 1250.0,\n            \"credit\": 0,\n            \"description\": \"Gasto por comisiones\",\n            \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n          },\n          {\n            \"account_code\": \"210305\",\n            \"account_name\": \"Comisiones por pagar\",\n            \"debit\": 0,\n            \"credit\": 1250.0,\n            \"description\": \"Comisiones por pagar\",\n            \"cost_center_id\": null\n          }\n        ]\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "status",
                          "value": "BORRADOR",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) 1-200.",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Partidas del rango (máximo 370 días), paginado.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `BORRADOR`, `PROCESADA` | No | Estado. |\n| `branch_id` | string | No | Sucursal. |\n| `per_page` | integer | No | 1-200. |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear partida en borrador",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/journal-entries",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "journal-entries"
                  ]
                },
                "description": "Crea una partida en BORRADOR. Debe cuadrar, usar cuentas de movimiento y caer en un período abierto.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `entry_date` | string (date) | Sí | Debe tener período ABIERTO. |\n| `description` | string | Sí |  |\n| `entry_type` | string | No | Código de un tipo de partida activo del negocio (máximo 20 caracteres; ver Tipos de partida). |\n| `entry_type_id` | string (uuid) | No | ID de un tipo de partida activo (alternativa a `entry_type`; si se envían ambos, prevalece `entry_type_id`). Sin ninguno de los dos se usa el tipo configurado para la API externa (`DIA` si no hay). Un tipo inexistente o inactivo responde 422 con la lista de códigos válidos. |\n| `external_reference` | string | No | Referencia en tu sistema. |\n| `details` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"entry_date\": \"2026-10-31\",\n  \"entry_type\": \"DIA\",\n  \"entry_type_id\": \"{{entry_type_id}}\",\n  \"description\": \"Comisiones de ventas octubre\",\n  \"external_reference\": \"COM-2026-10\",\n  \"details\": [\n    {\n      \"account_code\": \"510201\",\n      \"debit\": 1250,\n      \"credit\": 0,\n      \"description\": \"Gasto por comisiones\",\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"cost_center_distribution_id\": null\n    },\n    {\n      \"account_code\": \"210305\",\n      \"debit\": 0,\n      \"credit\": 1250,\n      \"description\": \"Comisiones por pagar\",\n      \"cost_center_distribution_id\": null\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Partida creada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries"
                      ]
                    },
                    "description": "Crea una partida en BORRADOR. Debe cuadrar, usar cuentas de movimiento y caer en un período abierto.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `entry_date` | string (date) | Sí | Debe tener período ABIERTO. |\n| `description` | string | Sí |  |\n| `entry_type` | string | No | Código de un tipo de partida activo del negocio (máximo 20 caracteres; ver Tipos de partida). |\n| `entry_type_id` | string (uuid) | No | ID de un tipo de partida activo (alternativa a `entry_type`; si se envían ambos, prevalece `entry_type_id`). Sin ninguno de los dos se usa el tipo configurado para la API externa (`DIA` si no hay). Un tipo inexistente o inactivo responde 422 con la lista de códigos válidos. |\n| `external_reference` | string | No | Referencia en tu sistema. |\n| `details` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"entry_date\": \"2026-10-31\",\n  \"description\": \"Comisiones de ventas octubre\",\n  \"external_reference\": \"COM-2026-10\",\n  \"details\": [\n    {\n      \"account_code\": \"510201\",\n      \"debit\": 1250.0,\n      \"credit\": 0,\n      \"description\": \"Gasto por comisiones\",\n      \"cost_center_id\": \"{{cost_center_id}}\"\n    },\n    {\n      \"account_code\": \"210305\",\n      \"debit\": 0,\n      \"credit\": 1250.0,\n      \"description\": \"Comisiones por pagar\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"entry_code\": null,\n    \"entry_type_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"entry_type\": \"DIA\",\n    \"entry_date\": \"2026-10-31\",\n    \"description\": \"Comisiones de ventas octubre [Ref: COM-2026-10] (API: Mi ERP)\",\n    \"status\": \"BORRADOR\",\n    \"reference_type\": \"external_integration\",\n    \"total_debit\": 1250.0,\n    \"total_credit\": 1250.0,\n    \"is_balanced\": true,\n    \"details\": [\n      {\n        \"account_code\": \"510201\",\n        \"account_name\": \"Comisiones sobre ventas\",\n        \"debit\": 1250.0,\n        \"credit\": 0,\n        \"description\": \"Gasto por comisiones\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n      },\n      {\n        \"account_code\": \"210305\",\n        \"account_name\": \"Comisiones por pagar\",\n        \"debit\": 0,\n        \"credit\": 1250.0,\n        \"description\": \"Comisiones por pagar\",\n        \"cost_center_id\": null\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries"
                      ]
                    },
                    "description": "Crea una partida en BORRADOR. Debe cuadrar, usar cuentas de movimiento y caer en un período abierto.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí |  |\n| `entry_date` | string (date) | Sí | Debe tener período ABIERTO. |\n| `description` | string | Sí |  |\n| `entry_type` | string | No | Código de un tipo de partida activo del negocio (máximo 20 caracteres; ver Tipos de partida). |\n| `entry_type_id` | string (uuid) | No | ID de un tipo de partida activo (alternativa a `entry_type`; si se envían ambos, prevalece `entry_type_id`). Sin ninguno de los dos se usa el tipo configurado para la API externa (`DIA` si no hay). Un tipo inexistente o inactivo responde 422 con la lista de códigos válidos. |\n| `external_reference` | string | No | Referencia en tu sistema. |\n| `details` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"entry_date\": \"2026-10-31\",\n  \"description\": \"Comisiones de ventas octubre\",\n  \"external_reference\": \"COM-2026-10\",\n  \"details\": [\n    {\n      \"account_code\": \"510201\",\n      \"debit\": 1250.0,\n      \"credit\": 0,\n      \"description\": \"Gasto por comisiones\",\n      \"cost_center_id\": \"{{cost_center_id}}\"\n    },\n    {\n      \"account_code\": \"210305\",\n      \"debit\": 0,\n      \"credit\": 1250.0,\n      \"description\": \"Comisiones por pagar\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"branch_id\": [\n      \"The branch id field is required.\"\n    ],\n    \"entry_type_id\": \"Entry type not found or inactive. Valid codes: DIA, EGR, ING, PROV (see GET /accounting/entry-types).\"\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar partida",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/journal-entries/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "journal-entries",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{journal_entry_id}}",
                      "description": "ID de la partida"
                    }
                  ]
                },
                "description": "Detalle de una partida con sus líneas.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{journal_entry_id}}",
                          "description": "ID de la partida"
                        }
                      ]
                    },
                    "description": "Detalle de una partida con sus líneas.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"entry_code\": \"DIA-2026-10-0042\",\n    \"entry_type\": \"DIA\",\n    \"entry_date\": \"2026-10-31\",\n    \"description\": \"Comisiones de ventas octubre [Ref: COM-2026-10] (API: Mi ERP)\",\n    \"status\": \"PROCESADA\",\n    \"reference_type\": \"external_integration\",\n    \"total_debit\": 1250.0,\n    \"total_credit\": 1250.0,\n    \"is_balanced\": true,\n    \"details\": [\n      {\n        \"account_code\": \"510201\",\n        \"account_name\": \"Comisiones sobre ventas\",\n        \"debit\": 1250.0,\n        \"credit\": 0,\n        \"description\": \"Gasto por comisiones\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n      },\n      {\n        \"account_code\": \"210305\",\n        \"account_name\": \"Comisiones por pagar\",\n        \"debit\": 0,\n        \"credit\": 1250.0,\n        \"description\": \"Comisiones por pagar\",\n        \"cost_center_id\": null\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/journal-entries/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "journal-entries",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{journal_entry_id}}",
                          "description": "ID de la partida"
                        }
                      ]
                    },
                    "description": "Detalle de una partida con sus líneas.\n\nPermiso requerido: `accounting.journal_entries`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.journal_entries` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Presupuestos",
          "item": [
            {
              "name": "Listar presupuestos",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets"
                  ],
                  "query": [
                    {
                      "key": "fiscal_year",
                      "value": "1",
                      "description": "(Opcional) Año.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "draft",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Presupuestos por centro de costo (sin líneas), del año más reciente al más antiguo.\n\nPermiso requerido: `accounting.budgets`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `fiscal_year` | integer | No | Año. |\n| `status` | string: `draft`, `approved`, `closed` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets"
                      ],
                      "query": [
                        {
                          "key": "fiscal_year",
                          "value": "1",
                          "description": "(Opcional) Año.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "draft",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Presupuestos por centro de costo (sin líneas), del año más reciente al más antiguo.\n\nPermiso requerido: `accounting.budgets`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `fiscal_year` | integer | No | Año. |\n| `status` | string: `draft`, `approved`, `closed` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Presupuesto 2026\",\n      \"fiscal_year\": 2026,\n      \"status\": \"draft\",\n      \"notes\": null,\n      \"lines_count\": 1,\n      \"total_amount\": 100.0,\n      \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n      \"updated_at\": \"2026-10-08T15:00:00.000000Z\"\n    }\n  ]\n}"
                }
              ]
            },
            {
              "name": "Crear presupuesto",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets"
                  ]
                },
                "description": "Nace en `draft`. `lines` opcional.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `fiscal_year` | integer | Sí |  |\n| `notes` | string | No |  |\n| `lines` | array de object | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `422`: Validación o presupuesto no editable.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Presupuesto 2026\",\n  \"fiscal_year\": 2026,\n  \"notes\": \"Versión inicial\",\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 1,\n      \"amount\": 100\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Presupuesto creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets"
                      ]
                    },
                    "description": "Nace en `draft`. `lines` opcional.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `fiscal_year` | integer | Sí |  |\n| `notes` | string | No |  |\n| `lines` | array de object | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Presupuesto 2026\",\n  \"fiscal_year\": 2026,\n  \"notes\": \"Versión inicial\",\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 1,\n      \"amount\": 100\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Presupuesto 2026\",\n    \"fiscal_year\": 2026,\n    \"status\": \"draft\",\n    \"notes\": null,\n    \"lines_count\": 1,\n    \"total_amount\": 100.0,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"month\": 1,\n        \"amount\": 100.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        },\n        \"account\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"6102\",\n          \"name\": \"Papelería\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Validación o presupuesto no editable",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets"
                      ]
                    },
                    "description": "Nace en `draft`. `lines` opcional.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `fiscal_year` | integer | Sí |  |\n| `notes` | string | No |  |\n| `lines` | array de object | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Presupuesto 2026\",\n  \"fiscal_year\": 2026,\n  \"notes\": \"Versión inicial\",\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 1,\n      \"amount\": 100\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"Solo se puede modificar un presupuesto en borrador.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar presupuesto",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{budget_id}}",
                      "description": "ID del presupuesto"
                    }
                  ]
                },
                "description": "Presupuesto con sus líneas.\n\nPermiso requerido: `accounting.budgets`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Presupuesto con sus líneas.\n\nPermiso requerido: `accounting.budgets`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Presupuesto 2026\",\n    \"fiscal_year\": 2026,\n    \"status\": \"draft\",\n    \"notes\": null,\n    \"lines_count\": 1,\n    \"total_amount\": 100.0,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"month\": 1,\n        \"amount\": 100.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        },\n        \"account\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"6102\",\n          \"name\": \"Papelería\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 No encontrado o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Presupuesto con sus líneas.\n\nPermiso requerido: `accounting.budgets`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `404`: No encontrado o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Budget not found\"\n}"
                }
              ]
            },
            {
              "name": "Editar presupuesto",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{budget_id}}",
                      "description": "ID del presupuesto"
                    }
                  ]
                },
                "description": "Cambia `name`, `fiscal_year` o `notes`. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `fiscal_year` | integer | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Presupuesto 2026 v2\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Cambia `name`, `fiscal_year` o `notes`. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `fiscal_year` | integer | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Presupuesto 2026 v2\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Presupuesto 2026\",\n    \"fiscal_year\": 2026,\n    \"status\": \"draft\",\n    \"notes\": null,\n    \"lines_count\": 1,\n    \"total_amount\": 100.0,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"month\": 1,\n        \"amount\": 100.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        },\n        \"account\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"6102\",\n          \"name\": \"Papelería\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Validación o presupuesto no editable",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Cambia `name`, `fiscal_year` o `notes`. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `fiscal_year` | integer | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Presupuesto 2026 v2\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"Solo se puede modificar un presupuesto en borrador.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Eliminar presupuesto",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{budget_id}}",
                      "description": "ID del presupuesto"
                    }
                  ]
                },
                "description": "Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"deleted\": true\n  }\n}"
                },
                {
                  "name": "422 Validación o presupuesto no editable",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"Solo se puede modificar un presupuesto en borrador.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Obtener presupuesto vs real",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/budget-vs-actual",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "budget-vs-actual"
                  ],
                  "query": [
                    {
                      "key": "fiscal_year",
                      "value": "2026",
                      "description": "(Opcional) Año (por defecto el actual).",
                      "disabled": true
                    },
                    {
                      "key": "budget_id",
                      "value": "{{budget_id}}",
                      "description": "(Opcional) Presupuesto a comparar (por defecto el aprobado del año).",
                      "disabled": true
                    },
                    {
                      "key": "month_from",
                      "value": "1",
                      "description": "(Opcional) Mes inicial (1-12).",
                      "disabled": true
                    },
                    {
                      "key": "month_to",
                      "value": "1",
                      "description": "(Opcional) Mes final (1-12).",
                      "disabled": true
                    },
                    {
                      "key": "cost_center_ids[]",
                      "value": "{{cost_center_id}}",
                      "description": "(Opcional) Centros a incluir (repetible). Sin él, todo el árbol.",
                      "disabled": true
                    },
                    {
                      "key": "include_children",
                      "value": "true",
                      "description": "(Opcional) Incluye los subcentros (por defecto true).",
                      "disabled": true
                    },
                    {
                      "key": "depth",
                      "value": "1",
                      "description": "(Opcional) Agrupa las cuentas al ancestro de ese nivel.",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Limita lo real a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "expense_threshold",
                      "value": "",
                      "description": "(Opcional) Umbral de ejecución de costos y gastos (por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "income_threshold",
                      "value": "",
                      "description": "(Opcional) Umbral de ejecución de ingresos (por defecto 100).",
                      "disabled": true
                    },
                    {
                      "key": "format",
                      "value": "json",
                      "description": "(Opcional) `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Compara el presupuesto (por defecto el `approved` del año) con lo real de partidas PROCESADAS, por centro y cuenta. `status`: `exceeded` (costo/gasto con ejecución mayor que `expense_threshold`, o real sin presupuesto), `under` (ingreso con ejecución menor que `income_threshold`) u `ok`.\n\nPermiso requerido: `accounting.budgets`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `fiscal_year` | integer | No | Año (por defecto el actual). |\n| `budget_id` | string (uuid) | No | Presupuesto a comparar (por defecto el aprobado del año). |\n| `month_from` | integer | No | Mes inicial (1-12). |\n| `month_to` | integer | No | Mes final (1-12). |\n| `cost_center_ids[]` | array de string | No | Centros a incluir (repetible). Sin él, todo el árbol. |\n| `include_children` | boolean | No | Incluye los subcentros (por defecto true). |\n| `depth` | integer | No | Agrupa las cuentas al ancestro de ese nivel. |\n| `branch_id` | string (uuid) | No | Limita lo real a una sucursal. |\n| `expense_threshold` | number | No | Umbral de ejecución de costos y gastos (por defecto 100). |\n| `income_threshold` | number | No | Umbral de ejecución de ingresos (por defecto 100). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `422`: Sin presupuesto aprobado o formato inválido."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/budget-vs-actual",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "budget-vs-actual"
                      ],
                      "query": [
                        {
                          "key": "fiscal_year",
                          "value": "2026",
                          "description": "(Opcional) Año (por defecto el actual).",
                          "disabled": true
                        },
                        {
                          "key": "budget_id",
                          "value": "{{budget_id}}",
                          "description": "(Opcional) Presupuesto a comparar (por defecto el aprobado del año).",
                          "disabled": true
                        },
                        {
                          "key": "month_from",
                          "value": "1",
                          "description": "(Opcional) Mes inicial (1-12).",
                          "disabled": true
                        },
                        {
                          "key": "month_to",
                          "value": "1",
                          "description": "(Opcional) Mes final (1-12).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_ids[]",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Centros a incluir (repetible). Sin él, todo el árbol.",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Incluye los subcentros (por defecto true).",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Agrupa las cuentas al ancestro de ese nivel.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Limita lo real a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "expense_threshold",
                          "value": "",
                          "description": "(Opcional) Umbral de ejecución de costos y gastos (por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "income_threshold",
                          "value": "",
                          "description": "(Opcional) Umbral de ejecución de ingresos (por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Compara el presupuesto (por defecto el `approved` del año) con lo real de partidas PROCESADAS, por centro y cuenta. `status`: `exceeded` (costo/gasto con ejecución mayor que `expense_threshold`, o real sin presupuesto), `under` (ingreso con ejecución menor que `income_threshold`) u `ok`.\n\nPermiso requerido: `accounting.budgets`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `fiscal_year` | integer | No | Año (por defecto el actual). |\n| `budget_id` | string (uuid) | No | Presupuesto a comparar (por defecto el aprobado del año). |\n| `month_from` | integer | No | Mes inicial (1-12). |\n| `month_to` | integer | No | Mes final (1-12). |\n| `cost_center_ids[]` | array de string | No | Centros a incluir (repetible). Sin él, todo el árbol. |\n| `include_children` | boolean | No | Incluye los subcentros (por defecto true). |\n| `depth` | integer | No | Agrupa las cuentas al ancestro de ese nivel. |\n| `branch_id` | string (uuid) | No | Limita lo real a una sucursal. |\n| `expense_threshold` | number | No | Umbral de ejecución de costos y gastos (por defecto 100). |\n| `income_threshold` | number | No | Umbral de ejecución de ingresos (por defecto 100). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `422`: Sin presupuesto aprobado o formato inválido."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"title\": \"Presupuesto vs real por centro de costo\",\n    \"budget\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Presupuesto 2026\",\n      \"fiscal_year\": 2026,\n      \"status\": \"approved\"\n    },\n    \"month_from\": 1,\n    \"month_to\": 10,\n    \"expense_threshold\": 100,\n    \"income_threshold\": 100,\n    \"centers\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"code\": \"01\",\n        \"name\": \"Ventas\",\n        \"level\": 1,\n        \"parent_id\": null,\n        \"is_leaf\": false,\n        \"rows\": [\n          {\n            \"account_code\": \"6102\",\n            \"account_name\": \"Papelería\",\n            \"group\": \"expenses\",\n            \"budget\": 100,\n            \"actual\": 120,\n            \"variance\": 20,\n            \"execution_pct\": 120,\n            \"status\": \"exceeded\"\n          }\n        ],\n        \"totals\": {\n          \"income\": {\n            \"budget\": 0,\n            \"actual\": 0,\n            \"variance\": 0,\n            \"execution_pct\": null\n          },\n          \"costs\": {\n            \"budget\": 0,\n            \"actual\": 0,\n            \"variance\": 0,\n            \"execution_pct\": null\n          },\n          \"expenses\": {\n            \"budget\": 100,\n            \"actual\": 120,\n            \"variance\": 20,\n            \"execution_pct\": 120\n          }\n        }\n      }\n    ],\n    \"totals\": {\n      \"income\": {\n        \"budget\": 0,\n        \"actual\": 0,\n        \"variance\": 0,\n        \"execution_pct\": null\n      },\n      \"costs\": {\n        \"budget\": 0,\n        \"actual\": 0,\n        \"variance\": 0,\n        \"execution_pct\": null\n      },\n      \"expenses\": {\n        \"budget\": 100,\n        \"actual\": 120,\n        \"variance\": 20,\n        \"execution_pct\": 120\n      }\n    }\n  }\n}"
                },
                {
                  "name": "422 Sin presupuesto aprobado o formato inválido",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/budget-vs-actual",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "budget-vs-actual"
                      ],
                      "query": [
                        {
                          "key": "fiscal_year",
                          "value": "2026",
                          "description": "(Opcional) Año (por defecto el actual).",
                          "disabled": true
                        },
                        {
                          "key": "budget_id",
                          "value": "{{budget_id}}",
                          "description": "(Opcional) Presupuesto a comparar (por defecto el aprobado del año).",
                          "disabled": true
                        },
                        {
                          "key": "month_from",
                          "value": "1",
                          "description": "(Opcional) Mes inicial (1-12).",
                          "disabled": true
                        },
                        {
                          "key": "month_to",
                          "value": "1",
                          "description": "(Opcional) Mes final (1-12).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_ids[]",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Centros a incluir (repetible). Sin él, todo el árbol.",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Incluye los subcentros (por defecto true).",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Agrupa las cuentas al ancestro de ese nivel.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Limita lo real a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "expense_threshold",
                          "value": "",
                          "description": "(Opcional) Umbral de ejecución de costos y gastos (por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "income_threshold",
                          "value": "",
                          "description": "(Opcional) Umbral de ejecución de ingresos (por defecto 100).",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Compara el presupuesto (por defecto el `approved` del año) con lo real de partidas PROCESADAS, por centro y cuenta. `status`: `exceeded` (costo/gasto con ejecución mayor que `expense_threshold`, o real sin presupuesto), `under` (ingreso con ejecución menor que `income_threshold`) u `ok`.\n\nPermiso requerido: `accounting.budgets`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `fiscal_year` | integer | No | Año (por defecto el actual). |\n| `budget_id` | string (uuid) | No | Presupuesto a comparar (por defecto el aprobado del año). |\n| `month_from` | integer | No | Mes inicial (1-12). |\n| `month_to` | integer | No | Mes final (1-12). |\n| `cost_center_ids[]` | array de string | No | Centros a incluir (repetible). Sin él, todo el árbol. |\n| `include_children` | boolean | No | Incluye los subcentros (por defecto true). |\n| `depth` | integer | No | Agrupa las cuentas al ancestro de ese nivel. |\n| `branch_id` | string (uuid) | No | Limita lo real a una sucursal. |\n| `expense_threshold` | number | No | Umbral de ejecución de costos y gastos (por defecto 100). |\n| `income_threshold` | number | No | Umbral de ejecución de ingresos (por defecto 100). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` o `excel` (descarga presupuesto-vs-real-AAAA). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets` o desactivada.\n- `422`: Sin presupuesto aprobado o formato inválido."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"budget_id\": [\n      \"No hay un presupuesto aprobado para 2026.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Guardar líneas del presupuesto",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets/:id/lines",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets",
                    ":id",
                    "lines"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{budget_id}}",
                      "description": "ID del presupuesto"
                    }
                  ]
                },
                "description": "Upsert por centro, cuenta y mes. Con `replace: false` (por defecto) un `amount: 0` borra la celda; con `replace: true` reemplaza todas las líneas. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `lines` | array de object | Sí |  |\n| `replace` | boolean | No | true = reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"replace\": false,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 3,\n      \"amount\": 150\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id/lines",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id",
                        "lines"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Upsert por centro, cuenta y mes. Con `replace: false` (por defecto) un `amount: 0` borra la celda; con `replace: true` reemplaza todas las líneas. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `lines` | array de object | Sí |  |\n| `replace` | boolean | No | true = reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"replace\": false,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 3,\n      \"amount\": 150\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Presupuesto 2026\",\n    \"fiscal_year\": 2026,\n    \"status\": \"draft\",\n    \"notes\": null,\n    \"lines_count\": 1,\n    \"total_amount\": 100.0,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"month\": 1,\n        \"amount\": 100.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        },\n        \"account\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"6102\",\n          \"name\": \"Papelería\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Validación o presupuesto no editable",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id/lines",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id",
                        "lines"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Upsert por centro, cuenta y mes. Con `replace: false` (por defecto) un `amount: 0` borra la celda; con `replace: true` reemplaza todas las líneas. Solo en `draft`.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `lines` | array de object | Sí |  |\n| `replace` | boolean | No | true = reemplaza todas las líneas. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación o presupuesto no editable.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"replace\": false,\n  \"lines\": [\n    {\n      \"cost_center_id\": \"{{cost_center_id}}\",\n      \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"month\": 3,\n      \"amount\": 150\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"Solo se puede modificar un presupuesto en borrador.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Cambiar estado del presupuesto",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/budgets/:id/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "budgets",
                    ":id",
                    "status"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{budget_id}}",
                      "description": "ID del presupuesto"
                    }
                  ]
                },
                "description": "Solo puede haber un `approved` por año.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `draft`, `approved`, `closed` | Sí | Nuevo estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Estado inválido u otro aprobado del mismo año.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"approved\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id/status",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id",
                        "status"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Solo puede haber un `approved` por año.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `draft`, `approved`, `closed` | Sí | Nuevo estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Estado inválido u otro aprobado del mismo año.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"status\": \"approved\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n    \"name\": \"Presupuesto 2026\",\n    \"fiscal_year\": 2026,\n    \"status\": \"approved\",\n    \"notes\": null,\n    \"lines_count\": 1,\n    \"total_amount\": 100.0,\n    \"created_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"updated_at\": \"2026-10-08T15:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"account_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"month\": 1,\n        \"amount\": 100.0,\n        \"cost_center\": {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"code\": \"0101\",\n          \"name\": \"Ventas San Salvador\"\n        },\n        \"account\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"code\": \"6102\",\n          \"name\": \"Papelería\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Estado inválido u otro aprobado del mismo año",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/budgets/:id/status",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "budgets",
                        ":id",
                        "status"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{budget_id}}",
                          "description": "ID del presupuesto"
                        }
                      ]
                    },
                    "description": "Solo puede haber un `approved` por año.\n\nPermiso requerido: `accounting.budgets.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `draft`, `approved`, `closed` | Sí | Nuevo estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.budgets.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Estado inválido u otro aprobado del mismo año.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"status\": \"approved\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"Ya existe un presupuesto aprobado para 2026.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Reportes",
          "item": [
            {
              "name": "Obtener balance general",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/balance-sheet?as_of_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "balance-sheet"
                  ],
                  "query": [
                    {
                      "key": "as_of_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha de corte."
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Opcional: limita a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "depth",
                      "value": "1",
                      "description": "(Opcional) Nivel de detalle (1-10).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Activos, pasivos y patrimonio a la fecha.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/balance-sheet?as_of_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "balance-sheet"
                      ],
                      "query": [
                        {
                          "key": "as_of_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha de corte."
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Activos, pasivos y patrimonio a la fecha.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"title\": \"Balance General\",\n    \"as_of_date\": \"31/10/2026\",\n    \"assets\": [\n      {\n        \"code\": \"11\",\n        \"name\": \"Activo corriente\",\n        \"balance\": 85000.0,\n        \"level\": 2\n      }\n    ],\n    \"liabilities\": [\n      {\n        \"code\": \"21\",\n        \"name\": \"Pasivo corriente\",\n        \"balance\": 30000.0,\n        \"level\": 2\n      }\n    ],\n    \"equity\": [\n      {\n        \"code\": \"31\",\n        \"name\": \"Capital social\",\n        \"balance\": 35000.0,\n        \"level\": 2\n      }\n    ],\n    \"current_earnings\": 20000.0,\n    \"total_assets\": 85000.0,\n    \"total_liabilities\": 30000.0,\n    \"total_equity\": 55000.0,\n    \"total_liabilities_equity\": 85000.0,\n    \"detail_level\": 2,\n    \"generated_at\": \"31/10/2026 18:20:05\"\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/balance-sheet?as_of_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "balance-sheet"
                      ],
                      "query": [
                        {
                          "key": "as_of_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha de corte."
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Activos, pasivos y patrimonio a la fecha.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Obtener estado de resultados",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/income-statement?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "income-statement"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Opcional: limita a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "depth",
                      "value": "1",
                      "description": "(Opcional) Nivel de detalle (1-10).",
                      "disabled": true
                    },
                    {
                      "key": "cost_center_id",
                      "value": "{{cost_center_id}}",
                      "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                      "disabled": true
                    },
                    {
                      "key": "include_children",
                      "value": "true",
                      "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Ingresos, costos y gastos del período.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/income-statement?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "income-statement"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_id",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Ingresos, costos y gastos del período.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"title\": \"Estado de Resultados\",\n    \"date_from\": \"01/01/2026\",\n    \"date_to\": \"31/10/2026\",\n    \"income\": [\n      {\n        \"code\": \"41\",\n        \"name\": \"Ingresos por ventas\",\n        \"amount\": 120000.0,\n        \"level\": 2\n      }\n    ],\n    \"costs\": [\n      {\n        \"code\": \"51\",\n        \"name\": \"Costo de ventas\",\n        \"amount\": 70000.0,\n        \"level\": 2\n      }\n    ],\n    \"expenses\": [\n      {\n        \"code\": \"61\",\n        \"name\": \"Gastos de operación\",\n        \"amount\": 30000.0,\n        \"level\": 2\n      }\n    ],\n    \"total_income\": 120000.0,\n    \"total_costs\": 70000.0,\n    \"total_expenses\": 30000.0,\n    \"gross_profit\": 50000.0,\n    \"operating_income\": 20000.0,\n    \"net_income\": 20000.0,\n    \"detail_level\": 2,\n    \"generated_at\": \"31/10/2026 18:20:05\"\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/income-statement?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "income-statement"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_id",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Ingresos, costos y gastos del período.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Obtener estado de resultados por centro de costo",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/income-statement-by-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "income-statement-by-cost-center"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                    },
                    {
                      "key": "cost_center_ids[]",
                      "value": "{{cost_center_id}}",
                      "description": "(Opcional) Centros que serán columnas (repetible).",
                      "disabled": true
                    },
                    {
                      "key": "parent_cost_center_id",
                      "value": "",
                      "description": "(Opcional) Sin cost_center_ids: las columnas son los subcentros directos de este centro.",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Opcional: limita a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "depth",
                      "value": "1",
                      "description": "(Opcional) Nivel de detalle (1-10).",
                      "disabled": true
                    },
                    {
                      "key": "format",
                      "value": "json",
                      "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Una columna por centro (cada una suma su subárbol) más `none` (Sin centro), `other` (Otros centros, si hay movimientos de centros no incluidos) y `total`, que coincide con el Estado de resultados. Sin `cost_center_ids` ni `parent_cost_center_id`, las columnas son los centros raíz.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `cost_center_ids[]` | array de string | No | Centros que serán columnas (repetible). |\n| `parent_cost_center_id` | string (uuid) | No | Sin cost_center_ids: las columnas son los subcentros directos de este centro. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/income-statement-by-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "income-statement-by-cost-center"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "cost_center_ids[]",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Centros que serán columnas (repetible).",
                          "disabled": true
                        },
                        {
                          "key": "parent_cost_center_id",
                          "value": "",
                          "description": "(Opcional) Sin cost_center_ids: las columnas son los subcentros directos de este centro.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Una columna por centro (cada una suma su subárbol) más `none` (Sin centro), `other` (Otros centros, si hay movimientos de centros no incluidos) y `total`, que coincide con el Estado de resultados. Sin `cost_center_ids` ni `parent_cost_center_id`, las columnas son los centros raíz.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `cost_center_ids[]` | array de string | No | Centros que serán columnas (repetible). |\n| `parent_cost_center_id` | string (uuid) | No | Sin cost_center_ids: las columnas son los subcentros directos de este centro. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"title\": \"Estado de resultados por centro de costo\",\n    \"date_from\": \"01/10/2026\",\n    \"date_to\": \"31/10/2026\",\n    \"detail_level\": 3,\n    \"columns\": [\n      {\n        \"key\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"code\": \"01\",\n        \"name\": \"Ventas\"\n      },\n      {\n        \"key\": \"none\",\n        \"id\": null,\n        \"code\": null,\n        \"name\": \"Sin centro\"\n      },\n      {\n        \"key\": \"total\",\n        \"id\": null,\n        \"code\": null,\n        \"name\": \"Total\"\n      }\n    ],\n    \"income\": [\n      {\n        \"code\": \"5\",\n        \"name\": \"Ingresos\",\n        \"level\": 1,\n        \"amounts\": {\n          \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\": 100.0,\n          \"none\": 20.0,\n          \"total\": 120.0\n        }\n      }\n    ],\n    \"costs\": [],\n    \"expenses\": [\n      {\n        \"code\": \"6\",\n        \"name\": \"Gastos\",\n        \"level\": 1,\n        \"amounts\": {\n          \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\": 40.0,\n          \"none\": 0,\n          \"total\": 40.0\n        }\n      }\n    ],\n    \"totals\": {\n      \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\": {\n        \"income\": 100.0,\n        \"costs\": 0,\n        \"expenses\": 40.0,\n        \"gross_profit\": 100.0,\n        \"net_income\": 60.0\n      },\n      \"none\": {\n        \"income\": 20.0,\n        \"costs\": 0,\n        \"expenses\": 0,\n        \"gross_profit\": 20.0,\n        \"net_income\": 20.0\n      },\n      \"total\": {\n        \"income\": 120.0,\n        \"costs\": 0,\n        \"expenses\": 40.0,\n        \"gross_profit\": 120.0,\n        \"net_income\": 80.0\n      }\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/income-statement-by-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "income-statement-by-cost-center"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "cost_center_ids[]",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Centros que serán columnas (repetible).",
                          "disabled": true
                        },
                        {
                          "key": "parent_cost_center_id",
                          "value": "",
                          "description": "(Opcional) Sin cost_center_ids: las columnas son los subcentros directos de este centro.",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Una columna por centro (cada una suma su subárbol) más `none` (Sin centro), `other` (Otros centros, si hay movimientos de centros no incluidos) y `total`, que coincide con el Estado de resultados. Sin `cost_center_ids` ni `parent_cost_center_id`, las columnas son los centros raíz.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `cost_center_ids[]` | array de string | No | Centros que serán columnas (repetible). |\n| `parent_cost_center_id` | string (uuid) | No | Sin cost_center_ids: las columnas son los subcentros directos de este centro. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar movimientos sin centro de costo",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/movements-without-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "movements-without-cost-center"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                    },
                    {
                      "key": "status",
                      "value": "all",
                      "description": "(Opcional) Estado de las partidas (por defecto all = borradores y procesadas).",
                      "disabled": true
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Opcional: limita a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "format",
                      "value": "json",
                      "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Líneas de partida sin centro en cuentas con política `optional` o `required`, para corregirlas antes del cierre. Incluye borradores salvo que se filtre por `status`.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `status` | string: `all`, `BORRADOR`, `PROCESADA` | No | Estado de las partidas (por defecto all = borradores y procesadas). |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/movements-without-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "movements-without-cost-center"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "status",
                          "value": "all",
                          "description": "(Opcional) Estado de las partidas (por defecto all = borradores y procesadas).",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Líneas de partida sin centro en cuentas con política `optional` o `required`, para corregirlas antes del cierre. Incluye borradores salvo que se filtre por `status`.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `status` | string: `all`, `BORRADOR`, `PROCESADA` | No | Estado de las partidas (por defecto all = borradores y procesadas). |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"rows\": [\n      {\n        \"journal_entry_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"entry_code\": \"DIA-2026-10-0042\",\n        \"entry_date\": \"2026-10-05\",\n        \"status\": \"PROCESADA\",\n        \"description\": \"Compra de papelería\",\n        \"detail_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"account_code\": \"6102\",\n        \"account_name\": \"Papelería\",\n        \"policy\": \"required\",\n        \"debit\": 100.0,\n        \"credit\": 0,\n        \"reference_detail\": \"Papelería\"\n      }\n    ],\n    \"by_account\": [\n      {\n        \"account_code\": \"6102\",\n        \"account_name\": \"Papelería\",\n        \"policy\": \"required\",\n        \"lines\": 1,\n        \"debit\": 100.0,\n        \"credit\": 0\n      }\n    ],\n    \"total_lines\": 1\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/movements-without-cost-center?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "movements-without-cost-center"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)."
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD), mayor o igual que start_date."
                        },
                        {
                          "key": "status",
                          "value": "all",
                          "description": "(Opcional) Estado de las partidas (por defecto all = borradores y procesadas).",
                          "disabled": true
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "format",
                          "value": "json",
                          "description": "(Opcional) `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Líneas de partida sin centro en cuentas con política `optional` o `required`, para corregirlas antes del cierre. Incluye borradores salvo que se filtre por `status`.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD). |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD), mayor o igual que start_date. |\n| `status` | string: `all`, `BORRADOR`, `PROCESADA` | No | Estado de las partidas (por defecto all = borradores y procesadas). |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `format` | string: `json`, `pdf`, `excel` | No | `json` (por defecto), `pdf` (application/pdf) o `excel` (.xlsx). Con pdf/excel la respuesta es el archivo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Obtener balanza de comprobación",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/accounting/reports/trial-balance?as_of_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "accounting",
                    "reports",
                    "trial-balance"
                  ],
                  "query": [
                    {
                      "key": "as_of_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha de corte."
                    },
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Opcional) Opcional: limita a una sucursal.",
                      "disabled": true
                    },
                    {
                      "key": "depth",
                      "value": "1",
                      "description": "(Opcional) Nivel de detalle (1-10).",
                      "disabled": true
                    },
                    {
                      "key": "cost_center_id",
                      "value": "{{cost_center_id}}",
                      "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                      "disabled": true
                    },
                    {
                      "key": "include_children",
                      "value": "true",
                      "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                      "disabled": true
                    }
                  ]
                },
                "description": "Saldos por cuenta a la fecha. Solo partidas PROCESADAS.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/trial-balance?as_of_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "trial-balance"
                      ],
                      "query": [
                        {
                          "key": "as_of_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha de corte."
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_id",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Saldos por cuenta a la fecha. Solo partidas PROCESADAS.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"title\": \"Balanza de Comprobación\",\n    \"as_of_date\": \"31/10/2026\",\n    \"accounts\": [\n      {\n        \"code\": \"1101\",\n        \"name\": \"Efectivo y equivalentes\",\n        \"level\": 3,\n        \"sum_debit\": 15200.0,\n        \"sum_credit\": 9800.0,\n        \"debit_balance\": 5400.0,\n        \"credit_balance\": 0\n      }\n    ],\n    \"total_sum_debit\": 152340.1,\n    \"total_sum_credit\": 152340.1,\n    \"total_debit_balance\": 80450.0,\n    \"total_credit_balance\": 80450.0,\n    \"detail_level\": 4,\n    \"generated_at\": \"31/10/2026 18:20:05\"\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/accounting/reports/trial-balance?as_of_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "accounting",
                        "reports",
                        "trial-balance"
                      ],
                      "query": [
                        {
                          "key": "as_of_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha de corte."
                        },
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Opcional) Opcional: limita a una sucursal.",
                          "disabled": true
                        },
                        {
                          "key": "depth",
                          "value": "1",
                          "description": "(Opcional) Nivel de detalle (1-10).",
                          "disabled": true
                        },
                        {
                          "key": "cost_center_id",
                          "value": "{{cost_center_id}}",
                          "description": "(Opcional) Opcional: solo líneas de ese centro de costo (de otro negocio -> 404).",
                          "disabled": true
                        },
                        {
                          "key": "include_children",
                          "value": "true",
                          "description": "(Opcional) Con cost_center_id, incluye sus subcentros (por defecto true).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Saldos por cuenta a la fecha. Solo partidas PROCESADAS.\n\nPermiso requerido: `accounting.reports`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `as_of_date` | string (date) | Sí | Fecha de corte. |\n| `branch_id` | string | No | Opcional: limita a una sucursal. |\n| `depth` | integer | No | Nivel de detalle (1-10). |\n| `cost_center_id` | string (uuid) | No | Opcional: solo líneas de ese centro de costo (de otro negocio -> 404). |\n| `include_children` | boolean | No | Con cost_center_id, incluye sus subcentros (por defecto true). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `accounting.reports` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "Proyectos",
      "description": "Proyectos con su resumen financiero y vinculación de ventas, compras y planillas.",
      "item": [
        {
          "name": "Listar proyectos",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/projects",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "projects"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "planned",
                  "description": "(Opcional) Estado.",
                  "disabled": true
                },
                {
                  "key": "customer_id",
                  "value": "{{customer_id}}",
                  "description": "(Opcional) Filtra por cliente.",
                  "disabled": true
                },
                {
                  "key": "search",
                  "value": "",
                  "description": "(Opcional) Busca por nombre (máx. 100).",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "50",
                  "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "(Opcional) Página.",
                  "disabled": true
                }
              ]
            },
            "description": "Proyectos del negocio (no eliminados), del más reciente al más antiguo por fecha de inicio. Paginado.\n\nPermiso requerido: `projects`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `search` | string | No | Busca por nombre (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `422`: Error de validación."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects"
                  ],
                  "query": [
                    {
                      "key": "status",
                      "value": "planned",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "customer_id",
                      "value": "{{customer_id}}",
                      "description": "(Opcional) Filtra por cliente.",
                      "disabled": true
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Proyectos del negocio (no eliminados), del más reciente al más antiguo por fecha de inicio. Paginado.\n\nPermiso requerido: `projects`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `search` | string | No | Busca por nombre (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `422`: Error de validación."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"name\": \"Remodelación oficinas Grupo ABC\",\n        \"status\": \"in_progress\",\n        \"customer\": {\n          \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n          \"name\": \"Grupo ABC S.A. de C.V.\"\n        },\n        \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"start_date\": \"2026-09-01\",\n        \"end_date\": \"2026-12-15\",\n        \"budget\": 25000.0,\n        \"description\": \"Obra civil y mobiliario\",\n        \"quotation_id\": null,\n        \"created_at\": \"2026-08-28T11:00:00-06:00\"\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects"
                  ],
                  "query": [
                    {
                      "key": "status",
                      "value": "planned",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "customer_id",
                      "value": "{{customer_id}}",
                      "description": "(Opcional) Filtra por cliente.",
                      "disabled": true
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre (máx. 100).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Proyectos del negocio (no eliminados), del más reciente al más antiguo por fecha de inicio. Paginado.\n\nPermiso requerido: `projects`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `customer_id` | string (uuid) | No | Filtra por cliente. |\n| `search` | string | No | Busca por nombre (máx. 100). |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `422`: Error de validación."
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"status\": [\n      \"The selected status is invalid.\"\n    ]\n  }\n}"
            }
          ]
        },
        {
          "name": "Crear proyecto",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
              }
            ],
            "url": {
              "raw": "{{base_url}}/projects",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "projects"
              ]
            },
            "description": "Crea un proyecto. El cliente y la sucursal deben pertenecer al negocio.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `customer_id` | string (uuid) | Sí | Cliente del negocio. |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | Sí | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Remodelación oficinas Grupo ABC\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"start_date\": \"2026-09-01\",\n  \"end_date\": \"2026-12-15\",\n  \"budget\": 25000.0,\n  \"status\": \"in_progress\",\n  \"description\": \"Obra civil y mobiliario\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "201 Proyecto creado",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects"
                  ]
                },
                "description": "Crea un proyecto. El cliente y la sucursal deben pertenecer al negocio.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `customer_id` | string (uuid) | Sí | Cliente del negocio. |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | Sí | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Remodelación oficinas Grupo ABC\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"start_date\": \"2026-09-01\",\n  \"end_date\": \"2026-12-15\",\n  \"budget\": 25000.0,\n  \"status\": \"in_progress\",\n  \"description\": \"Obra civil y mobiliario\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Remodelación oficinas Grupo ABC\",\n    \"status\": \"in_progress\",\n    \"customer\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Grupo ABC S.A. de C.V.\"\n    },\n    \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"start_date\": \"2026-09-01\",\n    \"end_date\": \"2026-12-15\",\n    \"budget\": 25000.0,\n    \"description\": \"Obra civil y mobiliario\",\n    \"quotation_id\": null,\n    \"created_at\": \"2026-08-28T11:00:00-06:00\"\n  }\n}"
            },
            {
              "name": "422 Error de validación o cliente/sucursal de otro negocio",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "Opcional. Llave única por operación (máximo 100 caracteres, vigente 24 h). Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original sin repetir la operación."
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects"
                  ]
                },
                "description": "Crea un proyecto. El cliente y la sucursal deben pertenecer al negocio.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `customer_id` | string (uuid) | Sí | Cliente del negocio. |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | Sí | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- Admite el encabezado `Idempotency-Key`: un reintento con la misma llave y el mismo cuerpo no repite la operación (la respuesta lleva `Idempotent-Replayed: true`); con otro cuerpo, o mientras la primera sigue en proceso, responde `409`.\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `409`: Conflicto de idempotencia.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Remodelación oficinas Grupo ABC\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"branch_id\": \"{{branch_id}}\",\n  \"start_date\": \"2026-09-01\",\n  \"end_date\": \"2026-12-15\",\n  \"budget\": 25000.0,\n  \"status\": \"in_progress\",\n  \"description\": \"Obra civil y mobiliario\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Customer not found\"\n}"
            }
          ]
        },
        {
          "name": "Consultar proyecto",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/projects/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "projects",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{project_id}}",
                  "description": "ID del proyecto"
                }
              ]
            },
            "description": "Detalle del proyecto con su resumen financiero: ventas, compras, planillas, órdenes de trabajo, utilidad, margen y avance del presupuesto.\n\nPermiso requerido: `projects`\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `404`: No encontrado o de otro negocio."
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Detalle del proyecto con su resumen financiero: ventas, compras, planillas, órdenes de trabajo, utilidad, margen y avance del presupuesto.\n\nPermiso requerido: `projects`\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Remodelación oficinas Grupo ABC\",\n    \"status\": \"in_progress\",\n    \"customer\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Grupo ABC S.A. de C.V.\"\n    },\n    \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"start_date\": \"2026-09-01\",\n    \"end_date\": \"2026-12-15\",\n    \"budget\": 25000.0,\n    \"description\": \"Obra civil y mobiliario\",\n    \"quotation_id\": null,\n    \"created_at\": \"2026-08-28T11:00:00-06:00\",\n    \"summary\": {\n      \"total_sales\": 12000.0,\n      \"total_expenses\": 6500.0,\n      \"total_payroll\": 2100.0,\n      \"total_work_orders\": 400.0,\n      \"total_costs\": 9000.0,\n      \"profit\": 3000.0,\n      \"margin_percent\": 25.0,\n      \"budget\": 25000.0,\n      \"budget_used_percent\": 36.0,\n      \"counts\": {\n        \"sales\": 3,\n        \"expenses\": 8,\n        \"payrolls\": 2,\n        \"work_orders\": 1\n      }\n    }\n  }\n}"
            },
            {
              "name": "404 No encontrado o de otro negocio",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Detalle del proyecto con su resumen financiero: ventas, compras, planillas, órdenes de trabajo, utilidad, margen y avance del presupuesto.\n\nPermiso requerido: `projects`\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects` o desactivada.\n- `404`: No encontrado o de otro negocio."
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Project not found\"\n}"
            }
          ]
        },
        {
          "name": "Actualizar proyecto",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/projects/:id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "projects",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{project_id}}",
                  "description": "ID del proyecto"
                }
              ]
            },
            "description": "Actualiza solo los campos enviados.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `customer_id` | string (uuid) | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | No |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"completed\",\n  \"end_date\": \"2026-12-10\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Proyecto actualizado",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Actualiza solo los campos enviados.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `customer_id` | string (uuid) | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | No |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"completed\",\n  \"end_date\": \"2026-12-10\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Remodelación oficinas Grupo ABC\",\n    \"status\": \"completed\",\n    \"customer\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"name\": \"Grupo ABC S.A. de C.V.\"\n    },\n    \"branch_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"start_date\": \"2026-09-01\",\n    \"end_date\": \"2026-12-15\",\n    \"budget\": 25000.0,\n    \"description\": \"Obra civil y mobiliario\",\n    \"quotation_id\": null,\n    \"created_at\": \"2026-08-28T11:00:00-06:00\"\n  }\n}"
            },
            {
              "name": "422 Error de validación o cliente/sucursal de otro negocio",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Actualiza solo los campos enviados.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `customer_id` | string (uuid) | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_date` | string (date) | No |  |\n| `end_date` | string (date) | No |  |\n| `budget` | number | No |  |\n| `status` | string: `planned`, `in_progress`, `completed`, `on_hold`, `cancelled` | No | Estado. |\n| `description` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación o cliente/sucursal de otro negocio.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"completed\",\n  \"end_date\": \"2026-12-10\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Branch not found\"\n}"
            }
          ]
        },
        {
          "name": "Vincular documentos",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/projects/:id/items",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "projects",
                ":id",
                "items"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{project_id}}",
                  "description": "ID del proyecto"
                }
              ]
            },
            "description": "Vincula ventas, compras o planillas; los IDs de otro negocio vuelven en `rejected_ids`.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `sale`, `expense`, `payroll` | Sí | Tipo de documento. |\n| `ids` | array de string | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"sale\",\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Éxito",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id/items",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id",
                    "items"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Vincula ventas, compras o planillas; los IDs de otro negocio vuelven en `rejected_ids`.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `sale`, `expense`, `payroll` | Sí | Tipo de documento. |\n| `ids` | array de string | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"sale\",\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": true,\n  \"data\": {\n    \"linked\": 2,\n    \"rejected_ids\": [\n      \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n    ],\n    \"summary\": {\n      \"total_sales\": 12000.0,\n      \"total_expenses\": 6500.0,\n      \"total_payroll\": 2100.0,\n      \"total_work_orders\": 400.0,\n      \"total_costs\": 9000.0,\n      \"profit\": 3000.0,\n      \"margin_percent\": 25.0,\n      \"budget\": 25000.0,\n      \"budget_used_percent\": 36.0,\n      \"counts\": {\n        \"sales\": 3,\n        \"expenses\": 8,\n        \"payrolls\": 2,\n        \"work_orders\": 1\n      }\n    }\n  }\n}"
            },
            {
              "name": "422 Error de validación",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/projects/:id/items",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "projects",
                    ":id",
                    "items"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{project_id}}",
                      "description": "ID del proyecto"
                    }
                  ]
                },
                "description": "Vincula ventas, compras o planillas; los IDs de otro negocio vuelven en `rejected_ids`.\n\nPermiso requerido: `projects.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `type` | string: `sale`, `expense`, `payroll` | Sí | Tipo de documento. |\n| `ids` | array de string | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `projects.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"sale\",\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"type\": [\n      \"The selected type is invalid.\"\n    ]\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Recursos Humanos",
      "description": "Empleados, asistencia, horarios, reglas laborales, feriados, permisos y planillas.",
      "item": [
        {
          "name": "Empleados",
          "item": [
            {
              "name": "Listar empleados",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/employees",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "employees"
                  ],
                  "query": [
                    {
                      "key": "is_active",
                      "value": "true",
                      "description": "(Opcional) 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos.",
                      "disabled": true
                    },
                    {
                      "key": "search",
                      "value": "",
                      "description": "(Opcional) Busca por nombre, apellido o correo.",
                      "disabled": true
                    },
                    {
                      "key": "document_number",
                      "value": "01234567-8",
                      "description": "(Opcional) Número de documento exacto.",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "50",
                      "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "1",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Empleados del negocio, paginado. Incluye datos personales y salario.\n\nPermiso requerido: `hr.employees`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `is_active` | boolean | No | 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos. |\n| `search` | string | No | Busca por nombre, apellido o correo. |\n| `document_number` | string | No | Número de documento exacto. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees"
                      ],
                      "query": [
                        {
                          "key": "is_active",
                          "value": "true",
                          "description": "(Opcional) 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos.",
                          "disabled": true
                        },
                        {
                          "key": "search",
                          "value": "",
                          "description": "(Opcional) Busca por nombre, apellido o correo.",
                          "disabled": true
                        },
                        {
                          "key": "document_number",
                          "value": "01234567-8",
                          "description": "(Opcional) Número de documento exacto.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Empleados del negocio, paginado. Incluye datos personales y salario.\n\nPermiso requerido: `hr.employees`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `is_active` | boolean | No | 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos. |\n| `search` | string | No | Busca por nombre, apellido o correo. |\n| `document_number` | string | No | Número de documento exacto. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"first_name\": \"María\",\n        \"last_name\": \"López\",\n        \"document_type\": \"DUI\",\n        \"document_number\": \"01234567-8\",\n        \"tax_number\": \"0614-010190-101-1\",\n        \"email\": \"maria@empresa.com\",\n        \"phone\": \"7000-0000\",\n        \"type\": \"permanent\",\n        \"job_title\": \"Contadora\",\n        \"hire_date\": \"2024-02-01\",\n        \"salary\": 850.0,\n        \"employment_relationship\": \"labor\",\n        \"pay_type\": \"salaried\",\n        \"hourly_rate\": null,\n        \"is_active\": true\n      }\n    ],\n    \"pagination\": {\n      \"current_page\": 1,\n      \"last_page\": 1,\n      \"per_page\": 50,\n      \"total\": 1\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees"
                      ],
                      "query": [
                        {
                          "key": "is_active",
                          "value": "true",
                          "description": "(Opcional) 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos.",
                          "disabled": true
                        },
                        {
                          "key": "search",
                          "value": "",
                          "description": "(Opcional) Busca por nombre, apellido o correo.",
                          "disabled": true
                        },
                        {
                          "key": "document_number",
                          "value": "01234567-8",
                          "description": "(Opcional) Número de documento exacto.",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "50",
                          "description": "(Opcional) Resultados por página (1-200, por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "1",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Empleados del negocio, paginado. Incluye datos personales y salario.\n\nPermiso requerido: `hr.employees`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `is_active` | boolean | No | 1 = activos, 0 = inactivos. Sin el parámetro devuelve ambos. |\n| `search` | string | No | Busca por nombre, apellido o correo. |\n| `document_number` | string | No | Número de documento exacto. |\n| `per_page` | integer | No | Resultados por página (1-200, por defecto 50). |\n| `page` | integer | No | Página. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear empleado",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/employees",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "employees"
                  ]
                },
                "description": "Da de alta un empleado. El número de documento debe ser único en el negocio.\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | Sí |  |\n| `last_name` | string | Sí |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | Sí | Tipo de contratación. |\n| `hire_date` | string (date) | Sí | Fecha de ingreso. |\n| `salary` | number | Sí | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `409`: Documento duplicado.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"first_name\": \"María\",\n  \"last_name\": \"López\",\n  \"document_type\": \"DUI\",\n  \"document_number\": \"01234567-8\",\n  \"tax_number\": \"0614-010190-101-1\",\n  \"email\": \"maria@empresa.com\",\n  \"phone\": \"7000-0000\",\n  \"type\": \"permanent\",\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"manager_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"hire_date\": \"2026-10-01\",\n  \"salary\": 850,\n  \"bank_name\": \"Banco Agrícola\",\n  \"bank_account_type\": \"Ahorro\",\n  \"bank_account_number\": \"3000123456\",\n  \"employment_relationship\": \"labor\",\n  \"pay_type\": \"salaried\",\n  \"hourly_rate\": null\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Empleado creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees"
                      ]
                    },
                    "description": "Da de alta un empleado. El número de documento debe ser único en el negocio.\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | Sí |  |\n| `last_name` | string | Sí |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | Sí | Tipo de contratación. |\n| `hire_date` | string (date) | Sí | Fecha de ingreso. |\n| `salary` | number | Sí | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `409`: Documento duplicado.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"first_name\": \"María\",\n  \"last_name\": \"López\",\n  \"document_type\": \"DUI\",\n  \"document_number\": \"01234567-8\",\n  \"tax_number\": \"0614-010190-101-1\",\n  \"email\": \"maria@empresa.com\",\n  \"phone\": \"7000-0000\",\n  \"type\": \"permanent\",\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"manager_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"hire_date\": \"2026-10-01\",\n  \"salary\": 850.0,\n  \"bank_name\": \"Banco Agrícola\",\n  \"bank_account_type\": \"Ahorro\",\n  \"bank_account_number\": \"3000123456\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"first_name\": \"María\",\n    \"last_name\": \"López\",\n    \"document_type\": \"DUI\",\n    \"document_number\": \"01234567-8\",\n    \"tax_number\": \"0614-010190-101-1\",\n    \"email\": \"maria@empresa.com\",\n    \"phone\": \"7000-0000\",\n    \"type\": \"permanent\",\n    \"job_title\": \"Contadora\",\n    \"hire_date\": \"2024-02-01\",\n    \"salary\": 850.0,\n    \"employment_relationship\": \"labor\",\n    \"pay_type\": \"salaried\",\n    \"hourly_rate\": null,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees"
                      ]
                    },
                    "description": "Da de alta un empleado. El número de documento debe ser único en el negocio.\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | Sí |  |\n| `last_name` | string | Sí |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | Sí | Tipo de contratación. |\n| `hire_date` | string (date) | Sí | Fecha de ingreso. |\n| `salary` | number | Sí | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `409`: Documento duplicado.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"first_name\": \"María\",\n  \"last_name\": \"López\",\n  \"document_type\": \"DUI\",\n  \"document_number\": \"01234567-8\",\n  \"tax_number\": \"0614-010190-101-1\",\n  \"email\": \"maria@empresa.com\",\n  \"phone\": \"7000-0000\",\n  \"type\": \"permanent\",\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"manager_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"hire_date\": \"2026-10-01\",\n  \"salary\": 850.0,\n  \"bank_name\": \"Banco Agrícola\",\n  \"bank_account_type\": \"Ahorro\",\n  \"bank_account_number\": \"3000123456\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"first_name\": [\n      \"The first name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar puestos de trabajo",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/job-titles",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "job-titles"
                  ]
                },
                "description": "Catálogo de puestos para obtener el `job_title_id`.\n\nPermiso requerido: `hr.employees`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/job-titles",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "job-titles"
                      ]
                    },
                    "description": "Catálogo de puestos para obtener el `job_title_id`.\n\nPermiso requerido: `hr.employees`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Contadora\",\n      \"description\": \"Contabilidad general\",\n      \"parent_id\": null\n    }\n  ]\n}"
                }
              ]
            },
            {
              "name": "Consultar empleado",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/employees/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "employees",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{employee_id}}",
                      "description": "ID del empleado"
                    }
                  ]
                },
                "description": "Detalle de un empleado.\n\nPermiso requerido: `hr.employees`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{employee_id}}",
                          "description": "ID del empleado"
                        }
                      ]
                    },
                    "description": "Detalle de un empleado.\n\nPermiso requerido: `hr.employees`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"first_name\": \"María\",\n    \"last_name\": \"López\",\n    \"document_type\": \"DUI\",\n    \"document_number\": \"01234567-8\",\n    \"tax_number\": \"0614-010190-101-1\",\n    \"email\": \"maria@empresa.com\",\n    \"phone\": \"7000-0000\",\n    \"type\": \"permanent\",\n    \"job_title\": \"Contadora\",\n    \"hire_date\": \"2024-02-01\",\n    \"salary\": 850.0,\n    \"employment_relationship\": \"labor\",\n    \"pay_type\": \"salaried\",\n    \"hourly_rate\": null,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{employee_id}}",
                          "description": "ID del empleado"
                        }
                      ]
                    },
                    "description": "Detalle de un empleado.\n\nPermiso requerido: `hr.employees`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Actualizar empleado",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/employees/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "employees",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{employee_id}}",
                      "description": "ID del empleado"
                    }
                  ]
                },
                "description": "Actualiza solo los campos enviados. Para dar de baja envía `is_active: false` (no se eliminan empleados).\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | No |  |\n| `last_name` | string | No |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | No | Tipo de contratación. |\n| `hire_date` | string (date) | No | Fecha de ingreso. |\n| `salary` | number | No | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"salary\": 950.0,\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Empleado actualizado",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{employee_id}}",
                          "description": "ID del empleado"
                        }
                      ]
                    },
                    "description": "Actualiza solo los campos enviados. Para dar de baja envía `is_active: false` (no se eliminan empleados).\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | No |  |\n| `last_name` | string | No |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | No | Tipo de contratación. |\n| `hire_date` | string (date) | No | Fecha de ingreso. |\n| `salary` | number | No | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"salary\": 950.0,\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"first_name\": \"María\",\n    \"last_name\": \"López\",\n    \"document_type\": \"DUI\",\n    \"document_number\": \"01234567-8\",\n    \"tax_number\": \"0614-010190-101-1\",\n    \"email\": \"maria@empresa.com\",\n    \"phone\": \"7000-0000\",\n    \"type\": \"permanent\",\n    \"job_title\": \"Contadora\",\n    \"hire_date\": \"2024-02-01\",\n    \"salary\": 950.0,\n    \"employment_relationship\": \"labor\",\n    \"pay_type\": \"salaried\",\n    \"hourly_rate\": null,\n    \"is_active\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/employees/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "employees",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{employee_id}}",
                          "description": "ID del empleado"
                        }
                      ]
                    },
                    "description": "Actualiza solo los campos enviados. Para dar de baja envía `is_active: false` (no se eliminan empleados).\n\nPermiso requerido: `hr.employees.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `first_name` | string | No |  |\n| `last_name` | string | No |  |\n| `type` | string: `permanent`, `temporary`, `project_based` | No | Tipo de contratación. |\n| `hire_date` | string (date) | No | Fecha de ingreso. |\n| `salary` | number | No | Salario mensual. |\n| `document_type` | string | No |  |\n| `document_number` | string | No | Único en el negocio. |\n| `tax_number` | string | No | NIT. |\n| `email` | string | No |  |\n| `phone` | string | No |  |\n| `address` | string | No |  |\n| `birth_date` | string (date) | No |  |\n| `job_title_id` | string (uuid) | No | Puesto (GET /hr/job-titles). |\n| `manager_id` | string (uuid) | No | Jefe inmediato. |\n| `emergency_contact_name` | string | No |  |\n| `emergency_contact_phone` | string | No |  |\n| `bank_name` | string | No |  |\n| `bank_account_type` | string | No |  |\n| `bank_account_number` | string | No |  |\n| `is_active` | boolean | No | false para dar de baja. |\n| `employment_relationship` | string: `labor`, `services` | No | Vínculo: laboral o servicios profesionales. |\n| `pay_type` | string: `salaried`, `hourly`, `fee` | No | Modalidad de pago. |\n| `hourly_rate` | number | No | Tarifa por hora. Obligatoria si pay_type = hourly. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.employees.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"salary\": 950.0,\n  \"job_title_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"first_name\": [\n      \"The first name field is required.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Asistencia y resultados",
          "item": [
            {
              "name": "Listar resultados diarios de asistencia",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/attendance-results?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "attendance-results"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "employee_id",
                      "value": "{{employee_id}}",
                      "description": "(Opcional) Filtra por empleado.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "compliant",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Cumplimiento y horas clasificadas por empleado y día (máximo 93 días).\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `compliant`, `late`, `early_leave`, `late_and_early_leave`, `absent`, `incomplete`, `on_leave`, `holiday`, `rest_day`, `worked_on_rest_day`, `worked_on_holiday`, `no_schedule` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendance-results?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendance-results"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "compliant",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Cumplimiento y horas clasificadas por empleado y día (máximo 93 días).\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `compliant`, `late`, `early_leave`, `late_and_early_leave`, `absent`, `incomplete`, `on_leave`, `holiday`, `rest_day`, `worked_on_rest_day`, `worked_on_holiday`, `no_schedule` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_name\": \"María López\",\n      \"work_date\": \"2026-10-01\",\n      \"attendance_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"work_schedule_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"labor_rule_set_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"day_type\": \"regular\",\n      \"shift_kind\": \"day\",\n      \"status\": \"late\",\n      \"scheduled_minutes\": 480,\n      \"worked_minutes\": 590,\n      \"late_minutes\": 10,\n      \"early_leave_minutes\": 0,\n      \"ordinary_day_minutes\": 480,\n      \"ordinary_night_minutes\": 0,\n      \"overtime_day_minutes\": 110,\n      \"overtime_night_minutes\": 0,\n      \"breakdown\": [\n        {\n          \"category\": \"ordinary_day_regular\",\n          \"minutes\": 480,\n          \"multiplier\": 1,\n          \"amount\": 0\n        },\n        {\n          \"category\": \"overtime_day_regular\",\n          \"minutes\": 110,\n          \"multiplier\": 2,\n          \"amount\": 15.58\n        }\n      ],\n      \"warnings\": [],\n      \"is_locked\": false,\n      \"calculated_at\": \"2026-10-02 06:00:12\",\n      \"overtime_approval\": null,\n      \"overtime_pending_minutes\": 0,\n      \"overtime_rejected_minutes\": 0\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendance-results?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendance-results"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "compliant",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Cumplimiento y horas clasificadas por empleado y día (máximo 93 días).\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `compliant`, `late`, `early_leave`, `late_and_early_leave`, `absent`, `incomplete`, `on_leave`, `holiday`, `rest_day`, `worked_on_rest_day`, `worked_on_holiday`, `no_schedule` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar asistencia",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/attendances?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "attendances"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "employee_id",
                      "value": "{{employee_id}}",
                      "description": "(Opcional) Filtra por empleado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Marcaciones del rango (máximo 93 días).\n\nPermiso requerido: `hr.attendances`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendances?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendances"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Marcaciones del rango (máximo 93 días).\n\nPermiso requerido: `hr.attendances`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_name\": \"María López\",\n      \"document_number\": \"01234567-8\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:02\",\n      \"check_out\": \"17:05\",\n      \"check_in_at\": \"2026-10-01 08:02\",\n      \"check_out_at\": \"2026-10-01 17:05\",\n      \"notes\": null\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendances?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendances"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Marcaciones del rango (máximo 93 días).\n\nPermiso requerido: `hr.attendances`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Enviar marcaciones",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/attendances",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "attendances"
                  ]
                },
                "description": "Registra hasta 500 marcaciones. Idempotente: un registro existente del empleado en esa fecha se actualiza. Acepta check_in/check_out (HH:MM), check_in_at/check_out_at (YYYY-MM-DD HH:MM, admiten salida al día siguiente) o punches. Cada registro se procesa por separado; si todos fallan la respuesta es 422.\n\nPermiso requerido: `hr.attendances`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `records` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"records\": [\n    {\n      \"document_number\": \"01234567-8\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:02\",\n      \"check_out\": \"17:05\"\n    },\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"07:55\",\n      \"check_out\": \"18:30\",\n      \"notes\": \"Cierre de mes\"\n    },\n    {\n      \"document_number\": \"98765432-1\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:10\"\n    },\n    {\n      \"document_number\": \"45678912-3\",\n      \"date\": \"2026-10-01\",\n      \"check_in_at\": \"2026-10-01 22:00\",\n      \"check_out_at\": \"2026-10-02 06:05\"\n    },\n    {\n      \"document_number\": \"11223344-5\",\n      \"date\": \"2026-10-01\",\n      \"punches\": [\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 08:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 12:00\"\n        },\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 13:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 17:02\"\n        }\n      ]\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendances",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendances"
                      ]
                    },
                    "description": "Registra hasta 500 marcaciones. Idempotente: un registro existente del empleado en esa fecha se actualiza. Acepta check_in/check_out (HH:MM), check_in_at/check_out_at (YYYY-MM-DD HH:MM, admiten salida al día siguiente) o punches. Cada registro se procesa por separado; si todos fallan la respuesta es 422.\n\nPermiso requerido: `hr.attendances`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `records` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"records\": [\n    {\n      \"document_number\": \"01234567-8\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:02\",\n      \"check_out\": \"17:05\"\n    },\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"07:55\",\n      \"check_out\": \"18:30\",\n      \"notes\": \"Cierre de mes\"\n    },\n    {\n      \"document_number\": \"98765432-1\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:10\"\n    },\n    {\n      \"document_number\": \"45678912-3\",\n      \"date\": \"2026-10-01\",\n      \"check_in_at\": \"2026-10-01 22:00\",\n      \"check_out_at\": \"2026-10-02 06:05\"\n    },\n    {\n      \"document_number\": \"11223344-5\",\n      \"date\": \"2026-10-01\",\n      \"punches\": [\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 08:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 12:00\"\n        },\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 13:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 17:02\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"created\": 2,\n    \"updated\": 0,\n    \"failed\": 1,\n    \"results\": [\n      {\n        \"index\": 0,\n        \"status\": \"created\",\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n      },\n      {\n        \"index\": 1,\n        \"status\": \"created\",\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n      },\n      {\n        \"index\": 2,\n        \"status\": \"error\",\n        \"message\": \"Employee not found (send a valid employee_id or document_number).\"\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendances",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendances"
                      ]
                    },
                    "description": "Registra hasta 500 marcaciones. Idempotente: un registro existente del empleado en esa fecha se actualiza. Acepta check_in/check_out (HH:MM), check_in_at/check_out_at (YYYY-MM-DD HH:MM, admiten salida al día siguiente) o punches. Cada registro se procesa por separado; si todos fallan la respuesta es 422.\n\nPermiso requerido: `hr.attendances`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `records` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendances` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"records\": [\n    {\n      \"document_number\": \"01234567-8\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:02\",\n      \"check_out\": \"17:05\"\n    },\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"07:55\",\n      \"check_out\": \"18:30\",\n      \"notes\": \"Cierre de mes\"\n    },\n    {\n      \"document_number\": \"98765432-1\",\n      \"date\": \"2026-10-01\",\n      \"check_in\": \"08:10\"\n    },\n    {\n      \"document_number\": \"45678912-3\",\n      \"date\": \"2026-10-01\",\n      \"check_in_at\": \"2026-10-01 22:00\",\n      \"check_out_at\": \"2026-10-02 06:05\"\n    },\n    {\n      \"document_number\": \"11223344-5\",\n      \"date\": \"2026-10-01\",\n      \"punches\": [\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 08:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 12:00\"\n        },\n        {\n          \"type\": \"in\",\n          \"at\": \"2026-10-01 13:00\"\n        },\n        {\n          \"type\": \"out\",\n          \"at\": \"2026-10-01 17:02\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"records\": [\n      \"The records field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar aprobaciones de horas extra",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/overtime-approvals?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "overtime-approvals"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "employee_id",
                      "value": "{{employee_id}}",
                      "description": "(Opcional) Filtra por empleado.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "pending",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Aprobaciones de horas extra del rango (máximo 370 días), ordenadas por `work_date`. Solo existen si las reglas laborales tienen `overtime.requires_approval` y el día tiene extra.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `partially_approved`, `rejected` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "pending",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Aprobaciones de horas extra del rango (máximo 370 días), ordenadas por `work_date`. Solo existen si las reglas laborales tienen `overtime.requires_approval` y el día tiene extra.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `partially_approved`, `rejected` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"employee_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"employee_name\": \"Ana López\",\n      \"work_date\": \"2026-10-06\",\n      \"attendance_day_result_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"requested_minutes\": 120,\n      \"approved_minutes\": 60,\n      \"rejected_minutes\": 60,\n      \"status\": \"partially_approved\",\n      \"changed_after_decision\": false,\n      \"decided_by\": null,\n      \"decided_by_name\": null,\n      \"decided_at\": \"2026-10-08 10:00:00\",\n      \"comment\": \"Solo se autorizó una hora\",\n      \"is_locked\": false,\n      \"can_decide\": true\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "pending",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Aprobaciones de horas extra del rango (máximo 370 días), ordenadas por `work_date`. Solo existen si las reglas laborales tienen `overtime.requires_approval` y el día tiene extra.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `partially_approved`, `rejected` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Obtener resumen de asistencia por empleado",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/attendance-results/summary?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "attendance-results",
                    "summary"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    }
                  ]
                },
                "description": "Totales por empleado del rango (máximo 370 días): días, tardanzas, ausencias, minutos por categoría y monto sugerido.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendance-results/summary?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendance-results",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        }
                      ]
                    },
                    "description": "Totales por empleado del rango (máximo 370 días): días, tardanzas, ausencias, minutos por categoría y monto sugerido.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_name\": \"María López\",\n      \"pay_type\": \"salaried\",\n      \"days_worked\": 21,\n      \"late_days\": 3,\n      \"late_minutes\": 42,\n      \"early_leave_minutes\": 15,\n      \"absent_days\": 1,\n      \"minutes\": {\n        \"ordinary_day\": 9600,\n        \"ordinary_night\": 0,\n        \"overtime_day\": 330,\n        \"overtime_night\": 60,\n        \"rest_day\": 0,\n        \"holiday\": 0\n      },\n      \"suggested_amount\": 62.4,\n      \"overtime_pending_minutes\": 0,\n      \"overtime_rejected_minutes\": 0\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/attendance-results/summary?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "attendance-results",
                        "summary"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        }
                      ]
                    },
                    "description": "Totales por empleado del rango (máximo 370 días): días, tardanzas, ausencias, minutos por categoría y monto sugerido.\n\nPermiso requerido: `hr.attendance_results`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.attendance_results` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Decidir horas extra en lote",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/overtime-approvals/bulk",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "overtime-approvals",
                    "bulk"
                  ]
                },
                "description": "Aprueba (el total de cada día) o rechaza hasta 500 aprobaciones. Cada ID se procesa por separado; los errores se informan en `errors`.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `ids` | array de string | Sí |  |\n| `status` | string: `approved`, `rejected` | Sí | Decisión (approved aprueba el total de cada día). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ],\n  \"status\": \"approved\",\n  \"comment\": \"Cierre de quincena\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals/bulk",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals",
                        "bulk"
                      ]
                    },
                    "description": "Aprueba (el total de cada día) o rechaza hasta 500 aprobaciones. Cada ID se procesa por separado; los errores se informan en `errors`.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `ids` | array de string | Sí |  |\n| `status` | string: `approved`, `rejected` | Sí | Decisión (approved aprueba el total de cada día). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ],\n  \"status\": \"approved\",\n  \"comment\": \"Cierre de quincena\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"updated\": 1,\n    \"errors\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"message\": \"El día pertenece a una planilla procesada.\"\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals/bulk",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals",
                        "bulk"
                      ]
                    },
                    "description": "Aprueba (el total de cada día) o rechaza hasta 500 aprobaciones. Cada ID se procesa por separado; los errores se informan en `errors`.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `ids` | array de string | Sí |  |\n| `status` | string: `approved`, `rejected` | Sí | Decisión (approved aprueba el total de cada día). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"ids\": [\n    \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\"\n  ],\n  \"status\": \"approved\",\n  \"comment\": \"Cierre de quincena\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"ids\": [\n      \"The ids field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Decidir horas extra de un día",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/overtime-approvals/:id/decide",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "overtime-approvals",
                    ":id",
                    "decide"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{overtime_approval_id}}",
                      "description": "ID de la aprobación"
                    }
                  ]
                },
                "description": "`approved` sin `approved_minutes` aprueba todo; menos minutos que los solicitados = `partially_approved`; `0` = `rejected`. Recalcula el día y devuelve la aprobación y el resultado. Días con planilla procesada o pagada: 422.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `approved`, `rejected` | Sí | Decisión. |\n| `approved_minutes` | integer | No | Minutos aprobados (sin él, todos). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, día bloqueado o minutos mayores a los solicitados.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"status\": \"approved\",\n  \"approved_minutes\": 60,\n  \"comment\": \"Solo se autorizó una hora\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals/:id/decide",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals",
                        ":id",
                        "decide"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{overtime_approval_id}}",
                          "description": "ID de la aprobación"
                        }
                      ]
                    },
                    "description": "`approved` sin `approved_minutes` aprueba todo; menos minutos que los solicitados = `partially_approved`; `0` = `rejected`. Recalcula el día y devuelve la aprobación y el resultado. Días con planilla procesada o pagada: 422.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `approved`, `rejected` | Sí | Decisión. |\n| `approved_minutes` | integer | No | Minutos aprobados (sin él, todos). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, día bloqueado o minutos mayores a los solicitados.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"status\": \"approved\",\n  \"approved_minutes\": 60,\n  \"comment\": \"Solo se autorizó una hora\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"approval\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"employee_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"employee_name\": \"Ana López\",\n      \"work_date\": \"2026-10-06\",\n      \"attendance_day_result_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"requested_minutes\": 120,\n      \"approved_minutes\": 60,\n      \"rejected_minutes\": 60,\n      \"status\": \"partially_approved\",\n      \"changed_after_decision\": false,\n      \"decided_by\": null,\n      \"decided_by_name\": null,\n      \"decided_at\": \"2026-10-08 10:00:00\",\n      \"comment\": \"Solo se autorizó una hora\",\n      \"is_locked\": false,\n      \"can_decide\": true\n    },\n    \"result\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"work_date\": \"2026-10-06\",\n      \"overtime_pending_minutes\": 0,\n      \"overtime_rejected_minutes\": 60\n    }\n  }\n}"
                },
                {
                  "name": "422 Validación, día bloqueado o minutos mayores a los solicitados",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/overtime-approvals/:id/decide",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "overtime-approvals",
                        ":id",
                        "decide"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{overtime_approval_id}}",
                          "description": "ID de la aprobación"
                        }
                      ]
                    },
                    "description": "`approved` sin `approved_minutes` aprueba todo; menos minutos que los solicitados = `partially_approved`; `0` = `rejected`. Recalcula el día y devuelve la aprobación y el resultado. Días con planilla procesada o pagada: 422.\n\nPermiso requerido: `hr.overtime.approve`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `status` | string: `approved`, `rejected` | Sí | Decisión. |\n| `approved_minutes` | integer | No | Minutos aprobados (sin él, todos). |\n| `comment` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.overtime.approve` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, día bloqueado o minutos mayores a los solicitados.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"status\": \"approved\",\n  \"approved_minutes\": 60,\n  \"comment\": \"Solo se autorizó una hora\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"El día pertenece a una planilla procesada.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Horarios y reglas laborales",
          "item": [
            {
              "name": "Listar reglas laborales",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules"
                  ]
                },
                "description": "Vigencias de la empresa, la que rige hoy (`current_id`) y las reglas efectivas (`effective`: propias o plantilla del país).\n\nPermiso requerido: `hr.labor_rules`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules"
                      ]
                    },
                    "description": "Vigencias de la empresa, la que rige hoy (`current_id`) y las reglas efectivas (`effective`: propias o plantilla del país).\n\nPermiso requerido: `hr.labor_rules`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"rule_sets\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"country_code\": \"SV\",\n        \"name\": \"El Salvador - Código de Trabajo\",\n        \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"effective_from\": \"2026-01-01\",\n        \"effective_to\": null,\n        \"schema_version\": 1,\n        \"params\": {\n          \"timezone\": \"America/El_Salvador\",\n          \"day_band\": {\n            \"start\": \"06:00\",\n            \"end\": \"19:00\"\n          },\n          \"mixed_rule\": {\n            \"type\": \"night_if_night_minutes_gt\",\n            \"threshold_minutes\": 240\n          },\n          \"max_ordinary\": {\n            \"daily\": {\n              \"day\": 480,\n              \"night\": 420,\n              \"mixed\": 480\n            },\n            \"weekly\": {\n              \"day\": 2640,\n              \"night\": 2340,\n              \"mixed\": 2640\n            }\n          },\n          \"week_starts_on\": 1,\n          \"default_rest_days\": [\n            7\n          ],\n          \"default_daily_minutes\": {\n            \"1\": 480,\n            \"2\": 480,\n            \"3\": 480,\n            \"4\": 480,\n            \"5\": 480,\n            \"6\": 240,\n            \"7\": 0\n          },\n          \"overtime\": {\n            \"basis\": [\n              \"daily\",\n              \"weekly\"\n            ],\n            \"daily_cap_minutes\": null,\n            \"weekly_cap_minutes\": null,\n            \"total_daily_cap_minutes\": null,\n            \"requires_approval\": false\n          },\n          \"surcharges\": {\n            \"ordinary_day\": 0,\n            \"ordinary_night\": 0.25,\n            \"overtime_day\": 1.0,\n            \"overtime_night\": 1.5,\n            \"rest_day\": 0.5,\n            \"holiday\": 1.0,\n            \"combination\": \"multiplicative\"\n          },\n          \"rest_day_compensatory\": true,\n          \"breaks\": {\n            \"paid\": false,\n            \"min_minutes\": 30,\n            \"auto_deduct_minutes\": 0\n          },\n          \"tolerances\": {\n            \"late_grace_minutes\": 5,\n            \"early_leave_grace_minutes\": 0,\n            \"absence_after_minutes\": null\n          },\n          \"rounding\": {\n            \"unit_minutes\": 1,\n            \"mode\": \"none\"\n          },\n          \"min_hourly_wage\": 1.7,\n          \"currency\": \"USD\"\n        },\n        \"is_active\": true,\n        \"is_template\": false\n      }\n    ],\n    \"current_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"effective\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"country_code\": \"SV\",\n      \"name\": \"El Salvador - Código de Trabajo\",\n      \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"effective_from\": \"2026-01-01\",\n      \"effective_to\": null,\n      \"schema_version\": 1,\n      \"params\": {\n        \"timezone\": \"America/El_Salvador\",\n        \"day_band\": {\n          \"start\": \"06:00\",\n          \"end\": \"19:00\"\n        },\n        \"mixed_rule\": {\n          \"type\": \"night_if_night_minutes_gt\",\n          \"threshold_minutes\": 240\n        },\n        \"max_ordinary\": {\n          \"daily\": {\n            \"day\": 480,\n            \"night\": 420,\n            \"mixed\": 480\n          },\n          \"weekly\": {\n            \"day\": 2640,\n            \"night\": 2340,\n            \"mixed\": 2640\n          }\n        },\n        \"week_starts_on\": 1,\n        \"default_rest_days\": [\n          7\n        ],\n        \"default_daily_minutes\": {\n          \"1\": 480,\n          \"2\": 480,\n          \"3\": 480,\n          \"4\": 480,\n          \"5\": 480,\n          \"6\": 240,\n          \"7\": 0\n        },\n        \"overtime\": {\n          \"basis\": [\n            \"daily\",\n            \"weekly\"\n          ],\n          \"daily_cap_minutes\": null,\n          \"weekly_cap_minutes\": null,\n          \"total_daily_cap_minutes\": null,\n          \"requires_approval\": false\n        },\n        \"surcharges\": {\n          \"ordinary_day\": 0,\n          \"ordinary_night\": 0.25,\n          \"overtime_day\": 1.0,\n          \"overtime_night\": 1.5,\n          \"rest_day\": 0.5,\n          \"holiday\": 1.0,\n          \"combination\": \"multiplicative\"\n        },\n        \"rest_day_compensatory\": true,\n        \"breaks\": {\n          \"paid\": false,\n          \"min_minutes\": 30,\n          \"auto_deduct_minutes\": 0\n        },\n        \"tolerances\": {\n          \"late_grace_minutes\": 5,\n          \"early_leave_grace_minutes\": 0,\n          \"absence_after_minutes\": null\n        },\n        \"rounding\": {\n          \"unit_minutes\": 1,\n          \"mode\": \"none\"\n        },\n        \"min_hourly_wage\": 1.7,\n        \"currency\": \"USD\"\n      },\n      \"is_active\": true,\n      \"is_template\": false\n    }\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear reglas laborales",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules"
                  ]
                },
                "description": "Crea una vigencia de reglas de la empresa con `params` completos. No puede solaparse con otra activa. Encola el recálculo de la asistencia afectada.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | Sí | País (2 letras). |\n| `name` | string | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | Sí |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"country_code\": \"SV\",\n  \"name\": \"Reglas 2027\",\n  \"effective_from\": \"2027-01-01\",\n  \"effective_to\": null,\n  \"is_active\": true,\n  \"params\": {\n    \"timezone\": \"America/El_Salvador\",\n    \"day_band\": {\n      \"start\": \"06:00\",\n      \"end\": \"19:00\"\n    },\n    \"mixed_rule\": {\n      \"type\": \"night_if_night_minutes_gt\",\n      \"threshold_minutes\": 240\n    },\n    \"max_ordinary\": {\n      \"daily\": {\n        \"day\": 480,\n        \"night\": 420,\n        \"mixed\": 480\n      },\n      \"weekly\": {\n        \"day\": 2640,\n        \"night\": 2340,\n        \"mixed\": 2640\n      }\n    },\n    \"week_starts_on\": 1,\n    \"default_rest_days\": [\n      7\n    ],\n    \"default_daily_minutes\": {\n      \"1\": 480,\n      \"2\": 480,\n      \"3\": 480,\n      \"4\": 480,\n      \"5\": 480,\n      \"6\": 240,\n      \"7\": 0\n    },\n    \"overtime\": {\n      \"basis\": [\n        \"daily\",\n        \"weekly\"\n      ],\n      \"daily_cap_minutes\": null,\n      \"weekly_cap_minutes\": null,\n      \"total_daily_cap_minutes\": null,\n      \"requires_approval\": false\n    },\n    \"surcharges\": {\n      \"ordinary_day\": 0,\n      \"ordinary_night\": 0.25,\n      \"overtime_day\": 1.0,\n      \"overtime_night\": 1.5,\n      \"rest_day\": 0.5,\n      \"holiday\": 1.0,\n      \"combination\": \"multiplicative\"\n    },\n    \"rest_day_compensatory\": true,\n    \"breaks\": {\n      \"paid\": false,\n      \"min_minutes\": 30,\n      \"auto_deduct_minutes\": 0\n    },\n    \"tolerances\": {\n      \"late_grace_minutes\": 5,\n      \"early_leave_grace_minutes\": 0,\n      \"absence_after_minutes\": null\n    },\n    \"rounding\": {\n      \"unit_minutes\": 1,\n      \"mode\": \"none\"\n    },\n    \"min_hourly_wage\": 1.7,\n    \"currency\": \"USD\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Reglas creadas",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules"
                      ]
                    },
                    "description": "Crea una vigencia de reglas de la empresa con `params` completos. No puede solaparse con otra activa. Encola el recálculo de la asistencia afectada.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | Sí | País (2 letras). |\n| `name` | string | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | Sí |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"country_code\": \"SV\",\n  \"name\": \"Reglas 2027\",\n  \"effective_from\": \"2027-01-01\",\n  \"effective_to\": null,\n  \"is_active\": true,\n  \"params\": {\n    \"timezone\": \"America/El_Salvador\",\n    \"day_band\": {\n      \"start\": \"06:00\",\n      \"end\": \"19:00\"\n    },\n    \"mixed_rule\": {\n      \"type\": \"night_if_night_minutes_gt\",\n      \"threshold_minutes\": 240\n    },\n    \"max_ordinary\": {\n      \"daily\": {\n        \"day\": 480,\n        \"night\": 420,\n        \"mixed\": 480\n      },\n      \"weekly\": {\n        \"day\": 2640,\n        \"night\": 2340,\n        \"mixed\": 2640\n      }\n    },\n    \"week_starts_on\": 1,\n    \"default_rest_days\": [\n      7\n    ],\n    \"default_daily_minutes\": {\n      \"1\": 480,\n      \"2\": 480,\n      \"3\": 480,\n      \"4\": 480,\n      \"5\": 480,\n      \"6\": 240,\n      \"7\": 0\n    },\n    \"overtime\": {\n      \"basis\": [\n        \"daily\",\n        \"weekly\"\n      ],\n      \"daily_cap_minutes\": null,\n      \"weekly_cap_minutes\": null,\n      \"total_daily_cap_minutes\": null,\n      \"requires_approval\": false\n    },\n    \"surcharges\": {\n      \"ordinary_day\": 0,\n      \"ordinary_night\": 0.25,\n      \"overtime_day\": 1.0,\n      \"overtime_night\": 1.5,\n      \"rest_day\": 0.5,\n      \"holiday\": 1.0,\n      \"combination\": \"multiplicative\"\n    },\n    \"rest_day_compensatory\": true,\n    \"breaks\": {\n      \"paid\": false,\n      \"min_minutes\": 30,\n      \"auto_deduct_minutes\": 0\n    },\n    \"tolerances\": {\n      \"late_grace_minutes\": 5,\n      \"early_leave_grace_minutes\": 0,\n      \"absence_after_minutes\": null\n    },\n    \"rounding\": {\n      \"unit_minutes\": 1,\n      \"mode\": \"none\"\n    },\n    \"min_hourly_wage\": 1.7,\n    \"currency\": \"USD\"\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"country_code\": \"SV\",\n    \"name\": \"El Salvador - Código de Trabajo\",\n    \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"effective_from\": \"2026-01-01\",\n    \"effective_to\": null,\n    \"schema_version\": 1,\n    \"params\": {\n      \"timezone\": \"America/El_Salvador\",\n      \"day_band\": {\n        \"start\": \"06:00\",\n        \"end\": \"19:00\"\n      },\n      \"mixed_rule\": {\n        \"type\": \"night_if_night_minutes_gt\",\n        \"threshold_minutes\": 240\n      },\n      \"max_ordinary\": {\n        \"daily\": {\n          \"day\": 480,\n          \"night\": 420,\n          \"mixed\": 480\n        },\n        \"weekly\": {\n          \"day\": 2640,\n          \"night\": 2340,\n          \"mixed\": 2640\n        }\n      },\n      \"week_starts_on\": 1,\n      \"default_rest_days\": [\n        7\n      ],\n      \"default_daily_minutes\": {\n        \"1\": 480,\n        \"2\": 480,\n        \"3\": 480,\n        \"4\": 480,\n        \"5\": 480,\n        \"6\": 240,\n        \"7\": 0\n      },\n      \"overtime\": {\n        \"basis\": [\n          \"daily\",\n          \"weekly\"\n        ],\n        \"daily_cap_minutes\": null,\n        \"weekly_cap_minutes\": null,\n        \"total_daily_cap_minutes\": null,\n        \"requires_approval\": false\n      },\n      \"surcharges\": {\n        \"ordinary_day\": 0,\n        \"ordinary_night\": 0.25,\n        \"overtime_day\": 1.0,\n        \"overtime_night\": 1.5,\n        \"rest_day\": 0.5,\n        \"holiday\": 1.0,\n        \"combination\": \"multiplicative\"\n      },\n      \"rest_day_compensatory\": true,\n      \"breaks\": {\n        \"paid\": false,\n        \"min_minutes\": 30,\n        \"auto_deduct_minutes\": 0\n      },\n      \"tolerances\": {\n        \"late_grace_minutes\": 5,\n        \"early_leave_grace_minutes\": 0,\n        \"absence_after_minutes\": null\n      },\n      \"rounding\": {\n        \"unit_minutes\": 1,\n        \"mode\": \"none\"\n      },\n      \"min_hourly_wage\": 1.7,\n      \"currency\": \"USD\"\n    },\n    \"is_active\": true,\n    \"is_template\": false,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules"
                      ]
                    },
                    "description": "Crea una vigencia de reglas de la empresa con `params` completos. No puede solaparse con otra activa. Encola el recálculo de la asistencia afectada.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | Sí | País (2 letras). |\n| `name` | string | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | Sí |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"country_code\": \"SV\",\n  \"name\": \"Reglas 2027\",\n  \"effective_from\": \"2027-01-01\",\n  \"effective_to\": null,\n  \"is_active\": true,\n  \"params\": {\n    \"timezone\": \"America/El_Salvador\",\n    \"day_band\": {\n      \"start\": \"06:00\",\n      \"end\": \"19:00\"\n    },\n    \"mixed_rule\": {\n      \"type\": \"night_if_night_minutes_gt\",\n      \"threshold_minutes\": 240\n    },\n    \"max_ordinary\": {\n      \"daily\": {\n        \"day\": 480,\n        \"night\": 420,\n        \"mixed\": 480\n      },\n      \"weekly\": {\n        \"day\": 2640,\n        \"night\": 2340,\n        \"mixed\": 2640\n      }\n    },\n    \"week_starts_on\": 1,\n    \"default_rest_days\": [\n      7\n    ],\n    \"default_daily_minutes\": {\n      \"1\": 480,\n      \"2\": 480,\n      \"3\": 480,\n      \"4\": 480,\n      \"5\": 480,\n      \"6\": 240,\n      \"7\": 0\n    },\n    \"overtime\": {\n      \"basis\": [\n        \"daily\",\n        \"weekly\"\n      ],\n      \"daily_cap_minutes\": null,\n      \"weekly_cap_minutes\": null,\n      \"total_daily_cap_minutes\": null,\n      \"requires_approval\": false\n    },\n    \"surcharges\": {\n      \"ordinary_day\": 0,\n      \"ordinary_night\": 0.25,\n      \"overtime_day\": 1.0,\n      \"overtime_night\": 1.5,\n      \"rest_day\": 0.5,\n      \"holiday\": 1.0,\n      \"combination\": \"multiplicative\"\n    },\n    \"rest_day_compensatory\": true,\n    \"breaks\": {\n      \"paid\": false,\n      \"min_minutes\": 30,\n      \"auto_deduct_minutes\": 0\n    },\n    \"tolerances\": {\n      \"late_grace_minutes\": 5,\n      \"early_leave_grace_minutes\": 0,\n      \"absence_after_minutes\": null\n    },\n    \"rounding\": {\n      \"unit_minutes\": 1,\n      \"mode\": \"none\"\n    },\n    \"min_hourly_wage\": 1.7,\n    \"currency\": \"USD\"\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"country_code\": [\n      \"The country code field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar asignaciones de horario",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/schedule-assignments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "schedule-assignments"
                  ],
                  "query": [
                    {
                      "key": "employee_id",
                      "value": "{{employee_id}}",
                      "description": "(Opcional) Filtra por empleado.",
                      "disabled": true
                    },
                    {
                      "key": "date",
                      "value": "2026-10-08",
                      "description": "(Opcional) Vigentes en la fecha.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Asignaciones de horario. Con `date`, solo las vigentes en esa fecha.\n\nPermiso requerido: `hr.schedules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string | No | Filtra por empleado. |\n| `date` | string (date) | No | Vigentes en la fecha. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments"
                      ],
                      "query": [
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Vigentes en la fecha.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Asignaciones de horario. Con `date`, solo las vigentes en esa fecha.\n\nPermiso requerido: `hr.schedules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string | No | Filtra por empleado. |\n| `date` | string (date) | No | Vigentes en la fecha. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_name\": \"María López\",\n      \"work_schedule_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"work_schedule_name\": \"Administrativo\",\n      \"work_schedule_code\": \"ADM\",\n      \"start_date\": \"2026-10-01\",\n      \"end_date\": null,\n      \"notes\": null\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments"
                      ],
                      "query": [
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Vigentes en la fecha.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Asignaciones de horario. Con `date`, solo las vigentes en esa fecha.\n\nPermiso requerido: `hr.schedules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string | No | Filtra por empleado. |\n| `date` | string (date) | No | Vigentes en la fecha. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Asignar horario en lote",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/schedule-assignments",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "schedule-assignments"
                  ]
                },
                "description": "Asigna un horario a hasta 500 empleados (por `employee_ids` o `document_numbers`) con la misma vigencia. Idempotente por empleado y `start_date`. Si ninguno se asigna, responde 422.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `work_schedule_id` | string (uuid) | Sí |  |\n| `employee_ids` | array de string | No |  |\n| `document_numbers` | array de string | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `close_previous` | boolean | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"work_schedule_id\": \"{{work_schedule_id}}\",\n  \"document_numbers\": [\n    \"01234567-8\",\n    \"98765432-1\"\n  ],\n  \"start_date\": \"2026-11-01\",\n  \"end_date\": null,\n  \"close_previous\": true,\n  \"notes\": \"Cambio de turno\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments"
                      ]
                    },
                    "description": "Asigna un horario a hasta 500 empleados (por `employee_ids` o `document_numbers`) con la misma vigencia. Idempotente por empleado y `start_date`. Si ninguno se asigna, responde 422.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `work_schedule_id` | string (uuid) | Sí |  |\n| `employee_ids` | array de string | No |  |\n| `document_numbers` | array de string | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `close_previous` | boolean | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"work_schedule_id\": \"{{work_schedule_id}}\",\n  \"document_numbers\": [\n    \"01234567-8\",\n    \"98765432-1\"\n  ],\n  \"start_date\": \"2026-11-01\",\n  \"end_date\": null,\n  \"close_previous\": true,\n  \"notes\": \"Cambio de turno\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"created\": 1,\n    \"updated\": 0,\n    \"errors\": [\n      {\n        \"employee_id\": null,\n        \"document_number\": \"98765432-1\",\n        \"message\": \"Employee not found.\"\n      }\n    ],\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments"
                      ]
                    },
                    "description": "Asigna un horario a hasta 500 empleados (por `employee_ids` o `document_numbers`) con la misma vigencia. Idempotente por empleado y `start_date`. Si ninguno se asigna, responde 422.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `work_schedule_id` | string (uuid) | Sí |  |\n| `employee_ids` | array de string | No |  |\n| `document_numbers` | array de string | No |  |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | No |  |\n| `close_previous` | boolean | No |  |\n| `notes` | string | No |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"work_schedule_id\": \"{{work_schedule_id}}\",\n  \"document_numbers\": [\n    \"01234567-8\",\n    \"98765432-1\"\n  ],\n  \"start_date\": \"2026-11-01\",\n  \"end_date\": null,\n  \"close_previous\": true,\n  \"notes\": \"Cambio de turno\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"work_schedule_id\": [\n      \"The work schedule id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar horarios",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/work-schedules",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "work-schedules"
                  ]
                },
                "description": "Horarios de la empresa con turnos, minutos semanales, resumen por día y avisos legales.\n\nPermiso requerido: `hr.schedules`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules"
                      ]
                    },
                    "description": "Horarios de la empresa con turnos, minutos semanales, resumen por día y avisos legales.\n\nPermiso requerido: `hr.schedules`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Administrativo\",\n      \"code\": \"ADM\",\n      \"description\": \"Lunes a viernes\",\n      \"color\": \"#1890ff\",\n      \"is_active\": true,\n      \"shifts\": [\n        {\n          \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n          \"weekday\": 1,\n          \"start_time\": \"08:00\",\n          \"end_time\": \"17:00\",\n          \"break_minutes\": 60,\n          \"break_paid\": null\n        }\n      ],\n      \"weekly_minutes\": 2400,\n      \"days\": [\n        {\n          \"weekday\": 1,\n          \"minutes\": 480,\n          \"shift_kind\": \"day\",\n          \"warnings\": []\n        },\n        {\n          \"weekday\": 7,\n          \"minutes\": 0,\n          \"shift_kind\": null,\n          \"warnings\": []\n        }\n      ],\n      \"warnings\": []\n    }\n  ]\n}"
                }
              ]
            },
            {
              "name": "Crear horario",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/work-schedules",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "work-schedules"
                  ]
                },
                "description": "Crea un horario. Un turno con salida menor o igual que la entrada termina al día siguiente. Los turnos de un día no pueden solaparse.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `code` | string | Sí | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Nocturno\",\n  \"code\": \"NOCHE\",\n  \"description\": \"Vigilancia\",\n  \"color\": \"#2f54eb\",\n  \"shifts\": [\n    {\n      \"weekday\": 1,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 2,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 3,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Horario creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules"
                      ]
                    },
                    "description": "Crea un horario. Un turno con salida menor o igual que la entrada termina al día siguiente. Los turnos de un día no pueden solaparse.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `code` | string | Sí | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Nocturno\",\n  \"code\": \"NOCHE\",\n  \"description\": \"Vigilancia\",\n  \"color\": \"#2f54eb\",\n  \"shifts\": [\n    {\n      \"weekday\": 1,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 2,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 3,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Administrativo\",\n    \"code\": \"ADM\",\n    \"description\": \"Lunes a viernes\",\n    \"color\": \"#1890ff\",\n    \"is_active\": true,\n    \"shifts\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"weekday\": 1,\n        \"start_time\": \"08:00\",\n        \"end_time\": \"17:00\",\n        \"break_minutes\": 60,\n        \"break_paid\": null\n      }\n    ],\n    \"weekly_minutes\": 2400,\n    \"days\": [\n      {\n        \"weekday\": 1,\n        \"minutes\": 480,\n        \"shift_kind\": \"day\",\n        \"warnings\": []\n      },\n      {\n        \"weekday\": 7,\n        \"minutes\": 0,\n        \"shift_kind\": null,\n        \"warnings\": []\n      }\n    ],\n    \"warnings\": []\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules"
                      ]
                    },
                    "description": "Crea un horario. Un turno con salida menor o igual que la entrada termina al día siguiente. Los turnos de un día no pueden solaparse.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | Sí |  |\n| `code` | string | Sí | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Nocturno\",\n  \"code\": \"NOCHE\",\n  \"description\": \"Vigilancia\",\n  \"color\": \"#2f54eb\",\n  \"shifts\": [\n    {\n      \"weekday\": 1,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 2,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    },\n    {\n      \"weekday\": 3,\n      \"start_time\": \"22:00\",\n      \"end_time\": \"05:00\",\n      \"break_minutes\": 0\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"name\": [\n      \"The name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Editar reglas laborales",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{labor_rule_id}}",
                      "description": "ID del conjunto de reglas"
                    }
                  ]
                },
                "description": "Actualiza los campos enviados (`params` se reemplaza completo). Recalcula la asistencia de la vigencia.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | No | País (2 letras). |\n| `name` | string | No |  |\n| `effective_from` | string (date) | No |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | No |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"effective_to\": \"2026-12-31\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{labor_rule_id}}",
                          "description": "ID del conjunto de reglas"
                        }
                      ]
                    },
                    "description": "Actualiza los campos enviados (`params` se reemplaza completo). Recalcula la asistencia de la vigencia.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | No | País (2 letras). |\n| `name` | string | No |  |\n| `effective_from` | string (date) | No |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | No |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"effective_to\": \"2026-12-31\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"country_code\": \"SV\",\n    \"name\": \"El Salvador - Código de Trabajo\",\n    \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"effective_from\": \"2026-01-01\",\n    \"effective_to\": \"2026-12-31\",\n    \"schema_version\": 1,\n    \"params\": {\n      \"timezone\": \"America/El_Salvador\",\n      \"day_band\": {\n        \"start\": \"06:00\",\n        \"end\": \"19:00\"\n      },\n      \"mixed_rule\": {\n        \"type\": \"night_if_night_minutes_gt\",\n        \"threshold_minutes\": 240\n      },\n      \"max_ordinary\": {\n        \"daily\": {\n          \"day\": 480,\n          \"night\": 420,\n          \"mixed\": 480\n        },\n        \"weekly\": {\n          \"day\": 2640,\n          \"night\": 2340,\n          \"mixed\": 2640\n        }\n      },\n      \"week_starts_on\": 1,\n      \"default_rest_days\": [\n        7\n      ],\n      \"default_daily_minutes\": {\n        \"1\": 480,\n        \"2\": 480,\n        \"3\": 480,\n        \"4\": 480,\n        \"5\": 480,\n        \"6\": 240,\n        \"7\": 0\n      },\n      \"overtime\": {\n        \"basis\": [\n          \"daily\",\n          \"weekly\"\n        ],\n        \"daily_cap_minutes\": null,\n        \"weekly_cap_minutes\": null,\n        \"total_daily_cap_minutes\": null,\n        \"requires_approval\": false\n      },\n      \"surcharges\": {\n        \"ordinary_day\": 0,\n        \"ordinary_night\": 0.25,\n        \"overtime_day\": 1.0,\n        \"overtime_night\": 1.5,\n        \"rest_day\": 0.5,\n        \"holiday\": 1.0,\n        \"combination\": \"multiplicative\"\n      },\n      \"rest_day_compensatory\": true,\n      \"breaks\": {\n        \"paid\": false,\n        \"min_minutes\": 30,\n        \"auto_deduct_minutes\": 0\n      },\n      \"tolerances\": {\n        \"late_grace_minutes\": 5,\n        \"early_leave_grace_minutes\": 0,\n        \"absence_after_minutes\": null\n      },\n      \"rounding\": {\n        \"unit_minutes\": 1,\n        \"mode\": \"none\"\n      },\n      \"min_hourly_wage\": 1.7,\n      \"currency\": \"USD\"\n    },\n    \"is_active\": true,\n    \"is_template\": false,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{labor_rule_id}}",
                          "description": "ID del conjunto de reglas"
                        }
                      ]
                    },
                    "description": "Actualiza los campos enviados (`params` se reemplaza completo). Recalcula la asistencia de la vigencia.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | No | País (2 letras). |\n| `name` | string | No |  |\n| `effective_from` | string (date) | No |  |\n| `effective_to` | string (date) | No |  |\n| `params` | object | No |  |\n| `is_active` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"effective_to\": \"2026-12-31\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"country_code\": [\n      \"The country code field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar reglas vigentes en una fecha",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules/effective",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules",
                    "effective"
                  ],
                  "query": [
                    {
                      "key": "date",
                      "value": "2026-10-08",
                      "description": "(Opcional) Fecha (YYYY-MM-DD). Por defecto, hoy.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Parámetros que rigen en la fecha. `source`: `business`, `template` o `default`.\n\nPermiso requerido: `hr.labor_rules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No | Fecha (YYYY-MM-DD). Por defecto, hoy. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/effective",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        "effective"
                      ],
                      "query": [
                        {
                          "key": "date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Fecha (YYYY-MM-DD). Por defecto, hoy.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Parámetros que rigen en la fecha. `source`: `business`, `template` o `default`.\n\nPermiso requerido: `hr.labor_rules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No | Fecha (YYYY-MM-DD). Por defecto, hoy. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"date\": \"2026-10-01\",\n    \"rule_set\": {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"country_code\": \"SV\",\n      \"name\": \"El Salvador - Código de Trabajo\",\n      \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"effective_from\": \"2026-01-01\",\n      \"effective_to\": null,\n      \"schema_version\": 1,\n      \"params\": {\n        \"timezone\": \"America/El_Salvador\",\n        \"day_band\": {\n          \"start\": \"06:00\",\n          \"end\": \"19:00\"\n        },\n        \"mixed_rule\": {\n          \"type\": \"night_if_night_minutes_gt\",\n          \"threshold_minutes\": 240\n        },\n        \"max_ordinary\": {\n          \"daily\": {\n            \"day\": 480,\n            \"night\": 420,\n            \"mixed\": 480\n          },\n          \"weekly\": {\n            \"day\": 2640,\n            \"night\": 2340,\n            \"mixed\": 2640\n          }\n        },\n        \"week_starts_on\": 1,\n        \"default_rest_days\": [\n          7\n        ],\n        \"default_daily_minutes\": {\n          \"1\": 480,\n          \"2\": 480,\n          \"3\": 480,\n          \"4\": 480,\n          \"5\": 480,\n          \"6\": 240,\n          \"7\": 0\n        },\n        \"overtime\": {\n          \"basis\": [\n            \"daily\",\n            \"weekly\"\n          ],\n          \"daily_cap_minutes\": null,\n          \"weekly_cap_minutes\": null,\n          \"total_daily_cap_minutes\": null,\n          \"requires_approval\": false\n        },\n        \"surcharges\": {\n          \"ordinary_day\": 0,\n          \"ordinary_night\": 0.25,\n          \"overtime_day\": 1.0,\n          \"overtime_night\": 1.5,\n          \"rest_day\": 0.5,\n          \"holiday\": 1.0,\n          \"combination\": \"multiplicative\"\n        },\n        \"rest_day_compensatory\": true,\n        \"breaks\": {\n          \"paid\": false,\n          \"min_minutes\": 30,\n          \"auto_deduct_minutes\": 0\n        },\n        \"tolerances\": {\n          \"late_grace_minutes\": 5,\n          \"early_leave_grace_minutes\": 0,\n          \"absence_after_minutes\": null\n        },\n        \"rounding\": {\n          \"unit_minutes\": 1,\n          \"mode\": \"none\"\n        },\n        \"min_hourly_wage\": 1.7,\n        \"currency\": \"USD\"\n      },\n      \"is_active\": true,\n      \"is_template\": false\n    },\n    \"source\": \"business\",\n    \"params\": {\n      \"timezone\": \"America/El_Salvador\",\n      \"day_band\": {\n        \"start\": \"06:00\",\n        \"end\": \"19:00\"\n      },\n      \"mixed_rule\": {\n        \"type\": \"night_if_night_minutes_gt\",\n        \"threshold_minutes\": 240\n      },\n      \"max_ordinary\": {\n        \"daily\": {\n          \"day\": 480,\n          \"night\": 420,\n          \"mixed\": 480\n        },\n        \"weekly\": {\n          \"day\": 2640,\n          \"night\": 2340,\n          \"mixed\": 2640\n        }\n      },\n      \"week_starts_on\": 1,\n      \"default_rest_days\": [\n        7\n      ],\n      \"default_daily_minutes\": {\n        \"1\": 480,\n        \"2\": 480,\n        \"3\": 480,\n        \"4\": 480,\n        \"5\": 480,\n        \"6\": 240,\n        \"7\": 0\n      },\n      \"overtime\": {\n        \"basis\": [\n          \"daily\",\n          \"weekly\"\n        ],\n        \"daily_cap_minutes\": null,\n        \"weekly_cap_minutes\": null,\n        \"total_daily_cap_minutes\": null,\n        \"requires_approval\": false\n      },\n      \"surcharges\": {\n        \"ordinary_day\": 0,\n        \"ordinary_night\": 0.25,\n        \"overtime_day\": 1.0,\n        \"overtime_night\": 1.5,\n        \"rest_day\": 0.5,\n        \"holiday\": 1.0,\n        \"combination\": \"multiplicative\"\n      },\n      \"rest_day_compensatory\": true,\n      \"breaks\": {\n        \"paid\": false,\n        \"min_minutes\": 30,\n        \"auto_deduct_minutes\": 0\n      },\n      \"tolerances\": {\n        \"late_grace_minutes\": 5,\n        \"early_leave_grace_minutes\": 0,\n        \"absence_after_minutes\": null\n      },\n      \"rounding\": {\n        \"unit_minutes\": 1,\n        \"mode\": \"none\"\n      },\n      \"min_hourly_wage\": 1.7,\n      \"currency\": \"USD\"\n    }\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/effective",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        "effective"
                      ],
                      "query": [
                        {
                          "key": "date",
                          "value": "2026-10-08",
                          "description": "(Opcional) Fecha (YYYY-MM-DD). Por defecto, hoy.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Parámetros que rigen en la fecha. `source`: `business`, `template` o `default`.\n\nPermiso requerido: `hr.labor_rules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No | Fecha (YYYY-MM-DD). Por defecto, hoy. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Copiar reglas desde plantilla",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules/from-template",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules",
                    "from-template"
                  ]
                },
                "description": "Crea una vigencia de la empresa con los parámetros de la plantilla. Cierra el día previo la vigencia abierta anterior.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `template_id` | string (uuid) | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"effective_from\": \"2026-11-01\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Reglas creadas",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/from-template",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        "from-template"
                      ]
                    },
                    "description": "Crea una vigencia de la empresa con los parámetros de la plantilla. Cierra el día previo la vigencia abierta anterior.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `template_id` | string (uuid) | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"effective_from\": \"2026-11-01\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"country_code\": \"SV\",\n    \"name\": \"El Salvador - Código de Trabajo\",\n    \"source_template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"effective_from\": \"2026-01-01\",\n    \"effective_to\": null,\n    \"schema_version\": 1,\n    \"params\": {\n      \"timezone\": \"America/El_Salvador\",\n      \"day_band\": {\n        \"start\": \"06:00\",\n        \"end\": \"19:00\"\n      },\n      \"mixed_rule\": {\n        \"type\": \"night_if_night_minutes_gt\",\n        \"threshold_minutes\": 240\n      },\n      \"max_ordinary\": {\n        \"daily\": {\n          \"day\": 480,\n          \"night\": 420,\n          \"mixed\": 480\n        },\n        \"weekly\": {\n          \"day\": 2640,\n          \"night\": 2340,\n          \"mixed\": 2640\n        }\n      },\n      \"week_starts_on\": 1,\n      \"default_rest_days\": [\n        7\n      ],\n      \"default_daily_minutes\": {\n        \"1\": 480,\n        \"2\": 480,\n        \"3\": 480,\n        \"4\": 480,\n        \"5\": 480,\n        \"6\": 240,\n        \"7\": 0\n      },\n      \"overtime\": {\n        \"basis\": [\n          \"daily\",\n          \"weekly\"\n        ],\n        \"daily_cap_minutes\": null,\n        \"weekly_cap_minutes\": null,\n        \"total_daily_cap_minutes\": null,\n        \"requires_approval\": false\n      },\n      \"surcharges\": {\n        \"ordinary_day\": 0,\n        \"ordinary_night\": 0.25,\n        \"overtime_day\": 1.0,\n        \"overtime_night\": 1.5,\n        \"rest_day\": 0.5,\n        \"holiday\": 1.0,\n        \"combination\": \"multiplicative\"\n      },\n      \"rest_day_compensatory\": true,\n      \"breaks\": {\n        \"paid\": false,\n        \"min_minutes\": 30,\n        \"auto_deduct_minutes\": 0\n      },\n      \"tolerances\": {\n        \"late_grace_minutes\": 5,\n        \"early_leave_grace_minutes\": 0,\n        \"absence_after_minutes\": null\n      },\n      \"rounding\": {\n        \"unit_minutes\": 1,\n        \"mode\": \"none\"\n      },\n      \"min_hourly_wage\": 1.7,\n      \"currency\": \"USD\"\n    },\n    \"is_active\": true,\n    \"is_template\": false,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/from-template",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        "from-template"
                      ]
                    },
                    "description": "Crea una vigencia de la empresa con los parámetros de la plantilla. Cierra el día previo la vigencia abierta anterior.\n\nPermiso requerido: `hr.labor_rules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `template_id` | string (uuid) | Sí |  |\n| `effective_from` | string (date) | Sí |  |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"template_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n  \"effective_from\": \"2026-11-01\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"template_id\": [\n      \"The template id field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Listar plantillas de reglas por país",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/labor-rules/templates",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "labor-rules",
                    "templates"
                  ],
                  "query": [
                    {
                      "key": "country_code",
                      "value": "SV",
                      "description": "(Opcional) Código ISO de 2 letras.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Plantillas de país (SV, GT, CO). Son un punto de partida: valídalas con tu asesor laboral.\n\nPermiso requerido: `hr.labor_rules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | No | Código ISO de 2 letras. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/labor-rules/templates",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "labor-rules",
                        "templates"
                      ],
                      "query": [
                        {
                          "key": "country_code",
                          "value": "SV",
                          "description": "(Opcional) Código ISO de 2 letras.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Plantillas de país (SV, GT, CO). Son un punto de partida: valídalas con tu asesor laboral.\n\nPermiso requerido: `hr.labor_rules`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `country_code` | string | No | Código ISO de 2 letras. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.labor_rules` o desactivada."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": null,\n      \"country_code\": \"SV\",\n      \"name\": \"El Salvador - Código de Trabajo\",\n      \"source_template_id\": null,\n      \"effective_from\": \"2000-01-01\",\n      \"effective_to\": null,\n      \"schema_version\": 1,\n      \"params\": {\n        \"timezone\": \"America/El_Salvador\",\n        \"day_band\": {\n          \"start\": \"06:00\",\n          \"end\": \"19:00\"\n        },\n        \"mixed_rule\": {\n          \"type\": \"night_if_night_minutes_gt\",\n          \"threshold_minutes\": 240\n        },\n        \"max_ordinary\": {\n          \"daily\": {\n            \"day\": 480,\n            \"night\": 420,\n            \"mixed\": 480\n          },\n          \"weekly\": {\n            \"day\": 2640,\n            \"night\": 2340,\n            \"mixed\": 2640\n          }\n        },\n        \"week_starts_on\": 1,\n        \"default_rest_days\": [\n          7\n        ],\n        \"default_daily_minutes\": {\n          \"1\": 480,\n          \"2\": 480,\n          \"3\": 480,\n          \"4\": 480,\n          \"5\": 480,\n          \"6\": 240,\n          \"7\": 0\n        },\n        \"overtime\": {\n          \"basis\": [\n            \"daily\",\n            \"weekly\"\n          ],\n          \"daily_cap_minutes\": null,\n          \"weekly_cap_minutes\": null,\n          \"total_daily_cap_minutes\": null,\n          \"requires_approval\": false\n        },\n        \"surcharges\": {\n          \"ordinary_day\": 0,\n          \"ordinary_night\": 0.25,\n          \"overtime_day\": 1.0,\n          \"overtime_night\": 1.5,\n          \"rest_day\": 0.5,\n          \"holiday\": 1.0,\n          \"combination\": \"multiplicative\"\n        },\n        \"rest_day_compensatory\": true,\n        \"breaks\": {\n          \"paid\": false,\n          \"min_minutes\": 30,\n          \"auto_deduct_minutes\": 0\n        },\n        \"tolerances\": {\n          \"late_grace_minutes\": 5,\n          \"early_leave_grace_minutes\": 0,\n          \"absence_after_minutes\": null\n        },\n        \"rounding\": {\n          \"unit_minutes\": 1,\n          \"mode\": \"none\"\n        },\n        \"min_hourly_wage\": 1.7,\n        \"currency\": \"USD\"\n      },\n      \"is_active\": true,\n      \"is_template\": true\n    }\n  ]\n}"
                }
              ]
            },
            {
              "name": "Eliminar asignación",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/schedule-assignments/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "schedule-assignments",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{schedule_assignment_id}}",
                      "description": "ID de la asignación"
                    }
                  ]
                },
                "description": "Elimina la asignación y recalcula la asistencia afectada.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{schedule_assignment_id}}",
                          "description": "ID de la asignación"
                        }
                      ]
                    },
                    "description": "Elimina la asignación y recalcula la asistencia afectada.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"deleted\": true,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/schedule-assignments/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "schedule-assignments",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{schedule_assignment_id}}",
                          "description": "ID de la asignación"
                        }
                      ]
                    },
                    "description": "Elimina la asignación y recalcula la asistencia afectada.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Consultar horario",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/work-schedules/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "work-schedules",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{work_schedule_id}}",
                      "description": "ID del horario"
                    }
                  ]
                },
                "description": "Detalle de un horario.\n\nPermiso requerido: `hr.schedules`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Detalle de un horario.\n\nPermiso requerido: `hr.schedules`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Administrativo\",\n    \"code\": \"ADM\",\n    \"description\": \"Lunes a viernes\",\n    \"color\": \"#1890ff\",\n    \"is_active\": true,\n    \"shifts\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"weekday\": 1,\n        \"start_time\": \"08:00\",\n        \"end_time\": \"17:00\",\n        \"break_minutes\": 60,\n        \"break_paid\": null\n      }\n    ],\n    \"weekly_minutes\": 2400,\n    \"days\": [\n      {\n        \"weekday\": 1,\n        \"minutes\": 480,\n        \"shift_kind\": \"day\",\n        \"warnings\": []\n      },\n      {\n        \"weekday\": 7,\n        \"minutes\": 0,\n        \"shift_kind\": null,\n        \"warnings\": []\n      }\n    ],\n    \"warnings\": []\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Detalle de un horario.\n\nPermiso requerido: `hr.schedules`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Editar horario",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/work-schedules/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "work-schedules",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{work_schedule_id}}",
                      "description": "ID del horario"
                    }
                  ]
                },
                "description": "Actualiza los campos enviados; `shifts` reemplaza todos los turnos. Recalcula la asistencia de los empleados asignados.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Administrativo (verano)\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Actualiza los campos enviados; `shifts` reemplaza todos los turnos. Recalcula la asistencia de los empleados asignados.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Administrativo (verano)\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Administrativo\",\n    \"code\": \"ADM\",\n    \"description\": \"Lunes a viernes\",\n    \"color\": \"#1890ff\",\n    \"is_active\": true,\n    \"shifts\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"weekday\": 1,\n        \"start_time\": \"08:00\",\n        \"end_time\": \"17:00\",\n        \"break_minutes\": 60,\n        \"break_paid\": null\n      }\n    ],\n    \"weekly_minutes\": 2400,\n    \"days\": [\n      {\n        \"weekday\": 1,\n        \"minutes\": 480,\n        \"shift_kind\": \"day\",\n        \"warnings\": []\n      },\n      {\n        \"weekday\": 7,\n        \"minutes\": 0,\n        \"shift_kind\": null,\n        \"warnings\": []\n      }\n    ],\n    \"warnings\": [],\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Actualiza los campos enviados; `shifts` reemplaza todos los turnos. Recalcula la asistencia de los empleados asignados.\n\nPermiso requerido: `hr.schedules.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `name` | string | No |  |\n| `code` | string | No | Único en la empresa. |\n| `description` | string | No |  |\n| `color` | string | No |  |\n| `is_active` | boolean | No |  |\n| `shifts` | array de object | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"name\": \"Administrativo (verano)\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"name\": [\n      \"The name field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Eliminar horario",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/work-schedules/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "work-schedules",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{work_schedule_id}}",
                      "description": "ID del horario"
                    }
                  ]
                },
                "description": "Borrado lógico. Responde 409 si tiene asignaciones vigentes.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Tiene asignaciones vigentes."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Borrado lógico. Responde 409 si tiene asignaciones vigentes.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Tiene asignaciones vigentes."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"deleted\": true\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/work-schedules/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "work-schedules",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{work_schedule_id}}",
                          "description": "ID del horario"
                        }
                      ]
                    },
                    "description": "Borrado lógico. Responde 409 si tiene asignaciones vigentes.\n\nPermiso requerido: `hr.schedules.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.schedules.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Tiene asignaciones vigentes."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Feriados",
          "item": [
            {
              "name": "Listar feriados",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/holidays",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "holidays"
                  ],
                  "query": [
                    {
                      "key": "year",
                      "value": "2026",
                      "description": "(Opcional) Año (2000-2100). Por defecto, el actual.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Feriados del país de la empresa y asuetos propios del año, con origen y exclusiones.\n\nPermiso requerido: `hr.holidays`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año (2000-2100). Por defecto, el actual. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.holidays` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays"
                      ],
                      "query": [
                        {
                          "key": "year",
                          "value": "2026",
                          "description": "(Opcional) Año (2000-2100). Por defecto, el actual.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Feriados del país de la empresa y asuetos propios del año, con origen y exclusiones.\n\nPermiso requerido: `hr.holidays`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año (2000-2100). Por defecto, el actual. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.holidays` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": null,\n      \"country_code\": \"SV\",\n      \"date\": \"2026-11-02\",\n      \"name\": \"Día de los Difuntos\",\n      \"scope\": \"national\",\n      \"region_code\": null,\n      \"branch_id\": null,\n      \"action\": \"add\",\n      \"start_time\": null,\n      \"is_paid\": true,\n      \"source\": \"generator\",\n      \"origin\": \"country\",\n      \"is_excluded\": true,\n      \"exclusion_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n    },\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"country_code\": \"SV\",\n      \"date\": \"2026-12-24\",\n      \"name\": \"Nochebuena\",\n      \"scope\": \"company\",\n      \"region_code\": null,\n      \"branch_id\": null,\n      \"action\": \"add\",\n      \"start_time\": \"12:00\",\n      \"is_paid\": true,\n      \"source\": \"manual\",\n      \"origin\": \"company\",\n      \"is_excluded\": false,\n      \"exclusion_id\": null\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays"
                      ],
                      "query": [
                        {
                          "key": "year",
                          "value": "2026",
                          "description": "(Opcional) Año (2000-2100). Por defecto, el actual.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Feriados del país de la empresa y asuetos propios del año, con origen y exclusiones.\n\nPermiso requerido: `hr.holidays`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `year` | integer | No | Año (2000-2100). Por defecto, el actual. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.holidays` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear asueto",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/holidays",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "holidays"
                  ]
                },
                "description": "Crea un asueto de la empresa (uno por llamada). Recalcula la asistencia de esa fecha.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | Sí |  |\n| `name` | string | Sí |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"date\": \"2026-12-24\",\n  \"name\": \"Nochebuena\",\n  \"branch_id\": null,\n  \"start_time\": \"12:00\",\n  \"is_paid\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Asueto creado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays"
                      ]
                    },
                    "description": "Crea un asueto de la empresa (uno por llamada). Recalcula la asistencia de esa fecha.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | Sí |  |\n| `name` | string | Sí |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"date\": \"2026-12-24\",\n  \"name\": \"Nochebuena\",\n  \"branch_id\": null,\n  \"start_time\": \"12:00\",\n  \"is_paid\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"country_code\": \"SV\",\n    \"date\": \"2026-12-24\",\n    \"name\": \"Nochebuena\",\n    \"scope\": \"company\",\n    \"region_code\": null,\n    \"branch_id\": null,\n    \"action\": \"add\",\n    \"start_time\": \"12:00\",\n    \"is_paid\": true,\n    \"source\": \"manual\",\n    \"origin\": \"company\",\n    \"is_excluded\": false,\n    \"exclusion_id\": null,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays"
                      ]
                    },
                    "description": "Crea un asueto de la empresa (uno por llamada). Recalcula la asistencia de esa fecha.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | Sí |  |\n| `name` | string | Sí |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"date\": \"2026-12-24\",\n  \"name\": \"Nochebuena\",\n  \"branch_id\": null,\n  \"start_time\": \"12:00\",\n  \"is_paid\": true\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"date\": [\n      \"The date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Editar asueto",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/holidays/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "holidays",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{holiday_id}}",
                      "description": "ID del asueto"
                    }
                  ]
                },
                "description": "Edita un asueto de la empresa. Feriados del país y exclusiones responden 404.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No |  |\n| `name` | string | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"is_paid\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del asueto"
                        }
                      ]
                    },
                    "description": "Edita un asueto de la empresa. Feriados del país y exclusiones responden 404.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No |  |\n| `name` | string | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"is_paid\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"country_code\": \"SV\",\n    \"date\": \"2026-12-24\",\n    \"name\": \"Nochebuena\",\n    \"scope\": \"company\",\n    \"region_code\": null,\n    \"branch_id\": null,\n    \"action\": \"add\",\n    \"start_time\": \"12:00\",\n    \"is_paid\": true,\n    \"source\": \"manual\",\n    \"origin\": \"company\",\n    \"is_excluded\": false,\n    \"exclusion_id\": null,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del asueto"
                        }
                      ]
                    },
                    "description": "Edita un asueto de la empresa. Feriados del país y exclusiones responden 404.\n\nPermiso requerido: `hr.holidays.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `date` | string (date) | No |  |\n| `name` | string | No |  |\n| `branch_id` | string (uuid) | No |  |\n| `start_time` | string | No |  |\n| `is_paid` | boolean | No |  |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"is_paid\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"date\": [\n      \"The date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Eliminar asueto o exclusión",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/holidays/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "holidays",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{holiday_id}}",
                      "description": "ID del asueto o de la exclusión"
                    }
                  ]
                },
                "description": "Elimina un asueto de la empresa o una exclusión (`exclusion_id`).\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del asueto o de la exclusión"
                        }
                      ]
                    },
                    "description": "Elimina un asueto de la empresa o una exclusión (`exclusion_id`).\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"deleted\": true,\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "DELETE",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del asueto o de la exclusión"
                        }
                      ]
                    },
                    "description": "Elimina un asueto de la empresa o una exclusión (`exclusion_id`).\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Excluir feriado del país",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/holidays/:id/exclude",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "holidays",
                    ":id",
                    "exclude"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{holiday_id}}",
                      "description": "ID del feriado del país"
                    }
                  ]
                },
                "description": "La empresa trabaja ese feriado como día normal. Idempotente.\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id/exclude",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id",
                        "exclude"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del feriado del país"
                        }
                      ]
                    },
                    "description": "La empresa trabaja ese feriado como día normal. Idempotente.\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"business_id\": null,\n    \"country_code\": \"SV\",\n    \"date\": \"2026-11-02\",\n    \"name\": \"Día de los Difuntos\",\n    \"scope\": \"national\",\n    \"region_code\": null,\n    \"branch_id\": null,\n    \"action\": \"add\",\n    \"start_time\": null,\n    \"is_paid\": true,\n    \"source\": \"generator\",\n    \"origin\": \"country\",\n    \"is_excluded\": true,\n    \"exclusion_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"recalculation_queued\": true\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/holidays/:id/exclude",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "holidays",
                        ":id",
                        "exclude"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{holiday_id}}",
                          "description": "ID del feriado del país"
                        }
                      ]
                    },
                    "description": "La empresa trabaja ese feriado como día normal. Idempotente.\n\nPermiso requerido: `hr.holidays.write`\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.holidays.write` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Permisos",
          "item": [
            {
              "name": "Listar solicitudes de permiso",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/leave-requests?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "leave-requests"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "employee_id",
                      "value": "{{employee_id}}",
                      "description": "(Opcional) Filtra por empleado.",
                      "disabled": true
                    },
                    {
                      "key": "status",
                      "value": "pending",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    },
                    {
                      "key": "type",
                      "value": "vacation",
                      "description": "(Opcional) Tipo.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Solicitudes que se cruzan con el rango (máximo 93 días).\n\nPermiso requerido: `hr.leave_requests`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `rejected`, `cancelled` | No | Estado. |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | No | Tipo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/leave-requests?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "leave-requests"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "pending",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "type",
                          "value": "vacation",
                          "description": "(Opcional) Tipo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Solicitudes que se cruzan con el rango (máximo 93 días).\n\nPermiso requerido: `hr.leave_requests`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `rejected`, `cancelled` | No | Estado. |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | No | Tipo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employee_name\": \"María López\",\n      \"document_number\": \"01234567-8\",\n      \"type\": \"vacation\",\n      \"start_date\": \"2026-12-22\",\n      \"end_date\": \"2026-12-31\",\n      \"days\": 10,\n      \"status\": \"approved\",\n      \"reason\": \"Vacaciones anuales\"\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/leave-requests?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "leave-requests"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "employee_id",
                          "value": "{{employee_id}}",
                          "description": "(Opcional) Filtra por empleado.",
                          "disabled": true
                        },
                        {
                          "key": "status",
                          "value": "pending",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        },
                        {
                          "key": "type",
                          "value": "vacation",
                          "description": "(Opcional) Tipo.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Solicitudes que se cruzan con el rango (máximo 93 días).\n\nPermiso requerido: `hr.leave_requests`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `employee_id` | string | No | Filtra por empleado. |\n| `status` | string: `pending`, `approved`, `rejected`, `cancelled` | No | Estado. |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | No | Tipo. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Crear solicitud de permiso",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/leave-requests",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "leave-requests"
                  ]
                },
                "description": "Crea una solicitud en estado `pending`. La aprobación siempre se hace en FileXpress. Los días a descontar se calculan según el conteo de las reglas laborales del país (`leave.vacation_day_counting`: días calendario o hábiles). La respuesta `days` son los días calendario del rango.\n\nPermiso requerido: `hr.leave_requests`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string (uuid) | No | Empleado (o document_number). |\n| `document_number` | string | No | Documento (o employee_id). |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | Sí | Tipo. |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | Sí |  |\n| `reason` | string | No |  |\n| `half_day` | boolean | No | Medio día. Solo aplica a solicitudes de un día (si no, 422). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"document_number\": \"01234567-8\",\n  \"type\": \"vacation\",\n  \"start_date\": \"2026-12-22\",\n  \"end_date\": \"2026-12-31\",\n  \"reason\": \"Vacaciones anuales\",\n  \"half_day\": false\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "201 Solicitud creada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/leave-requests",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "leave-requests"
                      ]
                    },
                    "description": "Crea una solicitud en estado `pending`. La aprobación siempre se hace en FileXpress. Los días a descontar se calculan según el conteo de las reglas laborales del país (`leave.vacation_day_counting`: días calendario o hábiles). La respuesta `days` son los días calendario del rango.\n\nPermiso requerido: `hr.leave_requests`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string (uuid) | No | Empleado (o document_number). |\n| `document_number` | string | No | Documento (o employee_id). |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | Sí | Tipo. |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | Sí |  |\n| `reason` | string | No |  |\n| `half_day` | boolean | No | Medio día. Solo aplica a solicitudes de un día (si no, 422). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"document_number\": \"01234567-8\",\n  \"type\": \"vacation\",\n  \"start_date\": \"2026-12-22\",\n  \"end_date\": \"2026-12-31\",\n  \"reason\": \"Vacaciones anuales\",\n  \"half_day\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"employee_name\": \"María López\",\n    \"document_number\": \"01234567-8\",\n    \"type\": \"vacation\",\n    \"start_date\": \"2026-12-22\",\n    \"end_date\": \"2026-12-31\",\n    \"days\": 10,\n    \"status\": \"pending\",\n    \"reason\": \"Vacaciones anuales\"\n  }\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/leave-requests",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "leave-requests"
                      ]
                    },
                    "description": "Crea una solicitud en estado `pending`. La aprobación siempre se hace en FileXpress. Los días a descontar se calculan según el conteo de las reglas laborales del país (`leave.vacation_day_counting`: días calendario o hábiles). La respuesta `days` son los días calendario del rango.\n\nPermiso requerido: `hr.leave_requests`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `employee_id` | string (uuid) | No | Empleado (o document_number). |\n| `document_number` | string | No | Documento (o employee_id). |\n| `type` | string: `vacation`, `sick_leave`, `personal_leave`, `unpaid_leave`, `other` | Sí | Tipo. |\n| `start_date` | string (date) | Sí |  |\n| `end_date` | string (date) | Sí |  |\n| `reason` | string | No |  |\n| `half_day` | boolean | No | Medio día. Solo aplica a solicitudes de un día (si no, 422). |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.leave_requests` o desactivada.\n- `404`: Recurso inexistente o de otro negocio.\n- `409`: Conflicto.\n- `422`: Error de validación.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"document_number\": \"01234567-8\",\n  \"type\": \"vacation\",\n  \"start_date\": \"2026-12-22\",\n  \"end_date\": \"2026-12-31\",\n  \"reason\": \"Vacaciones anuales\",\n  \"half_day\": false\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"type\": [\n      \"The type field is required.\"\n    ]\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Planillas",
          "item": [
            {
              "name": "Listar planillas",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/payrolls?start_date=2026-10-01&end_date=2026-10-08",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "payrolls"
                  ],
                  "query": [
                    {
                      "key": "start_date",
                      "value": "2026-10-01",
                      "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                    },
                    {
                      "key": "end_date",
                      "value": "2026-10-08",
                      "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                    },
                    {
                      "key": "status",
                      "value": "processed",
                      "description": "(Opcional) Estado.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Planillas procesadas o pagadas cuyo período se cruza con el rango (máximo 370 días).\n\nPermiso requerido: `hr.payrolls`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `processed`, `paid` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `422`: Error de validación."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "status",
                          "value": "processed",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Planillas procesadas o pagadas cuyo período se cruza con el rango (máximo 370 días).\n\nPermiso requerido: `hr.payrolls`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `processed`, `paid` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": [\n    {\n      \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"name\": \"Primera quincena octubre 2026\",\n      \"start_date\": \"2026-10-01\",\n      \"end_date\": \"2026-10-15\",\n      \"status\": \"paid\",\n      \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"employees\": 12,\n      \"total_net_amount\": 4820.35\n    }\n  ]\n}"
                },
                {
                  "name": "422 Error de validación",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls?start_date=2026-10-01&end_date=2026-10-08",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls"
                      ],
                      "query": [
                        {
                          "key": "start_date",
                          "value": "2026-10-01",
                          "description": "(Requerido) Fecha inicial (YYYY-MM-DD)"
                        },
                        {
                          "key": "end_date",
                          "value": "2026-10-08",
                          "description": "(Requerido) Fecha final (YYYY-MM-DD)"
                        },
                        {
                          "key": "status",
                          "value": "processed",
                          "description": "(Opcional) Estado.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Planillas procesadas o pagadas cuyo período se cruza con el rango (máximo 370 días).\n\nPermiso requerido: `hr.payrolls`\n\n**Parámetros de consulta**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `start_date` | string (date) | Sí | Fecha inicial (YYYY-MM-DD) |\n| `end_date` | string (date) | Sí | Fecha final (YYYY-MM-DD) |\n| `status` | string: `processed`, `paid` | No | Estado. |\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `422`: Error de validación."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"start_date\": [\n      \"The start date field is required.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar planilla",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/payrolls/:id",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "payrolls",
                    ":id"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{payroll_id}}",
                      "description": "ID de la planilla"
                    }
                  ]
                },
                "description": "Detalle por empleado: ingresos, deducciones y aportes patronales.\n\nPermiso requerido: `hr.payrolls`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{payroll_id}}",
                          "description": "ID de la planilla"
                        }
                      ]
                    },
                    "description": "Detalle por empleado: ingresos, deducciones y aportes patronales.\n\nPermiso requerido: `hr.payrolls`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"name\": \"Primera quincena octubre 2026\",\n    \"start_date\": \"2026-10-01\",\n    \"end_date\": \"2026-10-15\",\n    \"status\": \"paid\",\n    \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"total_net_amount\": 4820.35,\n    \"details\": [\n      {\n        \"employee_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"employee_name\": \"María López\",\n        \"document_number\": \"01234567-8\",\n        \"cost_center_id\": null,\n        \"net_amount\": 371.29,\n        \"payment_status\": \"paid\",\n        \"payment_date\": \"2026-10-15\",\n        \"earnings\": [\n          {\n            \"name\": \"Horas extra\",\n            \"concept\": \"overtime\",\n            \"quantity\": 4,\n            \"amount\": 28.33\n          }\n        ],\n        \"deductions\": [\n          {\n            \"name\": \"ISSS Laboral\",\n            \"concept\": \"policy\",\n            \"quantity\": null,\n            \"amount\": 13.6\n          },\n          {\n            \"name\": \"Renta (ISR)\",\n            \"concept\": \"income_tax\",\n            \"quantity\": null,\n            \"amount\": 1.95\n          }\n        ],\n        \"employer_contributions\": [\n          {\n            \"name\": \"ISSS Patronal\",\n            \"concept\": \"policy\",\n            \"quantity\": null,\n            \"amount\": 34.0\n          }\n        ]\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "404 Recurso inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls/:id",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls",
                        ":id"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{payroll_id}}",
                          "description": "ID de la planilla"
                        }
                      ]
                    },
                    "description": "Detalle por empleado: ingresos, deducciones y aportes patronales.\n\nPermiso requerido: `hr.payrolls`\n\n**Notas**\n\n- `403`: Integración sin el permiso `hr.payrolls` o desactivada.\n- `404`: Recurso inexistente o de otro negocio."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Not found.\"\n}"
                }
              ]
            },
            {
              "name": "Asignar centro de costo a una planilla",
              "request": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/hr/payrolls/:id/cost-center",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "hr",
                    "payrolls",
                    ":id",
                    "cost-center"
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{payroll_id}}",
                      "description": "ID de la planilla"
                    }
                  ]
                },
                "description": "Centro de la planilla (`null` lo quita; omitido no cambia) y, por empleado, un centro propio (`null` = usa el de la planilla). Al contabilizar, los gastos de salarios y aportes patronales se agrupan por cuenta y centro. En lugar de un centro se puede enviar `cost_center_distribution_id` (planilla o empleado): el gasto se reparte por porcentaje. No modifica partidas ya generadas.\n\nPermiso requerido: `hr.payrolls.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de la planilla; null lo quita, omitido no cambia. |\n| `details` | array de object | No |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución de la planilla; null la quita, omitido no cambia. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.payrolls.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, empleado fuera de la planilla o centro inválido.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\",\n  \"details\": [\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"cost_center_id\": null\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls/:id/cost-center",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls",
                        ":id",
                        "cost-center"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{payroll_id}}",
                          "description": "ID de la planilla"
                        }
                      ]
                    },
                    "description": "Centro de la planilla (`null` lo quita; omitido no cambia) y, por empleado, un centro propio (`null` = usa el de la planilla). Al contabilizar, los gastos de salarios y aportes patronales se agrupan por cuenta y centro. En lugar de un centro se puede enviar `cost_center_distribution_id` (planilla o empleado): el gasto se reparte por porcentaje. No modifica partidas ya generadas.\n\nPermiso requerido: `hr.payrolls.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de la planilla; null lo quita, omitido no cambia. |\n| `details` | array de object | No |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución de la planilla; null la quita, omitido no cambia. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.payrolls.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, empleado fuera de la planilla o centro inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\",\n  \"details\": [\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"cost_center_id\": null\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"cost_center_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"cost_center_distribution_id\": null,\n    \"details\": [\n      {\n        \"employee_id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"cost_center_id\": null,\n        \"cost_center_distribution_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\"\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "422 Validación, empleado fuera de la planilla o centro inválido",
                  "originalRequest": {
                    "method": "PUT",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url}}/hr/payrolls/:id/cost-center",
                      "host": [
                        "{{base_url}}"
                      ],
                      "path": [
                        "hr",
                        "payrolls",
                        ":id",
                        "cost-center"
                      ],
                      "variable": [
                        {
                          "key": "id",
                          "value": "{{payroll_id}}",
                          "description": "ID de la planilla"
                        }
                      ]
                    },
                    "description": "Centro de la planilla (`null` lo quita; omitido no cambia) y, por empleado, un centro propio (`null` = usa el de la planilla). Al contabilizar, los gastos de salarios y aportes patronales se agrupan por cuenta y centro. En lugar de un centro se puede enviar `cost_center_distribution_id` (planilla o empleado): el gasto se reparte por porcentaje. No modifica partidas ya generadas.\n\nPermiso requerido: `hr.payrolls.write`\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `cost_center_id` | string (uuid) | No | Centro de la planilla; null lo quita, omitido no cambia. |\n| `details` | array de object | No |  |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución de la planilla; null la quita, omitido no cambia. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n\n**Notas**\n\n- Los identificadores se validan contra el negocio de la integración: un recurso de otro negocio responde `404`, igual que uno inexistente.\n- `403`: Integración sin el permiso `hr.payrolls.write` o desactivada.\n- `404`: No encontrado o de otro negocio.\n- `422`: Validación, empleado fuera de la planilla o centro inválido.",
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"cost_center_id\": \"{{cost_center_id}}\",\n  \"details\": [\n    {\n      \"employee_id\": \"{{employee_id}}\",\n      \"cost_center_id\": null\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"details.0.employee_id\": \"El empleado no pertenece a esta planilla.\"\n  }\n}"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "API v2",
      "description": "Endpoints de la API Externa v2 (`{{base_url_v2}}` = https://api.filexpress.app/api/external/v2): monedas y tasas de cambio, capacidades por país, y ventas y compras con moneda extranjera, `tax_ids` por línea y errores con `code` estable. Usan la misma API Key que v1. Todo lo demás permanece en v1 (`{{base_url}}`).",
      "item": [
        {
          "name": "General",
          "item": [
            {
              "name": "Verificar la conexión (v2)",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/health",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "health"
                  ]
                },
                "description": "Responde `Working` sin requerir autenticación.\n\nPermiso requerido: ninguno\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).",
                "auth": {
                  "type": "noauth"
                }
              },
              "response": [
                {
                  "name": "200 Servicio disponible",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/health",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "health"
                      ]
                    },
                    "description": "Responde `Working` sin requerir autenticación.\n\nPermiso requerido: ninguno\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).",
                    "auth": {
                      "type": "noauth"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "text",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "text/plain"
                    }
                  ],
                  "body": "Working"
                }
              ]
            }
          ]
        },
        {
          "name": "Monedas y tasas",
          "item": [
            {
              "name": "Listar monedas",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/currencies",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "currencies"
                  ]
                },
                "description": "Moneda base del negocio y monedas extranjeras activas. Solo v2.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/currencies",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "currencies"
                      ]
                    },
                    "description": "Moneda base del negocio y monedas extranjeras activas. Solo v2.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"base_currency_code\": \"USD\",\n    \"currencies\": [\n      {\n        \"code\": \"USD\",\n        \"name\": \"Dólar estadounidense\",\n        \"symbol\": \"$\",\n        \"decimals\": 2,\n        \"is_base\": true\n      },\n      {\n        \"code\": \"GTQ\",\n        \"name\": \"Quetzal guatemalteco\",\n        \"symbol\": \"Q\",\n        \"decimals\": 2,\n        \"is_base\": false\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "403 Sin el permiso currencies",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/currencies",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "currencies"
                      ]
                    },
                    "description": "Moneda base del negocio y monedas extranjeras activas. Solo v2.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"This integration does not have the 'currencies' permission.\",\n  \"required_scope\": \"currencies\"\n}"
                },
                {
                  "name": "403 Multi-moneda deshabilitada",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/currencies",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "currencies"
                      ]
                    },
                    "description": "Moneda base del negocio y monedas extranjeras activas. Solo v2.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"Multi-moneda no está habilitada para esta empresa.\"\n}"
                }
              ]
            },
            {
              "name": "Listar tasas de cambio",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/exchange-rates",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "exchange-rates"
                  ],
                  "query": [
                    {
                      "key": "currency",
                      "value": "GTQ",
                      "description": "(Opcional) Código de la moneda (por ejemplo GTQ).",
                      "disabled": true
                    },
                    {
                      "key": "from",
                      "value": "2026-10-01",
                      "description": "(Opcional) Vigente desde (YYYY-MM-DD).",
                      "disabled": true
                    },
                    {
                      "key": "to",
                      "value": "2026-10-31",
                      "description": "(Opcional) Vigente hasta (YYYY-MM-DD).",
                      "disabled": true
                    },
                    {
                      "key": "per_page",
                      "value": "",
                      "description": "(Opcional) 1 a 200 (por defecto 50).",
                      "disabled": true
                    },
                    {
                      "key": "page",
                      "value": "",
                      "description": "(Opcional) Página.",
                      "disabled": true
                    }
                  ]
                },
                "description": "Tasas del negocio, de la más reciente a la más antigua. `rate` son unidades de moneda base por 1 unidad de la moneda extranjera.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates"
                      ],
                      "query": [
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Opcional) Código de la moneda (por ejemplo GTQ).",
                          "disabled": true
                        },
                        {
                          "key": "from",
                          "value": "2026-10-01",
                          "description": "(Opcional) Vigente desde (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "to",
                          "value": "2026-10-31",
                          "description": "(Opcional) Vigente hasta (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "",
                          "description": "(Opcional) 1 a 200 (por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Tasas del negocio, de la más reciente a la más antigua. `rate` son unidades de moneda base por 1 unidad de la moneda extranjera.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"base_currency_code\": \"USD\",\n    \"rates\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"currency_code\": \"GTQ\",\n        \"rate\": \"0.13000000\",\n        \"effective_date\": \"2026-10-20\",\n        \"source\": \"manual\"\n      },\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"currency_code\": \"GTQ\",\n        \"rate\": \"0.12800000\",\n        \"effective_date\": \"2026-10-15\",\n        \"source\": \"manual\"\n      }\n    ],\n    \"current_page\": 1,\n    \"last_page\": 1,\n    \"per_page\": 50,\n    \"total\": 2\n  }\n}"
                },
                {
                  "name": "403 Sin el permiso currencies",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates"
                      ],
                      "query": [
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Opcional) Código de la moneda (por ejemplo GTQ).",
                          "disabled": true
                        },
                        {
                          "key": "from",
                          "value": "2026-10-01",
                          "description": "(Opcional) Vigente desde (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "to",
                          "value": "2026-10-31",
                          "description": "(Opcional) Vigente hasta (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "",
                          "description": "(Opcional) 1 a 200 (por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Tasas del negocio, de la más reciente a la más antigua. `rate` son unidades de moneda base por 1 unidad de la moneda extranjera.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"This integration does not have the 'currencies' permission.\",\n  \"required_scope\": \"currencies\"\n}"
                },
                {
                  "name": "403 Multi-moneda deshabilitada",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates"
                      ],
                      "query": [
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Opcional) Código de la moneda (por ejemplo GTQ).",
                          "disabled": true
                        },
                        {
                          "key": "from",
                          "value": "2026-10-01",
                          "description": "(Opcional) Vigente desde (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "to",
                          "value": "2026-10-31",
                          "description": "(Opcional) Vigente hasta (YYYY-MM-DD).",
                          "disabled": true
                        },
                        {
                          "key": "per_page",
                          "value": "",
                          "description": "(Opcional) 1 a 200 (por defecto 50).",
                          "disabled": true
                        },
                        {
                          "key": "page",
                          "value": "",
                          "description": "(Opcional) Página.",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "Tasas del negocio, de la más reciente a la más antigua. `rate` son unidades de moneda base por 1 unidad de la moneda extranjera.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"Multi-moneda no está habilitada para esta empresa.\"\n}"
                }
              ]
            },
            {
              "name": "Resolver la tasa de un documento",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "exchange-rates",
                    "resolve"
                  ],
                  "query": [
                    {
                      "key": "branch_id",
                      "value": "{{branch_id}}",
                      "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                    },
                    {
                      "key": "currency",
                      "value": "GTQ",
                      "description": "(Requerido) Código de 3 letras."
                    },
                    {
                      "key": "date",
                      "value": "2026-10-17",
                      "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                      "disabled": true
                    }
                  ]
                },
                "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"currency_code\": \"GTQ\",\n    \"base_currency_code\": \"USD\",\n    \"rate\": \"0.12800000\",\n    \"effective_date\": \"2026-10-15\",\n    \"exact\": false,\n    \"source\": \"manual\"\n  }\n}"
                },
                {
                  "name": "403 Sin el permiso currencies",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"This integration does not have the 'currencies' permission.\",\n  \"required_scope\": \"currencies\"\n}"
                },
                {
                  "name": "403 Multi-moneda deshabilitada",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"Multi-moneda no está habilitada para esta empresa.\"\n}"
                },
                {
                  "name": "404 Sin tasa a la fecha ni anterior",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"exchange_rate_not_found\",\n  \"message\": \"No hay tasa de cambio para GTQ a la fecha 2026-10-01 ni anterior. Registre una tasa de cambio o envíe exchange_rate en el documento.\",\n  \"errors\": {\n    \"exchange_rate\": \"Sin tasa de cambio para GTQ al 2026-10-01.\"\n  }\n}"
                },
                {
                  "name": "422 Parámetro inválido",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"validation_error\",\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"currency\": [\n      \"Obligatoria (código de 3 letras).\"\n    ]\n  }\n}"
                },
                {
                  "name": "422 Moneda no activa",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/exchange-rates/resolve?branch_id={{branch_id}}&currency=GTQ",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "exchange-rates",
                        "resolve"
                      ],
                      "query": [
                        {
                          "key": "branch_id",
                          "value": "{{branch_id}}",
                          "description": "(Requerido) Sucursal del negocio (GET /branches en v1). De otro negocio -> 422 `validation_error`."
                        },
                        {
                          "key": "currency",
                          "value": "GTQ",
                          "description": "(Requerido) Código de 3 letras."
                        },
                        {
                          "key": "date",
                          "value": "2026-10-17",
                          "description": "(Opcional) Fecha del documento (por defecto, hoy).",
                          "disabled": true
                        }
                      ]
                    },
                    "description": "La tasa que se aplicaría a un documento de la sucursal, moneda y fecha indicadas: la del día o la última anterior (una tasa de la sucursal tiene prioridad sobre la general). `exact` es false si se usó una fecha anterior.\n\nPermiso requerido: `currencies`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"La moneda GTQ no está activa para este negocio.\",\n  \"errors\": {\n    \"currency\": \"La moneda GTQ no está activa.\"\n  }\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Países",
          "item": [
            {
              "name": "Capacidades y catálogos de un país",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/countries/{{country_code}}",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "countries",
                    "{{country_code}}"
                  ]
                },
                "description": "Tipos de documento, formas de pago, impuestos, reglas de impuestos y capacidades de facturación de un país, para armar documentos sin código específico por país. `base_currency_of_business` es la moneda base del negocio de la integración. Solo lee catálogos del país pedido; nunca datos de otros negocios. Responde 404 `country_not_supported` si no hay facturación electrónica configurada para el país.\n\nPermiso requerido: `countries`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/countries/{{country_code}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "countries",
                        "{{country_code}}"
                      ]
                    },
                    "description": "Tipos de documento, formas de pago, impuestos, reglas de impuestos y capacidades de facturación de un país, para armar documentos sin código específico por país. `base_currency_of_business` es la moneda base del negocio de la integración. Solo lee catálogos del país pedido; nunca datos de otros negocios. Responde 404 `country_not_supported` si no hay facturación electrónica configurada para el país.\n\nPermiso requerido: `countries`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"country_code\": \"GT\",\n    \"name\": \"Guatemala\",\n    \"legal_currency\": \"GTQ\",\n    \"base_currency_of_business\": \"USD\",\n    \"timezone\": \"America/Guatemala\",\n    \"document_types\": [\n      {\n        \"code\": \"fact\",\n        \"name\": \"Factura\",\n        \"number_code\": \"01\",\n        \"applicable_to\": \"both\",\n        \"requires\": []\n      }\n    ],\n    \"payment_methods\": [\n      {\n        \"id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n        \"code\": \"01\",\n        \"name\": \"Efectivo\"\n      }\n    ],\n    \"taxes\": [\n      {\n        \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n        \"name\": \"IVA\",\n        \"number_code\": \"20\",\n        \"tax_type\": \"percentage\",\n        \"percent\": 12,\n        \"effect\": \"add\"\n      }\n    ],\n    \"tax_rules\": [],\n    \"identification_types\": [],\n    \"adapter\": {\n      \"signs\": false,\n      \"async\": false,\n      \"void_mode\": \"cancel\",\n      \"supports_draft\": true,\n      \"supports_skip_transmission\": false,\n      \"country_data_schema\": {\n        \"fcam\": {\n          \"periodos\": {\n            \"type\": \"integer\",\n            \"required\": false,\n            \"default\": 1,\n            \"description\": \"Número de periodos (>= 1).\"\n          }\n        }\n      }\n    }\n  }\n}"
                },
                {
                  "name": "403 Integración sin el permiso `countries`",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/countries/{{country_code}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "countries",
                        "{{country_code}}"
                      ]
                    },
                    "description": "Tipos de documento, formas de pago, impuestos, reglas de impuestos y capacidades de facturación de un país, para armar documentos sin código específico por país. `base_currency_of_business` es la moneda base del negocio de la integración. Solo lee catálogos del país pedido; nunca datos de otros negocios. Responde 404 `country_not_supported` si no hay facturación electrónica configurada para el país.\n\nPermiso requerido: `countries`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Forbidden",
                  "code": 403,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"This integration does not have the 'countries' permission.\",\n  \"required_scope\": \"countries\"\n}"
                },
                {
                  "name": "404 País sin facturación electrónica configurada",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/countries/{{country_code}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "countries",
                        "{{country_code}}"
                      ]
                    },
                    "description": "Tipos de documento, formas de pago, impuestos, reglas de impuestos y capacidades de facturación de un país, para armar documentos sin código específico por país. `base_currency_of_business` es la moneda base del negocio de la integración. Solo lee catálogos del país pedido; nunca datos de otros negocios. Responde 404 `country_not_supported` si no hay facturación electrónica configurada para el país.\n\nPermiso requerido: `countries`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"country_not_supported\",\n  \"message\": \"No hay facturación electrónica configurada para el país XX.\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Ventas",
          "item": [
            {
              "name": "Crear venta (v2)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/sales",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "sales"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
              },
              "response": [
                {
                  "name": "200 Documento emitido",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"message\": \"Invoice created successfully\",\n  \"data\": {\n    \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n    \"control_number\": \"DTE-03-M001P001-000000000000045\",\n    \"status\": \"PROCESADO\",\n    \"issue_time\": \"2026-10-21 10:00:00\",\n    \"stamp\": \"2026A1B2C3D4E5F6\",\n    \"point_of_sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"establishment_code\": \"M001\",\n    \"point_of_sale_code\": \"P001\",\n    \"total\": 110.48,\n    \"currency_code\": \"GTQ\",\n    \"exchange_rate\": \"0.12800000\",\n    \"foreign_total\": \"863.13\",\n    \"base_currency_code\": \"USD\"\n  }\n}"
                },
                {
                  "name": "409 Otra solicitud con la misma `Idempotency-Key` sigue en curso. Espere y reintente con la misma llave.",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "",
                  "code": 409,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"idempotency_in_progress\",\n  \"message\": \"Hay otra solicitud en curso con la misma Idempotency-Key.\"\n}"
                },
                {
                  "name": "422 Impuestos distintos al recalculado",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"tax_invalid\",\n  \"message\": \"Impuestos inválidos\",\n  \"errors\": [\n    {\n      \"field\": \"invoiceResumenDetail.totalTax\",\n      \"code\": \"tax_amount_mismatch\",\n      \"message\": \"totalTax enviado (20) difiere del calculado (13).\"\n    }\n  ]\n}"
                },
                {
                  "name": "422 Falta tax_ids en una línea",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"validation_error\",\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"products.0.tax_ids\": [\n      \"The products.0.tax_ids field must be present.\"\n    ]\n  }\n}"
                },
                {
                  "name": "422 Moneda no activa",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"La moneda GTQ no está activa para este negocio.\",\n  \"errors\": {\n    \"currency_code\": \"La moneda GTQ no está activa.\"\n  }\n}"
                },
                {
                  "name": "422 Sin tasa vigente",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"exchange_rate_not_found\",\n  \"message\": \"No hay tasa de cambio para GTQ a la fecha 2026-10-21 ni anterior. Registre una tasa de cambio o envíe exchange_rate en el documento.\",\n  \"errors\": {\n    \"exchange_rate\": \"Sin tasa de cambio para GTQ al 2026-10-21.\"\n  }\n}"
                },
                {
                  "name": "422 Tasa inválida",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"exchange_rate_invalid\",\n  \"message\": \"La tasa de cambio del documento debe ser un número mayor que cero.\",\n  \"errors\": {\n    \"exchange_rate\": \"Debe ser mayor que cero.\"\n  }\n}"
                },
                {
                  "name": "422 Base distinta de la moneda legal",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"base_currency_not_legal\",\n  \"message\": \"El documento electrónico debe emitirse en GTQ (moneda legal de GT) y la moneda base del negocio es USD. Corrija la moneda base del negocio antes de emitir en moneda extranjera.\",\n  \"errors\": {\n    \"currency_code\": \"La moneda base (USD) no es la moneda legal (GTQ).\"\n  }\n}"
                },
                {
                  "name": "422 country_data inválido para el país",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"country_data_invalid\",\n  \"message\": \"country_data inválido para GT\",\n  \"errors\": {\n    \"periodos\": \"Debe ser un entero mayor o igual a 1.\"\n  }\n}"
                },
                {
                  "name": "422 Idempotency-Key usada con otro cuerpo",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"idempotency_key_reused\",\n  \"message\": \"La Idempotency-Key ya se usó con una solicitud distinta.\"\n}"
                },
                {
                  "name": "422 Idempotency-Key de más de 120 caracteres",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"customer_id\": \"{{customer_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"payment_details\": [\n    {\n      \"payment_method_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n      \"amount\": 863.13\n    }\n  ],\n  \"products\": [\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de transporte\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"discount\": 0,\n      \"subtotal\": 500.0,\n      \"sale_taxed\": 500.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"id\": \"{{product_id}}\",\n      \"name\": \"Servicio de carga\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"discount\": 0,\n      \"subtotal\": 250.0,\n      \"sale_taxed\": 250.0,\n      \"sale_exent\": 0,\n      \"sale_not_suject\": 0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 750.0,\n    \"saleTotalNotSuject\": 0,\n    \"saleTotalExent\": 0,\n    \"saleTotalTax\": 750.0,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 0,\n    \"totalRent\": 0,\n    \"saleTotalToPayment\": 863.13,\n    \"taxes\": [\n      {\n        \"tax_id\": \"{{tax_vat_id}}\",\n        \"amount\": 97.5\n      },\n      {\n        \"tax_id\": \"{{tax_fixed_id}}\",\n        \"amount\": 15.63\n      }\n    ],\n    \"withholdings\": []\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /sales` de v1, más moneda (`currency_code`, `exchange_rate`), `tax_ids` obligatorio por línea y validación estricta de impuestos (un monto distinto al recalculado responde 422 `tax_invalid`). Los montos del documento van en la moneda de `currency_code`; el servidor los convierte a la moneda base y el DTE sale en la moneda legal del país. `data.total` es el total a pagar en moneda base y `foreign_total`, en la moneda del documento.\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal emisora (GET /branches). |\n| `customer_id` | string (uuid) | Sí | Cliente receptor. |\n| `document_type` | string | Sí | SV: fc, ccf, fex, nc, nd, nr. US: inv, cm, dm. |\n| `date` | string | No | Fecha y hora ISO 8601. Por defecto, ahora. |\n| `observation` | string | No | Observaciones. |\n| `is_credit` | boolean | No | Venta al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `project_id` | string (uuid) | No | Proyecto asociado. |\n| `point_of_sale_id` | string (uuid) | No | Punto de venta emisor (de la sucursal y activo). Por defecto, el predeterminado de la sucursal. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la venta (hoja y activo; GET /accounting/cost-centers). Va a las líneas de ingreso al contabilizar. |\n| `incoterm_id` | string (uuid) | No | Incoterm (exportación). |\n| `payment_details` | array | Sí |  |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.saleTotalToPayment` se omite, el servidor calcula los montos de línea, impuestos, retenciones y totales; solo hacen falta cantidad, precio sin impuestos, descuento y `tax_ids`. No disponible para `fc` (`totals_required`). |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa (GET /accounting/cost-center-distributions): el ingreso se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `country_data` | object | No | Campos propios del país de la sucursal para este documento (por ejemplo, en Guatemala los de `fcam`, `nabn`, `ncre`, `ndeb` y `nev`). Debe ser un objeto, no una lista. Su esquema por tipo de documento está en `adapter.country_data_schema` de `GET /v2/countries/{code}`. Se valida antes de transmitir, y solo si el negocio tiene facturación electrónica activa; un campo inválido responde 422 `country_data_invalid`. En Guatemala también se acepta el alias `gt`; si vienen los dos, manda `country_data`. El Salvador no usa `country_data`. |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `tax_invalid`, `country_data_invalid`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"validation_error\",\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"Idempotency-Key\": [\n      \"Máximo 120 caracteres.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar venta (v2)",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/sales/{{sale_id}}",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "sales",
                    "{{sale_id}}"
                  ]
                },
                "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales/{{sale_id}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales",
                        "{{sale_id}}"
                      ]
                    },
                    "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"sale_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"6F1E2D3C-8A4B-4C5D-9E6F-0A1B2C3D4E5F\",\n    \"control_number\": \"DTE-03-M001P001-000000000000045\",\n    \"document_type\": \"ccf\",\n    \"status\": \"PROCESADO\",\n    \"issue_time\": \"2026-10-21 10:00:00\",\n    \"stamp\": \"2026A1B2C3D4E5F6\",\n    \"payment_status\": \"payed\",\n    \"is_credit\": false,\n    \"customer\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"legal_name\": \"Grupo Alfa, S.A. de C.V.\",\n      \"customer_name\": \"Grupo Alfa\"\n    },\n    \"totals\": {\n      \"sale_total\": 110.48,\n      \"sale_to_payment\": 110.48\n    },\n    \"products\": [\n      {\n        \"name\": \"Servicio de transporte\",\n        \"quantity\": 5,\n        \"individual_price\": 12.8,\n        \"subtotal\": 64.0\n      }\n    ],\n    \"currency_code\": \"GTQ\",\n    \"exchange_rate\": \"0.12800000\",\n    \"foreign_total\": \"863.13\",\n    \"base_currency_code\": \"USD\"\n  }\n}"
                },
                {
                  "name": "404 Venta inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/sales/{{sale_id}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "sales",
                        "{{sale_id}}"
                      ]
                    },
                    "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `sales`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Sale not found\"\n}"
                }
              ]
            }
          ]
        },
        {
          "name": "Compras y gastos",
          "item": [
            {
              "name": "Registrar compra (v2)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Idempotency-Key",
                    "value": "{{$guid}}",
                    "disabled": true,
                    "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/expenses",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "expenses"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
              },
              "response": [
                {
                  "name": "200 Compra registrada",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"message\": \"Expense created successfully\",\n  \"data\": {\n    \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n    \"control_number\": \"DTE-03-M001P001-000000000000123\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-21 10:00:00\",\n    \"total\": 1040.94,\n    \"currency_code\": \"GTQ\",\n    \"exchange_rate\": \"0.12800000\",\n    \"foreign_total\": \"1040.94\",\n    \"base_currency_code\": \"USD\"\n  }\n}"
                },
                {
                  "name": "409 Otra solicitud con la misma `Idempotency-Key` sigue en curso. Espere y reintente con la misma llave.",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "",
                  "code": 409,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"idempotency_in_progress\",\n  \"message\": \"Hay otra solicitud en curso con la misma Idempotency-Key.\"\n}"
                },
                {
                  "name": "422 Moneda no activa",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"currency_not_enabled\",\n  \"message\": \"La moneda GTQ no está activa para este negocio.\",\n  \"errors\": {\n    \"currency_code\": \"La moneda GTQ no está activa.\"\n  }\n}"
                },
                {
                  "name": "422 Sin tasa vigente",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"exchange_rate_not_found\",\n  \"message\": \"No hay tasa de cambio para GTQ a la fecha 2026-10-21 ni anterior. Registre una tasa de cambio o envíe exchange_rate en el documento.\",\n  \"errors\": {\n    \"exchange_rate\": \"Sin tasa de cambio para GTQ al 2026-10-21.\"\n  }\n}"
                },
                {
                  "name": "422 Falta tax_ids o el id no existe",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"validation_error\",\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"products.0.tax_ids\": [\n      \"The products.0.tax_ids field must be present.\"\n    ]\n  }\n}"
                },
                {
                  "name": "422 Idempotency-Key usada con otro cuerpo",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"idempotency_key_reused\",\n  \"message\": \"La Idempotency-Key ya se usó con una solicitud distinta.\"\n}"
                },
                {
                  "name": "422 Idempotency-Key de más de 120 caracteres",
                  "originalRequest": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      },
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Idempotency-Key",
                        "value": "{{$guid}}",
                        "disabled": true,
                        "description": "(Opcional) Opcional. Llave única por operación (máx. 120 caracteres; más de 120 responde 422 `validation_error`). Vale 24 h por integración. Un reintento con la misma llave y el mismo cuerpo devuelve la respuesta original (mismo código y cuerpo) con la cabecera `Idempotent-Replay: true`, sin emitir de nuevo. Con otro cuerpo o endpoint responde 422 `idempotency_key_reused`; mientras la primera solicitud sigue en curso, 409 `idempotency_in_progress`. Solo se guardan las respuestas 2xx y 422; un error 5xx, 401, 403, 404 o 429 no queda guardado y se puede reintentar con la misma llave."
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"branch_id\": \"{{branch_id}}\",\n  \"provider_id\": \"{{provider_id}}\",\n  \"document_type\": \"ccf\",\n  \"date\": \"2026-10-21T10:00:00\",\n  \"is_credit\": true,\n  \"credit_days\": 30,\n  \"number_control\": \"DTE-03-M001P001-000000000000123\",\n  \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n  \"currency_code\": \"GTQ\",\n  \"exchange_rate\": 0.128,\n  \"products\": [\n    {\n      \"sku\": \"COM-001\",\n      \"name\": \"Diésel\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 100.0,\n      \"expense_taxed\": 500.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 500.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id_2}}\"\n      ]\n    },\n    {\n      \"sku\": \"COM-002\",\n      \"name\": \"Gasolina\",\n      \"type\": \"goods\",\n      \"quantity\": 5,\n      \"price_before_taxes\": 50.0,\n      \"expense_taxed\": 250.0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 250.0,\n      \"tax_ids\": [\n        \"{{tax_vat_id}}\",\n        \"{{tax_fixed_id}}\"\n      ]\n    },\n    {\n      \"sku\": \"SRV-010\",\n      \"name\": \"Servicio exento\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 125.0,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 125.0,\n      \"expense_not_suject\": 0,\n      \"subtotal\": 125.0,\n      \"tax_ids\": []\n    },\n    {\n      \"sku\": \"SRV-011\",\n      \"name\": \"Servicio no sujeto\",\n      \"type\": \"services\",\n      \"quantity\": 1,\n      \"price_before_taxes\": 62.5,\n      \"expense_taxed\": 0,\n      \"expense_exent\": 0,\n      \"expense_not_suject\": 62.5,\n      \"subtotal\": 62.5,\n      \"tax_ids\": []\n    }\n  ],\n  \"totals\": {\n    \"netTotals\": 937.5,\n    \"charge_1\": 15.63,\n    \"charge_2\": 7.81,\n    \"expenseTotalTax\": 750.0,\n    \"expenseTotalExent\": 125.0,\n    \"expenseTotalNotSuject\": 62.5,\n    \"totalTax\": 97.5,\n    \"totalRetein\": 7.5,\n    \"totalRent\": 10.0,\n    \"expenseTotalToPayment\": 1040.94\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "description": "Igual que `POST /expenses` de v1, más moneda (`currency_code`, `exchange_rate`) y `tax_ids` obligatorio por línea (deben existir). El guardado de compras **no recalcula impuestos**: guarda lo que envía el cliente (convertido a base si trae moneda). `data.total` repite el `expenseTotalToPayment` enviado (en la moneda del documento).\n\nAcepta la cabecera opcional `Idempotency-Key` para reintentar sin duplicar el documento (ver el parámetro).\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2).\n\n**Campos del cuerpo**\n\n| Campo | Tipo | Requerido | Descripción |\n|---|---|---|---|\n| `branch_id` | string (uuid) | Sí | Sucursal. |\n| `provider_id` | string (uuid) | Sí | Proveedor. |\n| `document_type` | string | Sí | Tipo de documento. |\n| `date` | string (date) | Sí | Fecha. |\n| `is_credit` | boolean | Sí | Al crédito. |\n| `credit_days` | integer | No | Días de crédito. |\n| `observation` | string | No | Observaciones. |\n| `number_control` | string | No | Número de control del DTE. |\n| `generation_code` | string | No | Código de generación. |\n| `stamp` | string | No | Sello. |\n| `cost_center_id` | string (uuid) | No | Centro de costo de la compra (hoja y activo; GET /accounting/cost-centers). |\n| `products` | array | Sí |  |\n| `totals` | object | No | Modo calculado: si `totals.expenseTotalToPayment` se omite, el servidor calcula montos de línea, IVA, cargos fijos y total; `totalRetein` y `totalRent` los envía usted. |\n| `cost_center_distribution_id` | string (uuid) | No | Distribución activa: el gasto se reparte entre sus centros por porcentaje. Excluyente con `cost_center_id` en el mismo nivel (422 `Indique centro de costo o distribución, no ambos.`). |\n| `currency_code` | string | No | Moneda del documento (3 letras, por ejemplo GTQ). Debe estar activa para el negocio (GET /v2/currencies). Si se omite o es la moneda base, el documento es en moneda base. Todos los montos van en esta moneda. |\n| `exchange_rate` | number | No | Unidades de moneda base por 1 unidad de `currency_code`. Si se omite, se usa la tasa vigente a la fecha del documento. |\n\n**Códigos de error** (campo `code`): `currency_not_enabled`, `exchange_rate_not_found`, `exchange_rate_invalid`, `base_currency_not_legal`, `validation_error`, `idempotency_key_reused`, `idempotency_in_progress` (409). Ver la documentación de la API v2."
                  },
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"code\": \"validation_error\",\n  \"message\": \"Validation errors\",\n  \"errors\": {\n    \"Idempotency-Key\": [\n      \"Máximo 120 caracteres.\"\n    ]\n  }\n}"
                }
              ]
            },
            {
              "name": "Consultar compra (v2)",
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{base_url_v2}}/expenses/{{expense_id}}",
                  "host": [
                    "{{base_url_v2}}"
                  ],
                  "path": [
                    "expenses",
                    "{{expense_id}}"
                  ]
                },
                "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
              },
              "response": [
                {
                  "name": "200 Éxito",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses/{{expense_id}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses",
                        "{{expense_id}}"
                      ]
                    },
                    "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": true,\n  \"data\": {\n    \"expense_id\": \"9d1c5a3e-4b7f-4e2a-9c1d-2f6b8a0e7c11\",\n    \"generation_code\": \"A1B2C3D4-5E6F-4A7B-8C9D-0E1F2A3B4C5D\",\n    \"control_number\": \"DTE-03-M001P001-000000000000123\",\n    \"document_type\": \"ccf\",\n    \"status\": \"processed\",\n    \"issue_time\": \"2026-10-21 10:00:00\",\n    \"payment_status\": \"pending\",\n    \"is_credit\": true,\n    \"provider\": {\n      \"id\": \"3b8e2f10-7c4d-4a9e-b1f2-5d6c7e8f9a01\",\n      \"legal_name\": \"Distribuidora XYZ S.A. de C.V.\",\n      \"provider_name\": \"Distribuidora XYZ\"\n    },\n    \"totals\": {\n      \"expense_total\": 120.0,\n      \"expense_to_payment\": 133.24\n    },\n    \"products\": [\n      {\n        \"sku\": \"COM-001\",\n        \"name\": \"Diésel\",\n        \"quantity\": 5,\n        \"individual_price\": 12.8,\n        \"subtotal\": 64.0\n      }\n    ],\n    \"currency_code\": \"GTQ\",\n    \"exchange_rate\": \"0.12800000\",\n    \"foreign_total\": \"1040.94\",\n    \"base_currency_code\": \"USD\"\n  }\n}"
                },
                {
                  "name": "404 Compra inexistente o de otro negocio",
                  "originalRequest": {
                    "method": "GET",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/json"
                      }
                    ],
                    "url": {
                      "raw": "{{base_url_v2}}/expenses/{{expense_id}}",
                      "host": [
                        "{{base_url_v2}}"
                      ],
                      "path": [
                        "expenses",
                        "{{expense_id}}"
                      ]
                    },
                    "description": "Igual que v1 más la referencia de moneda. Los montos de `totals` y `products` están en moneda base.\n\nPermiso requerido: `expenses`\n\nURL base: variable `base_url_v2` (https://api.filexpress.app/api/external/v2)."
                  },
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"status\": false,\n  \"message\": \"Expense not found\"\n}"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "variable": []
}
